codemp/game/w_force.c File Reference

#include "b_local.h"
#include "w_saber.h"
#include "ai_main.h"
#include "../ghoul2/G2.h"
#include "../namespace_begin.h"
#include "../namespace_end.h"

Go to the source code of this file.

Defines

#define METROID_JUMP   1
#define FORCE_VELOCITY_DAMAGE   0

Functions

void NPC_PlayConfusionSound (gentity_t *self)
void NPC_Jedi_PlayConfusionSound (gentity_t *self)
void NPC_UseResponse (gentity_t *self, gentity_t *user, qboolean useWhenDone)
void Jedi_Decloak (gentity_t *self)
qboolean BG_FullBodyTauntAnim (int anim)
int ForceShootDrain (gentity_t *self)
gentity_tG_PreDefSound (vec3_t org, int pdSound)
void WP_InitForcePowers (gentity_t *ent)
void WP_SpawnInitForcePowers (gentity_t *ent)
qboolean BG_InKnockDown (int anim)
int ForcePowerUsableOn (gentity_t *attacker, gentity_t *other, forcePowers_t forcePower)
qboolean WP_ForcePowerAvailable (gentity_t *self, forcePowers_t forcePower, int overrideAmt)
qboolean WP_ForcePowerInUse (gentity_t *self, forcePowers_t forcePower)
qboolean WP_ForcePowerUsable (gentity_t *self, forcePowers_t forcePower)
int WP_AbsorbConversion (gentity_t *attacked, int atdAbsLevel, gentity_t *attacker, int atPower, int atPowerLevel, int atForceSpent)
void WP_ForcePowerRegenerate (gentity_t *self, int overrideAmt)
void WP_ForcePowerStart (gentity_t *self, forcePowers_t forcePower, int overrideAmt)
void ForceHeal (gentity_t *self)
void WP_AddToClientBitflags (gentity_t *ent, int entNum)
void ForceTeamHeal (gentity_t *self)
void ForceTeamForceReplenish (gentity_t *self)
void ForceGrip (gentity_t *self)
void ForceSpeed (gentity_t *self, int forceDuration)
void ForceSeeing (gentity_t *self)
void ForceProtect (gentity_t *self)
void ForceAbsorb (gentity_t *self)
void ForceRage (gentity_t *self)
void ForceLightning (gentity_t *self)
void ForceLightningDamage (gentity_t *self, gentity_t *traceEnt, vec3_t dir, vec3_t impactPoint)
void ForceShootLightning (gentity_t *self)
void ForceDrain (gentity_t *self)
void ForceDrainDamage (gentity_t *self, gentity_t *traceEnt, vec3_t dir, vec3_t impactPoint)
void ForceJumpCharge (gentity_t *self, usercmd_t *ucmd)
int WP_GetVelocityForForceJump (gentity_t *self, vec3_t jumpVel, usercmd_t *ucmd)
void ForceJump (gentity_t *self, usercmd_t *ucmd)
void WP_AddAsMindtricked (forcedata_t *fd, int entNum)
qboolean ForceTelepathyCheckDirectNPCTarget (gentity_t *self, trace_t *tr, qboolean *tookPower)
void ForceTelepathy (gentity_t *self)
void GEntity_UseFunc (gentity_t *self, gentity_t *other, gentity_t *activator)
qboolean CanCounterThrow (gentity_t *self, gentity_t *thrower, qboolean pull)
qboolean G_InGetUpAnim (playerState_t *ps)
void G_LetGoOfWall (gentity_t *ent)
void Touch_Button (gentity_t *ent, gentity_t *other, trace_t *trace)
void ForceThrow (gentity_t *self, qboolean pull)
void WP_ForcePowerStop (gentity_t *self, forcePowers_t forcePower)
void DoGripAction (gentity_t *self, forcePowers_t forcePower)
qboolean G_IsMindTricked (forcedata_t *fd, int client)
int WP_DoSpecificPower (gentity_t *self, usercmd_t *ucmd, forcePowers_t forcepower)
void FindGenericEnemyIndex (gentity_t *self)
void SeekerDroneUpdate (gentity_t *self)
void HolocronUpdate (gentity_t *self)
void JediMasterUpdate (gentity_t *self)
qboolean WP_HasForcePowers (const playerState_t *ps)
qboolean G_SpecialRollGetup (gentity_t *self)
void WP_ForcePowersUpdate (gentity_t *self, usercmd_t *ucmd)
qboolean Jedi_DodgeEvasion (gentity_t *self, gentity_t *shooter, trace_t *tr, int hitLoc)

Variables

vmCvar_t g_saberRestrictForce
bot_state_tbotstates [MAX_CLIENTS]
int speedLoopSound = 0
int rageLoopSound = 0
int protectLoopSound = 0
int absorbLoopSound = 0
int seeLoopSound = 0
int ysalamiriLoopSound = 0
const int forcePowerMinRank [NUM_FORCE_POWER_LEVELS][NUM_FORCE_POWERS]
const int mindTrickTime [NUM_FORCE_POWER_LEVELS]
float forcePushPullRadius [NUM_FORCE_POWER_LEVELS]
int g_LastFrameTime
int g_TimeSinceLastFrame


Define Documentation

#define FORCE_VELOCITY_DAMAGE   0
 

Definition at line 36 of file w_force.c.

#define METROID_JUMP   1
 

Definition at line 7 of file w_force.c.


Function Documentation

qboolean BG_FullBodyTauntAnim int  anim  ) 
 

Definition at line 1538 of file bg_panimate.c.

References BOTH_BOW, BOTH_DUAL_TAUNT, BOTH_GESTURE1, BOTH_MEDITATE, BOTH_SHOWOFF_DUAL, BOTH_SHOWOFF_FAST, BOTH_SHOWOFF_MEDIUM, BOTH_SHOWOFF_STAFF, BOTH_SHOWOFF_STRONG, BOTH_STAFF_TAUNT, BOTH_VICTORY_DUAL, BOTH_VICTORY_FAST, BOTH_VICTORY_MEDIUM, BOTH_VICTORY_STAFF, BOTH_VICTORY_STRONG, qboolean, qfalse, and qtrue.

Referenced by PmoveSingle(), and WP_ForcePowerStart().

01539 {
01540         switch ( anim )
01541         {
01542         case BOTH_GESTURE1:
01543         case BOTH_DUAL_TAUNT:
01544         case BOTH_STAFF_TAUNT:
01545         case BOTH_BOW:
01546         case BOTH_MEDITATE:
01547         case BOTH_SHOWOFF_FAST:
01548         case BOTH_SHOWOFF_MEDIUM:
01549         case BOTH_SHOWOFF_STRONG:
01550         case BOTH_SHOWOFF_DUAL:
01551         case BOTH_SHOWOFF_STAFF:
01552         case BOTH_VICTORY_FAST:
01553         case BOTH_VICTORY_MEDIUM:
01554         case BOTH_VICTORY_STRONG:
01555         case BOTH_VICTORY_DUAL:
01556         case BOTH_VICTORY_STAFF:
01557                 return qtrue;
01558                 break;
01559         }
01560         return qfalse;
01561 }

qboolean BG_InKnockDown int  anim  ) 
 

Definition at line 8526 of file bg_pmove.c.

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

qboolean CanCounterThrow gentity_t self,
gentity_t thrower,
qboolean  pull
 

Definition at line 2900 of file w_force.c.

References AngleSubtract(), gentity_s::client, ENTITYNUM_NONE, playerState_s::forceHandExtend, FP_PULL, FP_PUSH, g_gametype, gentity_t, playerState_s::groundEntityNum, GT_SIEGE, HANDEXTEND_NONE, gentity_s::health, vmCvar_t::integer, level, playerState_s::origin, playerState_s::powerups, gclient_s::ps, PW_DISINT_4, qboolean, level_locals_t::time, vec3_t, vectoangles(), VectorSubtract, playerState_s::viewangles, WEAPON_CHARGING, WEAPON_CHARGING_ALT, playerState_s::weaponstate, playerState_s::weaponTime, WP_ForcePowerUsable(), and YAW.

Referenced by ForceThrow().

02901 {
02902         int powerUse = 0;
02903 
02904         if (self->client->ps.forceHandExtend != HANDEXTEND_NONE)
02905         {
02906                 return 0;
02907         }
02908 
02909         if (self->client->ps.weaponTime > 0)
02910         {
02911                 return 0;
02912         }
02913 
02914         if ( self->health <= 0 )
02915         {
02916                 return 0;
02917         }
02918 
02919         if ( self->client->ps.powerups[PW_DISINT_4] > level.time )
02920         {
02921                 return 0;
02922         }
02923 
02924         if (self->client->ps.weaponstate == WEAPON_CHARGING ||
02925                 self->client->ps.weaponstate == WEAPON_CHARGING_ALT)
02926         { //don't autodefend when charging a weapon
02927                 return 0;
02928         }
02929 
02930         if (g_gametype.integer == GT_SIEGE &&
02931                 pull &&
02932                 thrower && thrower->client)
02933         { //in siege, pull will affect people if they are not facing you, so they can't run away so much
02934                 vec3_t d;
02935                 float a;
02936 
02937         VectorSubtract(thrower->client->ps.origin, self->client->ps.origin, d);
02938                 vectoangles(d, d);
02939 
02940         a = AngleSubtract(d[YAW], self->client->ps.viewangles[YAW]);
02941 
02942                 if (a > 60.0f || a < -60.0f)
02943                 { //if facing more than 60 degrees away they cannot defend
02944                         return 0;
02945                 }
02946         }
02947 
02948         if (pull)
02949         {
02950                 powerUse = FP_PULL;
02951         }
02952         else
02953         {
02954                 powerUse = FP_PUSH;
02955         }
02956 
02957         if ( !WP_ForcePowerUsable( self, powerUse ) )
02958         {
02959                 return 0;
02960         }
02961 
02962         if (self->client->ps.groundEntityNum == ENTITYNUM_NONE)
02963         { //you cannot counter a push/pull if you're in the air
02964                 return 0;
02965         }
02966 
02967         return 1;
02968 }

void DoGripAction gentity_t self,
forcePowers_t  forcePower
 

Definition at line 3945 of file w_force.c.

References AngleVectors(), CHAN_VOICE, gentity_s::client, DAMAGE_NO_ARMOR, gclient_s::dangerTime, EF_INVULNERABLE, playerState_s::eFlags, trace_t::entityNum, ENTITYNUM_NONE, playerState_s::fd, FORCE_LEVEL_1, FORCE_LEVEL_2, FORCE_LEVEL_3, forcedata_s::forceGripBeingGripped, playerState_s::forceGripChangeMovetype, forcedata_s::forceGripDamageDebounceTime, forcedata_s::forceGripEntityNum, playerState_s::forceGripMoveInterval, forcedata_s::forceGripStarted, playerState_s::forceHandExtend, playerState_s::forceHandExtendTime, forcedata_s::forcePowerDebounce, forcedata_s::forcePowerLevel, forcePowerNeeded, forcePowers_t, forcedata_s::forcePowersActive, ForcePowerUsableOn(), FP_ABSORB, FP_GRIP, trace_t::fraction, G_Damage(), g_entities, G_EntitySound(), G_SoundIndex(), gentity_t, HANDEXTEND_CHOKE, gentity_s::health, InFront(), gentity_s::inuse, gclient_s::invulnerableTimer, Jetpack_Off(), level, MASK_PLAYERSOLID, MAX_GRIP_DISTANCE, MOD_FORCE_DARK, NULL, entityState_s::number, playerState_s::origin, playerState_s::otherKiller, playerState_s::otherKillerDebounceTime, playerState_s::otherKillerTime, PM_FLOAT, PM_NORMAL, gclient_s::ps, Q_irand(), gentity_s::s, level_locals_t::time, trap_Trace(), va(), vec3_t, VectorCopy, VectorNormalize(), VectorSubtract, playerState_s::velocity, playerState_s::viewangles, WP_AbsorbConversion(), and WP_ForcePowerStop().

03946 {
03947         gentity_t *gripEnt;
03948         int gripLevel = 0;
03949         trace_t tr;
03950         vec3_t a;
03951         vec3_t fwd, fwd_o, start_o, nvel;
03952 
03953         self->client->dangerTime = level.time;
03954         self->client->ps.eFlags &= ~EF_INVULNERABLE;
03955         self->client->invulnerableTimer = 0;
03956 
03957         gripEnt = &g_entities[self->client->ps.fd.forceGripEntityNum];
03958 
03959         if (!gripEnt || !gripEnt->client || !gripEnt->inuse || gripEnt->health < 1 || !ForcePowerUsableOn(self, gripEnt, FP_GRIP))
03960         {
03961                 WP_ForcePowerStop(self, forcePower);
03962                 self->client->ps.fd.forceGripEntityNum = ENTITYNUM_NONE;
03963 
03964                 if (gripEnt && gripEnt->client && gripEnt->inuse)
03965                 {
03966                         gripEnt->client->ps.forceGripChangeMovetype = PM_NORMAL;
03967                 }
03968                 return;
03969         }
03970 
03971         VectorSubtract(gripEnt->client->ps.origin, self->client->ps.origin, a);
03972         
03973         trap_Trace(&tr, self->client->ps.origin, NULL, NULL, gripEnt->client->ps.origin, self->s.number, MASK_PLAYERSOLID);
03974 
03975         gripLevel = WP_AbsorbConversion(gripEnt, gripEnt->client->ps.fd.forcePowerLevel[FP_ABSORB], self, FP_GRIP, self->client->ps.fd.forcePowerLevel[FP_GRIP], forcePowerNeeded[self->client->ps.fd.forcePowerLevel[FP_GRIP]][FP_GRIP]);
03976 
03977         if (gripLevel == -1)
03978         {
03979                 gripLevel = self->client->ps.fd.forcePowerLevel[FP_GRIP];
03980         }
03981 
03982         if (!gripLevel)
03983         {
03984                 WP_ForcePowerStop(self, forcePower);
03985                 return;
03986         }
03987 
03988         if (VectorLength(a) > MAX_GRIP_DISTANCE)
03989         {
03990                 WP_ForcePowerStop(self, forcePower);
03991                 return;
03992         }
03993 
03994         if ( !InFront( gripEnt->client->ps.origin, self->client->ps.origin, self->client->ps.viewangles, 0.9f ) &&
03995                 gripLevel < FORCE_LEVEL_3)
03996         {
03997                 WP_ForcePowerStop(self, forcePower);
03998                 return;
03999         }
04000 
04001         if (tr.fraction != 1.0f &&
04002                 tr.entityNum != gripEnt->s.number /*&&
04003                 gripLevel < FORCE_LEVEL_3*/)
04004         {
04005                 WP_ForcePowerStop(self, forcePower);
04006                 return;
04007         }
04008 
04009         if (self->client->ps.fd.forcePowerDebounce[FP_GRIP] < level.time)
04010         { //2 damage per second while choking, resulting in 10 damage total (not including The Squeeze<tm>)
04011                 self->client->ps.fd.forcePowerDebounce[FP_GRIP] = level.time + 1000;
04012                 G_Damage(gripEnt, self, self, NULL, NULL, 2, DAMAGE_NO_ARMOR, MOD_FORCE_DARK);
04013         }
04014 
04015         Jetpack_Off(gripEnt); //make sure the guy being gripped has his jetpack off.
04016 
04017         if (gripLevel == FORCE_LEVEL_1)
04018         {
04019                 gripEnt->client->ps.fd.forceGripBeingGripped = level.time + 1000;
04020                 
04021                 if ((level.time - gripEnt->client->ps.fd.forceGripStarted) > 5000)
04022                 {
04023                         WP_ForcePowerStop(self, forcePower);
04024                 }
04025                 return;
04026         }
04027 
04028         if (gripLevel == FORCE_LEVEL_2)
04029         {
04030                 gripEnt->client->ps.fd.forceGripBeingGripped = level.time + 1000;
04031 
04032                 if (gripEnt->client->ps.forceGripMoveInterval < level.time)
04033                 {
04034                         gripEnt->client->ps.velocity[2] = 30;
04035 
04036                         gripEnt->client->ps.forceGripMoveInterval = level.time + 300; //only update velocity every 300ms, so as to avoid heavy bandwidth usage
04037                 }
04038 
04039                 gripEnt->client->ps.otherKiller = self->s.number;
04040                 gripEnt->client->ps.otherKillerTime = level.time + 5000;
04041                 gripEnt->client->ps.otherKillerDebounceTime = level.time + 100;
04042 
04043                 gripEnt->client->ps.forceGripChangeMovetype = PM_FLOAT;
04044 
04045                 if ((level.time - gripEnt->client->ps.fd.forceGripStarted) > 3000 && !self->client->ps.fd.forceGripDamageDebounceTime)
04046                 { //if we managed to lift him into the air for 2 seconds, give him a crack
04047                         self->client->ps.fd.forceGripDamageDebounceTime = 1;
04048                         G_Damage(gripEnt, self, self, NULL, NULL, 20, DAMAGE_NO_ARMOR, MOD_FORCE_DARK);
04049 
04050                         //Must play custom sounds on the actual entity. Don't use G_Sound (it creates a temp entity for the sound)
04051                         G_EntitySound( gripEnt, CHAN_VOICE, G_SoundIndex(va( "*choke%d.wav", Q_irand( 1, 3 ) )) );
04052 
04053                         gripEnt->client->ps.forceHandExtend = HANDEXTEND_CHOKE;
04054                         gripEnt->client->ps.forceHandExtendTime = level.time + 2000;
04055 
04056                         if (gripEnt->client->ps.fd.forcePowersActive & (1 << FP_GRIP))
04057                         { //choking, so don't let him keep gripping himself
04058                                 WP_ForcePowerStop(gripEnt, FP_GRIP);
04059                         }
04060                 }
04061                 else if ((level.time - gripEnt->client->ps.fd.forceGripStarted) > 4000)
04062                 {
04063                         WP_ForcePowerStop(self, forcePower);
04064                 }
04065                 return;
04066         }
04067 
04068         if (gripLevel == FORCE_LEVEL_3)
04069         {
04070                 gripEnt->client->ps.fd.forceGripBeingGripped = level.time + 1000;
04071 
04072                 gripEnt->client->ps.otherKiller = self->s.number;
04073                 gripEnt->client->ps.otherKillerTime = level.time + 5000;
04074                 gripEnt->client->ps.otherKillerDebounceTime = level.time + 100;
04075 
04076                 gripEnt->client->ps.forceGripChangeMovetype = PM_FLOAT;
04077 
04078                 if (gripEnt->client->ps.forceGripMoveInterval < level.time)
04079                 {
04080                         float nvLen = 0;
04081 
04082                         VectorCopy(gripEnt->client->ps.origin, start_o);
04083                         AngleVectors(self->client->ps.viewangles, fwd, NULL, NULL);
04084                         fwd_o[0] = self->client->ps.origin[0] + fwd[0]*128;
04085                         fwd_o[1] = self->client->ps.origin[1] + fwd[1]*128;
04086                         fwd_o[2] = self->client->ps.origin[2] + fwd[2]*128;
04087                         fwd_o[2] += 16;
04088                         VectorSubtract(fwd_o, start_o, nvel);
04089 
04090                         nvLen = VectorLength(nvel);
04091 
04092                         if (nvLen < 16)
04093                         { //within x units of desired spot
04094                                 VectorNormalize(nvel);
04095                                 gripEnt->client->ps.velocity[0] = nvel[0]*8;
04096                                 gripEnt->client->ps.velocity[1] = nvel[1]*8;
04097                                 gripEnt->client->ps.velocity[2] = nvel[2]*8;
04098                         }
04099                         else if (nvLen < 64)
04100                         {
04101                                 VectorNormalize(nvel);
04102                                 gripEnt->client->ps.velocity[0] = nvel[0]*128;
04103                                 gripEnt->client->ps.velocity[1] = nvel[1]*128;
04104                                 gripEnt->client->ps.velocity[2] = nvel[2]*128;
04105                         }
04106                         else if (nvLen < 128)
04107                         {
04108                                 VectorNormalize(nvel);
04109                                 gripEnt->client->ps.velocity[0] = nvel[0]*256;
04110                                 gripEnt->client->ps.velocity[1] = nvel[1]*256;
04111                                 gripEnt->client->ps.velocity[2] = nvel[2]*256;
04112                         }
04113                         else if (nvLen < 200)
04114                         {
04115                                 VectorNormalize(nvel);
04116                                 gripEnt->client->ps.velocity[0] = nvel[0]*512;
04117                                 gripEnt->client->ps.velocity[1] = nvel[1]*512;
04118                                 gripEnt->client->ps.velocity[2] = nvel[2]*512;
04119                         }
04120                         else
04121                         {
04122                                 VectorNormalize(nvel);
04123                                 gripEnt->client->ps.velocity[0] = nvel[0]*700;
04124                                 gripEnt->client->ps.velocity[1] = nvel[1]*700;
04125                                 gripEnt->client->ps.velocity[2] = nvel[2]*700;
04126                         }
04127 
04128                         gripEnt->client->ps.forceGripMoveInterval = level.time + 300; //only update velocity every 300ms, so as to avoid heavy bandwidth usage
04129                 }
04130 
04131                 if ((level.time - gripEnt->client->ps.fd.forceGripStarted) > 3000 && !self->client->ps.fd.forceGripDamageDebounceTime)
04132                 { //if we managed to lift him into the air for 2 seconds, give him a crack
04133                         self->client->ps.fd.forceGripDamageDebounceTime = 1;
04134                         G_Damage(gripEnt, self, self, NULL, NULL, 40, DAMAGE_NO_ARMOR, MOD_FORCE_DARK);
04135 
04136                         //Must play custom sounds on the actual entity. Don't use G_Sound (it creates a temp entity for the sound)
04137                         G_EntitySound( gripEnt, CHAN_VOICE, G_SoundIndex(va( "*choke%d.wav", Q_irand( 1, 3 ) )) );
04138 
04139                         gripEnt->client->ps.forceHandExtend = HANDEXTEND_CHOKE;
04140                         gripEnt->client->ps.forceHandExtendTime = level.time + 2000;
04141 
04142                         if (gripEnt->client->ps.fd.forcePowersActive & (1 << FP_GRIP))
04143                         { //choking, so don't let him keep gripping himself
04144                                 WP_ForcePowerStop(gripEnt, FP_GRIP);
04145                         }
04146                 }
04147                 else if ((level.time - gripEnt->client->ps.fd.forceGripStarted) > 4000)
04148                 {
04149                         WP_ForcePowerStop(self, forcePower);
04150                 }
04151                 return;
04152         }
04153 }

void FindGenericEnemyIndex gentity_t self  ) 
 

Definition at line 4664 of file w_force.c.

References gentity_s::client, g_entities, playerState_s::genericEnemyIndex, gentity_t, gentity_s::health, InFront(), MAX_CLIENTS, NULL, entityState_s::number, OnSameTeam(), OrgVisible(), playerState_s::origin, PM_INTERMISSION, PM_SPECTATOR, playerState_s::pm_type, gclient_s::ps, gentity_s::s, vec3_t, VectorSubtract, and playerState_s::viewangles.

Referenced by SeekerDroneUpdate().

04665 { //Find another client that would be considered a threat.
04666         int i = 0;
04667         float tlen;
04668         gentity_t *ent;
04669         gentity_t *besten = NULL;
04670         float blen = 99999999;
04671         vec3_t a;
04672 
04673         while (i < MAX_CLIENTS)
04674         {
04675                 ent = &g_entities[i];
04676 
04677                 if (ent && ent->client && ent->s.number != self->s.number && ent->health > 0 && !OnSameTeam(self, ent) && ent->client->ps.pm_type != PM_INTERMISSION && ent->client->ps.pm_type != PM_SPECTATOR)
04678                 {
04679                         VectorSubtract(ent->client->ps.origin, self->client->ps.origin, a);
04680                         tlen = VectorLength(a);
04681 
04682                         if (tlen < blen &&
04683                                 InFront(ent->client->ps.origin, self->client->ps.origin, self->client->ps.viewangles, 0.8f ) &&
04684                                 OrgVisible(self->client->ps.origin, ent->client->ps.origin, self->s.number))
04685                         {
04686                                 blen = tlen;
04687                                 besten = ent;
04688                         }
04689                 }
04690 
04691                 i++;
04692         }
04693 
04694         if (!besten)
04695         {
04696                 return;
04697         }
04698 
04699         self->client->ps.genericEnemyIndex = besten->s.number;
04700 }

void ForceAbsorb gentity_t self  ) 
 

Definition at line 1694 of file w_force.c.

References absorbLoopSound, gentity_s::client, playerState_s::fd, playerState_s::forceAllowDeactivateTime, forcedata_s::forcePowersActive, FP_ABSORB, FP_PROTECT, FP_RAGE, G_PreDefSound(), G_Sound(), gentity_t, gentity_s::health, level, playerState_s::origin, PDSOUND_ABSORB, gclient_s::ps, level_locals_t::time, TRACK_CHANNEL_3, WP_ForcePowerStart(), WP_ForcePowerStop(), and WP_ForcePowerUsable().

Referenced by ClientThink_real(), and WP_DoSpecificPower().

01695 {
01696         if ( self->health <= 0 )
01697         {
01698                 return;
01699         }
01700 
01701         if (self->client->ps.forceAllowDeactivateTime < level.time &&
01702                 (self->client->ps.fd.forcePowersActive & (1 << FP_ABSORB)) )
01703         {
01704                 WP_ForcePowerStop( self, FP_ABSORB );
01705                 return;
01706         }
01707 
01708         if ( !WP_ForcePowerUsable( self, FP_ABSORB ) )
01709         {
01710                 return;
01711         }
01712 
01713         // Make sure to turn off Force Rage and Force Protection.
01714         if (self->client->ps.fd.forcePowersActive & (1 << FP_RAGE) )
01715         {
01716                 WP_ForcePowerStop( self, FP_RAGE );
01717         }
01718         if (self->client->ps.fd.forcePowersActive & (1 << FP_PROTECT) )
01719         {
01720                 WP_ForcePowerStop( self, FP_PROTECT );
01721         }
01722 
01723         self->client->ps.forceAllowDeactivateTime = level.time + 1500;
01724 
01725         WP_ForcePowerStart( self, FP_ABSORB, 0 );
01726         G_PreDefSound(self->client->ps.origin, PDSOUND_ABSORB);
01727         G_Sound( self, TRACK_CHANNEL_3, absorbLoopSound );
01728 }

void ForceDrain gentity_t self  ) 
 

Definition at line 2022 of file w_force.c.

References CHAN_BODY, gentity_s::client, playerState_s::fd, playerState_s::forceHandExtend, playerState_s::forceHandExtendTime, forcedata_s::forcePower, forcedata_s::forcePowerDebounce, FP_DRAIN, G_Sound(), G_SoundIndex(), gentity_t, HANDEXTEND_FORCE_HOLD, HANDEXTEND_NONE, gentity_s::health, level, gclient_s::ps, level_locals_t::time, playerState_s::weaponTime, WP_ForcePowerStart(), and WP_ForcePowerUsable().

Referenced by WP_DoSpecificPower().

02023 {
02024         if ( self->health <= 0 )
02025         {
02026                 return;
02027         }
02028 
02029         if (self->client->ps.forceHandExtend != HANDEXTEND_NONE)
02030         {
02031                 return;
02032         }
02033 
02034         if (self->client->ps.weaponTime > 0)
02035         {
02036                 return;
02037         }
02038 
02039         if ( self->client->ps.fd.forcePower < 25 || !WP_ForcePowerUsable( self, FP_DRAIN ) )
02040         {
02041                 return;
02042         }
02043         if ( self->client->ps.fd.forcePowerDebounce[FP_DRAIN] > level.time )
02044         {//stops it while using it and also after using it, up to 3 second delay
02045                 return;
02046         }
02047 
02048 //      self->client->ps.forceHandExtend = HANDEXTEND_FORCEPUSH;
02049 //      self->client->ps.forceHandExtendTime = level.time + 1000;
02050         self->client->ps.forceHandExtend = HANDEXTEND_FORCE_HOLD;
02051         self->client->ps.forceHandExtendTime = level.time + 20000;
02052 
02053         G_Sound( self, CHAN_BODY, G_SoundIndex("sound/weapons/force/drain.wav") );
02054         
02055         WP_ForcePowerStart( self, FP_DRAIN, 500 );
02056 }

void ForceDrainDamage gentity_t self,
gentity_t traceEnt,
vec3_t  dir,
vec3_t  impactPoint
 

Definition at line 2058 of file w_force.c.

References gentity_s::client, gclient_s::dangerTime, DirToByte(), EF_INVULNERABLE, playerState_s::eFlags, ET_NPC, entityState_s::eType, EV_FORCE_DRAINED, entityState_s::eventParm, playerState_s::fd, FORCE_LEVEL_1, FORCE_LEVEL_2, FORCE_LEVEL_3, forcedata_s::forceDrainTime, forcedata_s::forcePower, forcedata_s::forcePowerLevel, forcedata_s::forcePowerRegenDebounceTime, gclient_s::forcePowerSoundDebounce, ForcePowerUsableOn(), FP_ABSORB, FP_DRAIN, g_friendlyFire, G_TempEntity(), entityState_s::genericenemyindex, gentity_t, gentity_s::health, vmCvar_t::integer, gclient_s::invulnerableTimer, level, entityState_s::number, OnSameTeam(), entityState_s::owner, gclient_s::ps, gentity_s::s, STAT_HEALTH, STAT_MAX_HEALTH, playerState_s::stats, gentity_s::takedamage, level_locals_t::time, vec3_t, and WP_AbsorbConversion().

Referenced by ForceShootDrain().

02059 {
02060         gentity_t *tent;
02061 
02062         self->client->dangerTime = level.time;
02063         self->client->ps.eFlags &= ~EF_INVULNERABLE;
02064         self->client->invulnerableTimer = 0;
02065 
02066         if ( traceEnt && traceEnt->takedamage )
02067         {
02068                 if ( traceEnt->client && (!OnSameTeam(self, traceEnt) || g_friendlyFire.integer) && self->client->ps.fd.forceDrainTime < level.time && traceEnt->client->ps.fd.forcePower )
02069                 {//an enemy or object
02070                         if (!traceEnt->client && traceEnt->s.eType == ET_NPC)
02071                         { //g2animent
02072                                 if (traceEnt->s.genericenemyindex < level.time)
02073                                 {
02074                                         traceEnt->s.genericenemyindex = level.time + 2000;
02075                                 }
02076                         }
02077                         if (ForcePowerUsableOn(self, traceEnt, FP_DRAIN))
02078                         {
02079                                 int modPowerLevel = -1;
02080                                 int     dmg = 0; //Q_irand( 1, 3 );
02081                                 if (self->client->ps.fd.forcePowerLevel[FP_DRAIN] == FORCE_LEVEL_1)
02082                                 {
02083                                         dmg = 2; //because it's one-shot
02084                                 }
02085                                 else if (self->client->ps.fd.forcePowerLevel[FP_DRAIN] == FORCE_LEVEL_2)
02086                                 {
02087                                         dmg = 3;
02088                                 }
02089                                 else if (self->client->ps.fd.forcePowerLevel[FP_DRAIN] == FORCE_LEVEL_3)
02090                                 {
02091                                         dmg = 4;
02092                                 }
02093                         
02094                                 if (traceEnt->client)
02095                                 {
02096                                         modPowerLevel = WP_AbsorbConversion(traceEnt, traceEnt->client->ps.fd.forcePowerLevel[FP_ABSORB], self, FP_DRAIN, self->client->ps.fd.forcePowerLevel[FP_DRAIN], 1);
02097                                 }
02098 
02099                                 if (modPowerLevel != -1)
02100                                 {
02101                                         if (!modPowerLevel)
02102                                         {
02103                                                 dmg = 0;
02104                                         }
02105                                         else if (modPowerLevel == 1)
02106                                         {
02107                                                 dmg = 1;
02108                                         }
02109                                         else if (modPowerLevel == 2)
02110                                         {
02111                                                 dmg = 2;
02112                                         }
02113                                 }
02114                                 //G_Damage( traceEnt, self, self, dir, impactPoint, dmg, 0, MOD_FORCE_DARK );
02115 
02116                                 if (dmg)
02117                                 {
02118                                         traceEnt->client->ps.fd.forcePower -= (dmg);
02119                                 }
02120                                 if (traceEnt->client->ps.fd.forcePower < 0)
02121                                 {
02122                                         traceEnt->client->ps.fd.forcePower = 0;
02123                                 }
02124 
02125                                 if (self->client->ps.stats[STAT_HEALTH] < self->client->ps.stats[STAT_MAX_HEALTH] &&
02126                                         self->health > 0 && self->client->ps.stats[STAT_HEALTH] > 0)
02127                                 {
02128                                         self->health += dmg;
02129                                         if (self->health > self->client->ps.stats[STAT_MAX_HEALTH])
02130                                         {
02131                                                 self->health = self->client->ps.stats[STAT_MAX_HEALTH];
02132                                         }
02133                                         self->client->ps.stats[STAT_HEALTH] = self->health;
02134                                 }
02135 
02136                                 traceEnt->client->ps.fd.forcePowerRegenDebounceTime = level.time + 800; //don't let the client being drained get force power back right away
02137 
02138                                 //Drain the standard amount since we just drained someone else
02139 
02140                                 /*
02141                                 if (self->client->ps.fd.forcePowerLevel[FP_DRAIN] == FORCE_LEVEL_1)
02142                                 {
02143                                         BG_ForcePowerDrain( &self->client->ps, FP_DRAIN, 0 );
02144                                 }
02145                                 else
02146                                 {
02147                                         BG_ForcePowerDrain( &self->client->ps, FP_DRAIN, forcePowerNeeded[self->client->ps.fd.forcePowerLevel[FP_DRAIN]][FP_DRAIN]/5 );
02148                                 }
02149 
02150                                 if (self->client->ps.fd.forcePowerLevel[FP_DRAIN] == FORCE_LEVEL_1)
02151                                 {
02152                                         self->client->ps.fd.forceDrainTime = level.time + 100;
02153                                 }
02154                                 else
02155                                 {
02156                                         self->client->ps.fd.forceDrainTime = level.time + 20;
02157                                 }
02158 
02159                                 if ( traceEnt->client )
02160                                 {
02161                                         if ( !Q_irand( 0, 2 ) )
02162                                         {
02163                                                 //G_Sound( traceEnt, CHAN_BODY, G_SoundIndex( "sound/weapons/force/lightninghit.wav" ) );
02164                                         }
02165                                 //      traceEnt->s.powerups |= ( 1 << PW_DISINT_1 );
02166 
02167                                 //      traceEnt->client->ps.powerups[PW_DISINT_1] = level.time + 500;
02168                                 }
02169                                 */
02170 
02171                                 if (traceEnt->client->forcePowerSoundDebounce < level.time)
02172                                 {
02173                                         tent = G_TempEntity( impactPoint, EV_FORCE_DRAINED);
02174                                         tent->s.eventParm = DirToByte(dir);
02175                                         tent->s.owner = traceEnt->s.number;
02176 
02177                                         traceEnt->client->forcePowerSoundDebounce = level.time + 400;
02178                                 }
02179                         }
02180                 }
02181         }
02182 }

void ForceGrip gentity_t self  ) 
 

Definition at line 1523 of file w_force.c.

References AngleVectors(), bgEntity_t, gentity_s::client, vehicleInfo_t::Eject, trace_t::entityNum, ENTITYNUM_NONE, playerState_s::fd, forcedata_s::forceGripDamageDebounceTime, forcedata_s::forceGripEntityNum, forcedata_s::forceGripUseTime, playerState_s::forceHandExtend, playerState_s::forceHandExtendTime, ForcePowerUsableOn(), FP_GRIP, trace_t::fraction, g_entities, g_friendlyFire, gentity_t, HANDEXTEND_FORCE_HOLD, HANDEXTEND_NONE, gentity_s::health, vmCvar_t::integer, gentity_s::inuse, level, gentity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, MASK_PLAYERSOLID, MAX_CLIENTS, MAX_GRIP_DISTANCE, NULL, entityState_s::number, OnSameTeam(), playerState_s::origin, gclient_s::ps, qfalse, gentity_s::s, level_locals_t::time, trap_Trace(), vehicleInfo_t::type, vec3_t, VectorCopy, VH_ANIMAL, VH_SPEEDER, playerState_s::viewangles, playerState_s::viewheight, playerState_s::weaponTime, and WP_ForcePowerUsable().

Referenced by WP_DoSpecificPower().

01524 {
01525         trace_t tr;
01526         vec3_t tfrom, tto, fwd;
01527 
01528         if ( self->health <= 0 )
01529         {
01530                 return;
01531         }
01532 
01533         if (self->client->ps.forceHandExtend != HANDEXTEND_NONE)
01534         {
01535                 return;
01536         }
01537 
01538         if (self->client->ps.weaponTime > 0)
01539         {
01540                 return;
01541         }
01542 
01543         if (self->client->ps.fd.forceGripUseTime > level.time)
01544         {
01545                 return;
01546         }
01547 
01548         if ( !WP_ForcePowerUsable( self, FP_GRIP ) )
01549         {
01550                 return;
01551         }
01552 
01553         VectorCopy(self->client->ps.origin, tfrom);
01554         tfrom[2] += self->client->ps.viewheight;
01555         AngleVectors(self->client->ps.viewangles, fwd, NULL, NULL);
01556         tto[0] = tfrom[0] + fwd[0]*MAX_GRIP_DISTANCE;
01557         tto[1] = tfrom[1] + fwd[1]*MAX_GRIP_DISTANCE;
01558         tto[2] = tfrom[2] + fwd[2]*MAX_GRIP_DISTANCE;
01559 
01560         trap_Trace(&tr, tfrom, NULL, NULL, tto, self->s.number, MASK_PLAYERSOLID);
01561 
01562         if ( tr.fraction != 1.0 &&
01563                 tr.entityNum != ENTITYNUM_NONE &&
01564                 g_entities[tr.entityNum].client &&
01565                 !g_entities[tr.entityNum].client->ps.fd.forceGripCripple &&
01566                 g_entities[tr.entityNum].client->ps.fd.forceGripBeingGripped < level.time &&
01567                 ForcePowerUsableOn(self, &g_entities[tr.entityNum], FP_GRIP) &&
01568                 (g_friendlyFire.integer || !OnSameTeam(self, &g_entities[tr.entityNum])) ) //don't grip someone who's still crippled
01569         {
01570                 if (g_entities[tr.entityNum].s.number < MAX_CLIENTS && g_entities[tr.entityNum].client->ps.m_iVehicleNum)
01571                 { //a player on a vehicle
01572                         gentity_t *vehEnt = &g_entities[g_entities[tr.entityNum].client->ps.m_iVehicleNum];
01573                         if (vehEnt->inuse && vehEnt->client && vehEnt->m_pVehicle)
01574                         {
01575                                 if (vehEnt->m_pVehicle->m_pVehicleInfo->type == VH_SPEEDER ||
01576                                         vehEnt->m_pVehicle->m_pVehicleInfo->type == VH_ANIMAL)
01577                                 { //push the guy off
01578                                         vehEnt->m_pVehicle->m_pVehicleInfo->Eject(vehEnt->m_pVehicle, (bgEntity_t *)&g_entities[tr.entityNum], qfalse);
01579                                 }
01580                         }
01581                 }
01582                 self->client->ps.fd.forceGripEntityNum = tr.entityNum;
01583                 g_entities[tr.entityNum].client->ps.fd.forceGripStarted = level.time;
01584                 self->client->ps.fd.forceGripDamageDebounceTime = 0;
01585 
01586                 self->client->ps.forceHandExtend = HANDEXTEND_FORCE_HOLD;
01587                 self->client->ps.forceHandExtendTime = level.time + 5000;
01588         }
01589         else
01590         {
01591                 self->client->ps.fd.forceGripEntityNum = ENTITYNUM_NONE;
01592                 return;
01593         }
01594 }

void ForceHeal gentity_t self  ) 
 

Definition at line 1236 of file w_force.c.

References BG_ForcePowerDrain(), CHAN_ITEM, gentity_s::client, playerState_s::fd, FORCE_LEVEL_2, FORCE_LEVEL_3, forcedata_s::forcePowerLevel, FP_HEAL, G_Sound(), G_SoundIndex(), gentity_t, gentity_s::health, gclient_s::ps, STAT_MAX_HEALTH, playerState_s::stats, and WP_ForcePowerUsable().

Referenced by ClientThink_real(), and WP_DoSpecificPower().

01237 {
01238         if ( self->health <= 0 )
01239         {
01240                 return;
01241         }
01242 
01243         if ( !WP_ForcePowerUsable( self, FP_HEAL ) )
01244         {
01245                 return;
01246         }
01247 
01248         if ( self->health >= self->client->ps.stats[STAT_MAX_HEALTH])
01249         {
01250                 return;
01251         }
01252 
01253         if (self->client->ps.fd.forcePowerLevel[FP_HEAL] == FORCE_LEVEL_3)
01254         {
01255                 self->health += 25; //This was 50, but that angered the Balance God.
01256                 
01257                 if (self->health > self->client->ps.stats[STAT_MAX_HEALTH])
01258                 {
01259                         self->health = self->client->ps.stats[STAT_MAX_HEALTH];
01260                 }
01261                 BG_ForcePowerDrain( &self->client->ps, FP_HEAL, 0 );
01262         }
01263         else if (self->client->ps.fd.forcePowerLevel[FP_HEAL] == FORCE_LEVEL_2)
01264         {
01265                 self->health += 10;
01266                 
01267                 if (self->health > self->client->ps.stats[STAT_MAX_HEALTH])
01268                 {
01269                         self->health = self->client->ps.stats[STAT_MAX_HEALTH];
01270                 }
01271                 BG_ForcePowerDrain( &self->client->ps, FP_HEAL, 0 );
01272         }
01273         else
01274         {
01275                 self->health += 5;
01276                 
01277                 if (self->health > self->client->ps.stats[STAT_MAX_HEALTH])
01278                 {
01279                         self->health = self->client->ps.stats[STAT_MAX_HEALTH];
01280                 }
01281                 BG_ForcePowerDrain( &self->client->ps, FP_HEAL, 0 );
01282         }
01283         /*
01284         else
01285         {
01286                 WP_ForcePowerStart( self, FP_HEAL, 0 );
01287         }
01288         */
01289         //NOTE: Decided to make all levels instant.
01290 
01291         G_Sound( self, CHAN_ITEM, G_SoundIndex("sound/weapons/force/heal.wav") );
01292 }

void ForceJump gentity_t self,
usercmd_t ucmd
 

Definition at line 2462 of file w_force.c.

References gentity_s::client, ENTITYNUM_NONE, playerState_s::fd, gclient_s::fjDidJump, FORCE_JUMP_CHARGE_TIME, forcedata_s::forceJumpCharge, playerState_s::forceJumpFlip, forceJumpStrength, forcedata_s::forceJumpZStart, forcedata_s::forcePowerDuration, forcedata_s::forcePowerLevel, forcePowerNeeded, FP_LEVITATION, FRAMETIME, gentity_t, entityState_s::groundEntityNum, gentity_s::health, level, playerState_s::origin, gclient_s::ps, qtrue, gentity_s::s, level_locals_t::time, ucmd, usercmd_t, vec3_t, VectorCopy, playerState_s::velocity, WP_ForcePowerStart(), WP_ForcePowerUsable(), and WP_GetVelocityForForceJump().

Referenced by Boba_StopKnockdown(), and WP_DoSpecificPower().

02463 {
02464         float forceJumpChargeInterval;
02465         vec3_t  jumpVel;
02466 
02467         if ( self->client->ps.fd.forcePowerDuration[FP_LEVITATION] > level.time )
02468         {
02469                 return;
02470         }
02471         if ( !WP_ForcePowerUsable( self, FP_LEVITATION ) )
02472         {
02473                 return;
02474         }
02475         if ( self->s.groundEntityNum == ENTITYNUM_NONE )
02476         {
02477                 return;
02478         }
02479         if ( self->health <= 0 )
02480         {
02481                 return;
02482         }
02483 
02484         self->client->fjDidJump = qtrue;
02485 
02486         forceJumpChargeInterval = forceJumpStrength[self->client->ps.fd.forcePowerLevel[FP_LEVITATION]]/(FORCE_JUMP_CHARGE_TIME/FRAMETIME);
02487 
02488         WP_GetVelocityForForceJump( self, jumpVel, ucmd );
02489 
02490         //FIXME: sound effect
02491         self->client->ps.fd.forceJumpZStart = self->client->ps.origin[2];//remember this for when we land
02492         VectorCopy( jumpVel, self->client->ps.velocity );
02493         //wasn't allowing them to attack when jumping, but that was annoying
02494         //self->client->ps.weaponTime = self->client->ps.torsoAnimTimer;
02495 
02496         WP_ForcePowerStart( self, FP_LEVITATION, self->client->ps.fd.forceJumpCharge/forceJumpChargeInterval/(FORCE_JUMP_CHARGE_TIME/FRAMETIME)*forcePowerNeeded[self->client->ps.fd.forcePowerLevel[FP_LEVITATION]][FP_LEVITATION] );
02497         //self->client->ps.fd.forcePowerDuration[FP_LEVITATION] = level.time + self->client->ps.weaponTime;
02498         self->client->ps.fd.forceJumpCharge = 0;
02499         self->client->ps.forceJumpFlip = qtrue;
02500 }

void ForceJumpCharge gentity_t self,
usercmd_t ucmd
 

Definition at line 2317 of file w_force.c.

References CHAN_VOICE, gentity_s::client, ENTITYNUM_NONE, playerState_s::fd, FORCE_JUMP_CHARGE_TIME, forcedata_s::forceJumpAddTime, forcedata_s::forceJumpCharge, forceJumpStrength, forcedata_s::forcePower, forcedata_s::forcePowerLevel, forcePowerNeeded, FP_LEVITATION, FRAMETIME, G_MuteSound(), G_Sound(), G_SoundIndex(), gentity_t, playerState_s::groundEntityNum, gentity_s::health, forcedata_s::killSoundEntIndex, level, gclient_s::ps, level_locals_t::time, TRACK_CHANNEL_1, and usercmd_t.

Referenced by WP_ForcePowersUpdate().

02318 { //I guess this is unused now. Was used for the "charge" jump type.
02319         float forceJumpChargeInterval = forceJumpStrength[0] / (FORCE_JUMP_CHARGE_TIME/FRAMETIME);
02320 
02321         if ( self->health <= 0 )
02322         {
02323                 return;
02324         }
02325 
02326         if (!self->client->ps.fd.forceJumpCharge && self->client->ps.groundEntityNum == ENTITYNUM_NONE)
02327         {
02328                 return;
02329         }
02330 
02331         if (self->client->ps.fd.forcePower < forcePowerNeeded[self->client->ps.fd.forcePowerLevel[FP_LEVITATION]][FP_LEVITATION])
02332         {
02333                 G_MuteSound(self->client->ps.fd.killSoundEntIndex[TRACK_CHANNEL_1-50], CHAN_VOICE);
02334                 return;
02335         }
02336 
02337         if (!self->client->ps.fd.forceJumpCharge)
02338         {
02339                 self->client->ps.fd.forceJumpAddTime = 0;
02340         }
02341 
02342         if (self->client->ps.fd.forceJumpAddTime >= level.time)
02343         {
02344                 return;
02345         }
02346 
02347         //need to play sound
02348         if ( !self->client->ps.fd.forceJumpCharge )
02349         {
02350                 G_Sound( self, TRACK_CHANNEL_1, G_SoundIndex("sound/weapons/force/jumpbuild.wav") );
02351         }
02352 
02353         //Increment
02354         if (self->client->ps.fd.forceJumpAddTime < level.time)
02355         {
02356                 self->client->ps.fd.forceJumpCharge += forceJumpChargeInterval*50;
02357                 self->client->ps.fd.forceJumpAddTime = level.time + 500;
02358         }
02359 
02360         //clamp to max strength for current level
02361         if ( self->client->ps.fd.forceJumpCharge > forceJumpStrength[self->client->ps.fd.forcePowerLevel[FP_LEVITATION]] )
02362         {
02363                 self->client->ps.fd.forceJumpCharge = forceJumpStrength[self->client->ps.fd.forcePowerLevel[FP_LEVITATION]];
02364                 G_MuteSound(self->client->ps.fd.killSoundEntIndex[TRACK_CHANNEL_1-50], CHAN_VOICE);
02365         }
02366 
02367         //clamp to max available force power
02368         if ( self->client->ps.fd.forceJumpCharge/forceJumpChargeInterval/(FORCE_JUMP_CHARGE_TIME/FRAMETIME)*forcePowerNeeded[self->client->ps.fd.forcePowerLevel[FP_LEVITATION]][FP_LEVITATION] > self->client->ps.fd.forcePower )
02369         {//can't use more than you have
02370                 G_MuteSound(self->client->ps.fd.killSoundEntIndex[TRACK_CHANNEL_1-50], CHAN_VOICE);
02371                 self->client->ps.fd.forceJumpCharge = self->client->ps.fd.forcePower*forceJumpChargeInterval/(FORCE_JUMP_CHARGE_TIME/FRAMETIME);
02372         }
02373         
02374         //G_Printf("%f\n", self->client->ps.fd.forceJumpCharge);
02375 }

void ForceLightning gentity_t self  ) 
 

Definition at line 1777 of file w_force.c.

References CHAN_BODY, gentity_s::client, playerState_s::fd, playerState_s::forceHandExtend, playerState_s::forceHandExtendTime, forcedata_s::forcePower, forcedata_s::forcePowerDebounce, FP_LIGHTNING, G_Sound(), G_SoundIndex(), gentity_t, HANDEXTEND_FORCE_HOLD, HANDEXTEND_NONE, gentity_s::health, level, gclient_s::ps, level_locals_t::time, playerState_s::weaponTime, WP_ForcePowerStart(), and WP_ForcePowerUsable().

Referenced by WP_DoSpecificPower().

01778 {
01779         if ( self->health <= 0 )
01780         {
01781                 return;
01782         }
01783         if ( self->client->ps.fd.forcePower < 25 || !WP_ForcePowerUsable( self, FP_LIGHTNING ) )
01784         {
01785                 return;
01786         }
01787         if ( self->client->ps.fd.forcePowerDebounce[FP_LIGHTNING] > level.time )
01788         {//stops it while using it and also after using it, up to 3 second delay
01789                 return;
01790         }
01791 
01792         if (self->client->ps.forceHandExtend != HANDEXTEND_NONE)
01793         {
01794                 return;
01795         }
01796 
01797         if (self->client->ps.weaponTime > 0)
01798         {
01799                 return;
01800         }
01801 
01802         //Shoot lightning from hand
01803         //using grip anim now, to extend the burst time
01804         self->client->ps.forceHandExtend = HANDEXTEND_FORCE_HOLD;
01805         self->client->ps.forceHandExtendTime = level.time + 20000;
01806 
01807         G_Sound( self, CHAN_BODY, G_SoundIndex("sound/weapons/force/lightning") );
01808         
01809         WP_ForcePowerStart( self, FP_LIGHTNING, 500 );
01810 }

void ForceLightningDamage gentity_t self,
gentity_t traceEnt,
vec3_t  dir,
vec3_t  impactPoint
 

Definition at line 1812 of file w_force.c.

References CHAN_BODY, gentity_s::client, gclient_s::cloakToggleTime, gclient_s::dangerTime, EF_INVULNERABLE, playerState_s::eFlags, playerState_s::electrifyTime, ET_NPC, entityState_s::eType, playerState_s::fd, FORCE_LEVEL_2, forcedata_s::forcePower, forcedata_s::forcePowerLevel, ForcePowerUsableOn(), FP_ABSORB, FP_LIGHTNING, G_Damage(), G_Sound(), G_SoundIndex(), entityState_s::genericenemyindex, gentity_t, gclient_s::invulnerableTimer, Jedi_Decloak(), level, MOD_FORCE_DARK, gclient_s::noLightningTime, playerState_s::powerups, gclient_s::ps, PW_CLOAKED, Q_irand(), gentity_s::s, gentity_s::takedamage, level_locals_t::time, va(), vec3_t, playerState_s::weapon, WP_AbsorbConversion(), and WP_MELEE.

Referenced by ForceShootLightning().

01813 {
01814         self->client->dangerTime = level.time;
01815         self->client->ps.eFlags &= ~EF_INVULNERABLE;
01816         self->client->invulnerableTimer = 0;
01817 
01818         if ( traceEnt && traceEnt->takedamage )
01819         {
01820                 if (!traceEnt->client && traceEnt->s.eType == ET_NPC)
01821                 { //g2animent
01822                         if (traceEnt->s.genericenemyindex < level.time)
01823                         {
01824                                 traceEnt->s.genericenemyindex = level.time + 2000;
01825                         }
01826                 }
01827                 if ( traceEnt->client )
01828                 {//an enemy or object
01829                         if (traceEnt->client->noLightningTime >= level.time)
01830                         { //give them power and don't hurt them.
01831                                 traceEnt->client->ps.fd.forcePower++;
01832                                 if (traceEnt->client->ps.fd.forcePower > 100)
01833                                 {
01834                                         traceEnt->client->ps.fd.forcePower = 100;
01835                                 }
01836                                 return;
01837                         }
01838                         if (ForcePowerUsableOn(self, traceEnt, FP_LIGHTNING))
01839                         {
01840                                 int     dmg = Q_irand(1,2); //Q_irand( 1, 3 );
01841                                 
01842                                 int modPowerLevel = -1;
01843                                 
01844                                 if (traceEnt->client)
01845                                 {
01846                                         modPowerLevel = WP_AbsorbConversion(traceEnt, traceEnt->client->ps.fd.forcePowerLevel[FP_ABSORB], self, FP_LIGHTNING, self->client->ps.fd.forcePowerLevel[FP_LIGHTNING], 1);
01847                                 }
01848 
01849                                 if (modPowerLevel != -1)
01850                                 {
01851                                         if (!modPowerLevel)
01852                                         {
01853                                                 dmg = 0;
01854                                                 traceEnt->client->noLightningTime = level.time + 400;
01855                                         }
01856                                         else if (modPowerLevel == 1)
01857                                         {
01858                                                 dmg = 1;
01859                                                 traceEnt->client->noLightningTime = level.time + 300;
01860                                         }
01861                                         else if (modPowerLevel == 2)
01862                                         {
01863                                                 dmg = 1;
01864                                                 traceEnt->client->noLightningTime = level.time + 100;
01865                                         }
01866                                 }
01867 
01868                                 if ( self->client->ps.weapon == WP_MELEE
01869                                         && self->client->ps.fd.forcePowerLevel[FP_LIGHTNING] > FORCE_LEVEL_2 )
01870                                 {//2-handed lightning
01871                                         //jackin' 'em up, Palpatine-style
01872                                         dmg *= 2;
01873                                 }
01874 
01875                                 if (dmg)
01876                                 {
01877                                         //rww - Shields can now absorb lightning too.
01878                                         G_Damage( traceEnt, self, self, dir, impactPoint, dmg, 0, MOD_FORCE_DARK );
01879                                 }
01880                                 if ( traceEnt->client )
01881                                 {
01882                                         if ( !Q_irand( 0, 2 ) )
01883                                         {
01884                                                 G_Sound( traceEnt, CHAN_BODY, G_SoundIndex( va("sound/weapons/force/lightninghit%i", Q_irand(1, 3) )) );
01885                                         }
01886 
01887                                         if (traceEnt->client->ps.electrifyTime < (level.time + 400))
01888                                         { //only update every 400ms to reduce bandwidth usage (as it is passing a 32-bit time value)
01889                                                 traceEnt->client->ps.electrifyTime = level.time + 800;
01890                                         }
01891                                         if ( traceEnt->client->ps.powerups[PW_CLOAKED] )
01892                                         {//disable cloak temporarily
01893                                                 Jedi_Decloak( traceEnt );
01894                                                 traceEnt->client->cloakToggleTime = level.time + Q_irand( 3000, 10000 );
01895                                         }
01896                                 }
01897                         }
01898                 }
01899         }
01900 }

int ForcePowerUsableOn gentity_t attacker,
gentity_t other,
forcePowers_t  forcePower
 

Definition at line 697 of file w_force.c.

References BG_CanUseFPNow(), BG_HasYsalamiri(), BG_InKnockDown(), BG_SaberInSpecial(), CLASS_VEHICLE, gentity_s::client, playerState_s::duelInProgress, ET_NPC, entityState_s::eType, playerState_s::fd, forcePowers_t, forcedata_s::forcePowersActive, gclient_s::forcePowerSoundDebounce, FP_ABSORB, FP_GRIP, FP_LIGHTNING, FP_PULL, FP_PUSH, g_gametype, G_PreDefSound(), gentity_t, GT_SIEGE, vmCvar_t::integer, playerState_s::legsAnim, level, entityState_s::NPC_class, entityState_s::number, playerState_s::origin, PDSOUND_ABSORBHIT, gclient_s::ps, gentity_s::s, playerState_s::saberMove, level_locals_t::time, entityState_s::trickedentindex, playerState_s::weapon, and WP_SABER.

Referenced by DoGripAction(), ForceDrainDamage(), ForceGrip(), ForceLightningDamage(), ForceTeamForceReplenish(), ForceTeamHeal(), ForceTelepathy(), ForceThrow(), and StandardBotAI().

00698 {
00699         if (other && other->client && BG_HasYsalamiri(g_gametype.integer, &other->client->ps))
00700         {
00701                 return 0;
00702         }
00703 
00704         if (attacker && attacker->client && !BG_CanUseFPNow(g_gametype.integer, &attacker->client->ps, level.time, forcePower))
00705         {
00706                 return 0;
00707         }
00708 
00709         //Dueling fighters cannot use force powers on others, with the exception of force push when locked with each other
00710         if (attacker && attacker->client && attacker->client->ps.duelInProgress)
00711         {
00712                 return 0;
00713         }
00714 
00715         if (other && other->client && other->client->ps.duelInProgress)
00716         {
00717                 return 0;
00718         }
00719 
00720         if (forcePower == FP_GRIP)
00721         {
00722                 if (other && other->client &&
00723                         (other->client->ps.fd.forcePowersActive & (1<<FP_ABSORB)))
00724                 { //don't allow gripping to begin with if they are absorbing
00725                         //play sound indicating that attack was absorbed
00726                         if (other->client->forcePowerSoundDebounce < level.time)
00727                         {
00728                                 gentity_t *abSound = G_PreDefSound(other->client->ps.origin, PDSOUND_ABSORBHIT);
00729                                 abSound->s.trickedentindex = other->s.number;
00730                                 other->client->forcePowerSoundDebounce = level.time + 400;
00731                         }
00732                         return 0;
00733                 }
00734                 else if (other && other->client &&
00735                         other->client->ps.weapon == WP_SABER &&
00736                         BG_SaberInSpecial(other->client->ps.saberMove))
00737                 { //don't grip person while they are in a special or some really bad things can happen.
00738                         return 0;
00739                 }
00740         }
00741 
00742         if (other && other->client &&
00743                 (forcePower == FP_PUSH ||
00744                 forcePower == FP_PULL))
00745         {
00746                 if (BG_InKnockDown(other->client->ps.legsAnim))
00747                 {
00748                         return 0;
00749                 }
00750         }
00751 
00752         if (other && other->client && other->s.eType == ET_NPC &&
00753                 other->s.NPC_class == CLASS_VEHICLE)
00754         { //can't use the force on vehicles.. except lightning
00755                 if (forcePower == FP_LIGHTNING)
00756                 {
00757                         return 1;
00758                 }
00759                 else
00760                 {
00761                         return 0;
00762                 }
00763         }
00764 
00765         if (other && other->client && other->s.eType == ET_NPC &&
00766                 g_gametype.integer == GT_SIEGE)
00767         { //can't use powers at all on npc's normally in siege...
00768                 return 0;
00769         }
00770 
00771         return 1;
00772 }

void ForceProtect gentity_t self  ) 
 

Definition at line 1658 of file w_force.c.

References gentity_s::client, playerState_s::fd, playerState_s::forceAllowDeactivateTime, forcedata_s::forcePowersActive, FP_ABSORB, FP_PROTECT, FP_RAGE, G_PreDefSound(), G_Sound(), gentity_t, gentity_s::health, level, playerState_s::origin, PDSOUND_PROTECT, protectLoopSound, gclient_s::ps, level_locals_t::time, TRACK_CHANNEL_3, WP_ForcePowerStart(), WP_ForcePowerStop(), and WP_ForcePowerUsable().

Referenced by ClientThink_real(), and WP_DoSpecificPower().

01659 {
01660         if ( self->health <= 0 )
01661         {
01662                 return;
01663         }
01664 
01665         if (self->client->ps.forceAllowDeactivateTime < level.time &&
01666                 (self->client->ps.fd.forcePowersActive & (1 << FP_PROTECT)) )
01667         {
01668                 WP_ForcePowerStop( self, FP_PROTECT );
01669                 return;
01670         }
01671 
01672         if ( !WP_ForcePowerUsable( self, FP_PROTECT ) )
01673         {
01674                 return;
01675         }
01676 
01677         // Make sure to turn off Force Rage and Force Absorb.
01678         if (self->client->ps.fd.forcePowersActive & (1 << FP_RAGE) )
01679         {
01680                 WP_ForcePowerStop( self, FP_RAGE );
01681         }
01682         if (self->client->ps.fd.forcePowersActive & (1 << FP_ABSORB) )
01683         {
01684                 WP_ForcePowerStop( self, FP_ABSORB );
01685         }
01686 
01687         self->client->ps.forceAllowDeactivateTime = level.time + 1500;
01688 
01689         WP_ForcePowerStart( self, FP_PROTECT, 0 );
01690         G_PreDefSound(self->client->ps.origin, PDSOUND_PROTECT);
01691         G_Sound( self, TRACK_CHANNEL_3, protectLoopSound );
01692 }

void ForceRage gentity_t self  ) 
 

Definition at line 1730 of file w_force.c.

References gentity_s::client, playerState_s::fd, playerState_s::forceAllowDeactivateTime, forcedata_s::forcePowersActive, forcedata_s::forceRageRecoveryTime, FP_ABSORB, FP_PROTECT, FP_RAGE, G_Sound(), G_SoundIndex(), gentity_t, gentity_s::health, level, gclient_s::ps, rageLoopSound, level_locals_t::time, TRACK_CHANNEL_3, TRACK_CHANNEL_4, WP_ForcePowerStart(), WP_ForcePowerStop(), and WP_ForcePowerUsable().

Referenced by ClientThink_real(), and WP_DoSpecificPower().

01731 {
01732         if ( self->health <= 0 )
01733         {
01734                 return;
01735         }
01736 
01737         if (self->client->ps.forceAllowDeactivateTime < level.time &&
01738                 (self->client->ps.fd.forcePowersActive & (1 << FP_RAGE)) )
01739         {
01740                 WP_ForcePowerStop( self, FP_RAGE );
01741                 return;
01742         }
01743 
01744         if ( !WP_ForcePowerUsable( self, FP_RAGE ) )
01745         {
01746                 return;
01747         }
01748 
01749         if (self->client->ps.fd.forceRageRecoveryTime >= level.time)
01750         {
01751                 return;
01752         }
01753 
01754         if (self->health < 10)
01755         {
01756                 return;
01757         }
01758 
01759         // Make sure to turn off Force Protection and Force Absorb.
01760         if (self->client->ps.fd.forcePowersActive & (1 << FP_PROTECT) )
01761         {
01762                 WP_ForcePowerStop( self, FP_PROTECT );
01763         }
01764         if (self->client->ps.fd.forcePowersActive & (1 << FP_ABSORB) )
01765         {
01766                 WP_ForcePowerStop( self, FP_ABSORB );
01767         }
01768 
01769         self->client->ps.forceAllowDeactivateTime = level.time + 1500;
01770 
01771         WP_ForcePowerStart( self, FP_RAGE, 0 );
01772 
01773         G_Sound( self, TRACK_CHANNEL_4, G_SoundIndex("sound/weapons/force/rage.wav") );
01774         G_Sound( self, TRACK_CHANNEL_3, rageLoopSound );
01775 }

void ForceSeeing gentity_t self  ) 
 

Definition at line 1631 of file w_force.c.

References CHAN_AUTO, gentity_s::client, playerState_s::fd, playerState_s::forceAllowDeactivateTime, forcedata_s::forcePowersActive, FP_SEE, G_Sound(), G_SoundIndex(), gentity_t, gentity_s::health, level, gclient_s::ps, seeLoopSound, level_locals_t::time, TRACK_CHANNEL_5, WP_ForcePowerStart(), WP_ForcePowerStop(), and WP_ForcePowerUsable().

Referenced by ClientThink_real(), and WP_DoSpecificPower().

01632 {
01633         if ( self->health <= 0 )
01634         {
01635                 return;
01636         }
01637 
01638         if (self->client->ps.forceAllowDeactivateTime < level.time &&
01639                 (self->client->ps.fd.forcePowersActive & (1 << FP_SEE)) )
01640         {
01641                 WP_ForcePowerStop( self, FP_SEE );
01642                 return;
01643         }
01644 
01645         if ( !WP_ForcePowerUsable( self, FP_SEE ) )
01646         {
01647                 return;
01648         }
01649 
01650         self->client->ps.forceAllowDeactivateTime = level.time + 1500;
01651 
01652         WP_ForcePowerStart( self, FP_SEE, 0 );
01653 
01654         G_Sound( self, CHAN_AUTO, G_SoundIndex("sound/weapons/force/see.wav") );
01655         G_Sound( self, TRACK_CHANNEL_5, seeLoopSound );
01656 }

int ForceShootDrain gentity_t self  ) 
 

Definition at line 2184 of file w_force.c.

References entityShared_t::absmax, entityShared_t::absmin, playerState_s::activeForcePass, trace_t::allsolid, AngleVectors(), BG_ForcePowerDrain(), entityShared_t::bmodel, gentity_s::client, DotProduct, trace_t::endpos, trace_t::entityNum, ENTITYNUM_NONE, playerState_s::fd, FORCE_LEVEL_2, FORCE_LEVEL_3, ForceDrainDamage(), forcedata_s::forcePower, forcedata_s::forcePowerLevel, forcedata_s::forcePowerRegenDebounceTime, FP_DRAIN, trace_t::fraction, g_entities, g_friendlyFire, gentity_t, gentity_s::health, vmCvar_t::integer, gentity_s::inuse, level, MASK_SHOT, MAX_DRAIN_DISTANCE, MAX_GENTITIES, NULL, entityState_s::number, OnSameTeam(), playerState_s::origin, gclient_s::ps, gentity_s::r, gentity_s::s, trace_t::startsolid, gentity_s::takedamage, level_locals_t::time, trap_EntitiesInBox(), trap_InPVS(), trap_Trace(), vec3_origin, vec3_t, VectorCopy, VectorMA, VectorNormalize(), VectorSubtract, and playerState_s::viewangles.

02185 {
02186         trace_t tr;
02187         vec3_t  end, forward;
02188         gentity_t       *traceEnt;
02189         int                     gotOneOrMore = 0;
02190 
02191         if ( self->health <= 0 )
02192         {
02193                 return 0;
02194         }
02195         AngleVectors( self->client->ps.viewangles, forward, NULL, NULL );
02196         VectorNormalize( forward );
02197 
02198         if ( self->client->ps.fd.forcePowerLevel[FP_DRAIN] > FORCE_LEVEL_2 )
02199         {//arc
02200                 vec3_t  center, mins, maxs, dir, ent_org, size, v;
02201                 float   radius = MAX_DRAIN_DISTANCE, dot, dist;
02202                 gentity_t       *entityList[MAX_GENTITIES];
02203                 int                     iEntityList[MAX_GENTITIES];
02204                 int             e, numListedEntities, i;
02205 
02206                 VectorCopy( self->client->ps.origin, center );
02207                 for ( i = 0 ; i < 3 ; i++ ) 
02208                 {
02209                         mins[i] = center[i] - radius;
02210                         maxs[i] = center[i] + radius;
02211                 }
02212                 numListedEntities = trap_EntitiesInBox( mins, maxs, iEntityList, MAX_GENTITIES );
02213 
02214                 i = 0;
02215                 while (i < numListedEntities)
02216                 {
02217                         entityList[i] = &g_entities[iEntityList[i]];
02218 
02219                         i++;
02220                 }
02221 
02222                 for ( e = 0 ; e < numListedEntities ; e++ ) 
02223                 {
02224                         traceEnt = entityList[e];
02225 
02226                         if ( !traceEnt )
02227                                 continue;
02228                         if ( traceEnt == self )
02229                                 continue;
02230                         if ( !traceEnt->inuse )
02231                                 continue;
02232                         if ( !traceEnt->takedamage )
02233                                 continue;
02234                         if ( traceEnt->health <= 0 )//no torturing corpses
02235                                 continue;
02236                         if ( !traceEnt->client )
02237                                 continue;
02238                         if ( !traceEnt->client->ps.fd.forcePower )
02239                                 continue;
02240                         if (OnSameTeam(self, traceEnt) && !g_friendlyFire.integer)
02241                                 continue;
02242                         //this is all to see if we need to start a saber attack, if it's in flight, this doesn't matter
02243                         // find the distance from the edge of the bounding box
02244                         for ( i = 0 ; i < 3 ; i++ ) 
02245                         {
02246                                 if ( center[i] < traceEnt->r.absmin[i] ) 
02247                                 {
02248                                         v[i] = traceEnt->r.absmin[i] - center[i];
02249                                 } else if ( center[i] > traceEnt->r.absmax[i] ) 
02250                                 {
02251                                         v[i] = center[i] - traceEnt->r.absmax[i];
02252                                 } else 
02253                                 {
02254                                         v[i] = 0;
02255                                 }
02256                         }
02257 
02258                         VectorSubtract( traceEnt->r.absmax, traceEnt->r.absmin, size );
02259                         VectorMA( traceEnt->r.absmin, 0.5, size, ent_org );
02260 
02261                         //see if they're in front of me
02262                         //must be within the forward cone
02263                         VectorSubtract( ent_org, center, dir );
02264                         VectorNormalize( dir );
02265                         if ( (dot = DotProduct( dir, forward )) < 0.5 )
02266                                 continue;
02267 
02268                         //must be close enough
02269                         dist = VectorLength( v );
02270                         if ( dist >= radius ) 
02271                         {
02272                                 continue;
02273                         }
02274                 
02275                         //in PVS?
02276                         if ( !traceEnt->r.bmodel && !trap_InPVS( ent_org, self->client->ps.origin ) )
02277                         {//must be in PVS
02278                                 continue;
02279                         }
02280 
02281                         //Now check and see if we can actually hit it
02282                         trap_Trace( &tr, self->client->ps.origin, vec3_origin, vec3_origin, ent_org, self->s.number, MASK_SHOT );
02283                         if ( tr.fraction < 1.0f && tr.entityNum != traceEnt->s.number )
02284                         {//must have clear LOS
02285                                 continue;
02286                         }
02287 
02288                         // ok, we are within the radius, add us to the incoming list
02289                         ForceDrainDamage( self, traceEnt, dir, ent_org );
02290                         gotOneOrMore = 1;
02291                 }
02292         }
02293         else
02294         {//trace-line
02295                 VectorMA( self->client->ps.origin, 2048, forward, end );
02296                 
02297                 trap_Trace( &tr, self->client->ps.origin, vec3_origin, vec3_origin, end, self->s.number, MASK_SHOT );
02298                 if ( tr.entityNum == ENTITYNUM_NONE || tr.fraction == 1.0 || tr.allsolid || tr.startsolid || !g_entities[tr.entityNum].client || !g_entities[tr.entityNum].inuse )
02299                 {
02300                         return 0;
02301                 }
02302                 
02303                 traceEnt = &g_entities[tr.entityNum];
02304                 ForceDrainDamage( self, traceEnt, forward, tr.endpos );
02305                 gotOneOrMore = 1;
02306         }
02307 
02308         self->client->ps.activeForcePass = self->client->ps.fd.forcePowerLevel[FP_DRAIN] + FORCE_LEVEL_3;
02309 
02310         BG_ForcePowerDrain( &self->client->ps, FP_DRAIN, 5 ); //used to be 1, but this did, too, anger the God of Balance.
02311 
02312         self->client->ps.fd.forcePowerRegenDebounceTime = level.time + 500;
02313 
02314         return gotOneOrMore;
02315 }

void ForceShootLightning gentity_t self  ) 
 

Definition at line 1902 of file w_force.c.

References entityShared_t::absmax, entityShared_t::absmin, trace_t::allsolid, AngleVectors(), entityShared_t::bmodel, gentity_s::client, DotProduct, trace_t::endpos, trace_t::entityNum, ENTITYNUM_NONE, playerState_s::fd, FORCE_LEVEL_2, FORCE_LIGHTNING_RADIUS, ForceLightningDamage(), forcedata_s::forcePowerLevel, FP_LIGHTNING, trace_t::fraction, g_entities, g_friendlyFire, gentity_t, gentity_s::health, vmCvar_t::integer, gentity_s::inuse, MASK_SHOT, MAX_GENTITIES, NULL, entityState_s::number, OnSameTeam(), playerState_s::origin, entityShared_t::ownerNum, gclient_s::ps, gentity_s::r, gentity_s::s, trace_t::startsolid, gentity_s::takedamage, trap_EntitiesInBox(), trap_InPVS(), trap_Trace(), vec3_origin, vec3_t, VectorCopy, VectorMA, VectorNormalize(), VectorSubtract, playerState_s::viewangles, entityState_s::weapon, and WP_THERMAL.

01903 {
01904         trace_t tr;
01905         vec3_t  end, forward;
01906         gentity_t       *traceEnt;
01907 
01908         if ( self->health <= 0 )
01909         {
01910                 return;
01911         }
01912         AngleVectors( self->client->ps.viewangles, forward, NULL, NULL );
01913         VectorNormalize( forward );
01914 
01915         if ( self->client->ps.fd.forcePowerLevel[FP_LIGHTNING] > FORCE_LEVEL_2 )
01916         {//arc
01917                 vec3_t  center, mins, maxs, dir, ent_org, size, v;
01918                 float   radius = FORCE_LIGHTNING_RADIUS, dot, dist;
01919                 gentity_t       *entityList[MAX_GENTITIES];
01920                 int                     iEntityList[MAX_GENTITIES];
01921                 int             e, numListedEntities, i;
01922 
01923                 VectorCopy( self->client->ps.origin, center );
01924                 for ( i = 0 ; i < 3 ; i++ ) 
01925                 {
01926                         mins[i] = center[i] - radius;
01927                         maxs[i] = center[i] + radius;
01928                 }
01929                 numListedEntities = trap_EntitiesInBox( mins, maxs, iEntityList, MAX_GENTITIES );
01930 
01931                 i = 0;
01932                 while (i < numListedEntities)
01933                 {
01934                         entityList[i] = &g_entities[iEntityList[i]];
01935 
01936                         i++;
01937                 }
01938 
01939                 for ( e = 0 ; e < numListedEntities ; e++ ) 
01940                 {
01941                         traceEnt = entityList[e];
01942 
01943                         if ( !traceEnt )
01944                                 continue;
01945                         if ( traceEnt == self )
01946                                 continue;
01947                         if ( traceEnt->r.ownerNum == self->s.number && traceEnt->s.weapon != WP_THERMAL )//can push your own thermals
01948                                 continue;
01949                         if ( !traceEnt->inuse )
01950                                 continue;
01951                         if ( !traceEnt->takedamage )
01952                                 continue;
01953                         if ( traceEnt->health <= 0 )//no torturing corpses
01954                                 continue;
01955                         if ( !g_friendlyFire.integer && OnSameTeam(self, traceEnt))
01956                                 continue;
01957                         //this is all to see if we need to start a saber attack, if it's in flight, this doesn't matter
01958                         // find the distance from the edge of the bounding box
01959                         for ( i = 0 ; i < 3 ; i++ ) 
01960                         {
01961                                 if ( center[i] < traceEnt->r.absmin[i] ) 
01962                                 {
01963                                         v[i] = traceEnt->r.absmin[i] - center[i];
01964                                 } else if ( center[i] > traceEnt->r.absmax[i] ) 
01965                                 {
01966                                         v[i] = center[i] - traceEnt->r.absmax[i];
01967                                 } else 
01968                                 {
01969                                         v[i] = 0;
01970                                 }
01971                         }
01972 
01973                         VectorSubtract( traceEnt->r.absmax, traceEnt->r.absmin, size );
01974                         VectorMA( traceEnt->r.absmin, 0.5, size, ent_org );
01975 
01976                         //see if they're in front of me
01977                         //must be within the forward cone
01978                         VectorSubtract( ent_org, center, dir );
01979                         VectorNormalize( dir );
01980                         if ( (dot = DotProduct( dir, forward )) < 0.5 )
01981                                 continue;
01982 
01983                         //must be close enough
01984                         dist = VectorLength( v );
01985                         if ( dist >= radius ) 
01986                         {
01987                                 continue;
01988                         }
01989                 
01990                         //in PVS?
01991                         if ( !traceEnt->r.bmodel && !trap_InPVS( ent_org, self->client->ps.origin ) )
01992                         {//must be in PVS
01993                                 continue;
01994                         }
01995 
01996                         //Now check and see if we can actually hit it
01997                         trap_Trace( &tr, self->client->ps.origin, vec3_origin, vec3_origin, ent_org, self->s.number, MASK_SHOT );
01998                         if ( tr.fraction < 1.0f && tr.entityNum != traceEnt->s.number )
01999                         {//must have clear LOS
02000                                 continue;
02001                         }
02002 
02003                         // ok, we are within the radius, add us to the incoming list
02004                         ForceLightningDamage( self, traceEnt, dir, ent_org );
02005                 }
02006         }
02007         else
02008         {//trace-line
02009                 VectorMA( self->client->ps.origin, 2048, forward, end );
02010                 
02011                 trap_Trace( &tr, self->client->ps.origin, vec3_origin, vec3_origin, end, self->s.number, MASK_SHOT );
02012                 if ( tr.entityNum == ENTITYNUM_NONE || tr.fraction == 1.0 || tr.allsolid || tr.startsolid )
02013                 {
02014                         return;
02015                 }
02016                 
02017                 traceEnt = &g_entities[tr.entityNum];
02018                 ForceLightningDamage( self, traceEnt, forward, tr.endpos );
02019         }
02020 }

void ForceSpeed gentity_t self,
int  forceDuration
 

Definition at line 1596 of file w_force.c.

References CHAN_BODY, gentity_s::client, ENTITYNUM_WORLD, playerState_s::fd, playerState_s::forceAllowDeactivateTime, forcedata_s::forcePowersActive, FP_SPEED, g_entities, G_Sound(), G_SoundIndex(), gentity_t, gentity_s::health, gclient_s::holdingObjectiveItem, level, MAX_CLIENTS, gclient_s::ps, speedLoopSound, level_locals_t::time, TRACK_CHANNEL_2, WP_ForcePowerStart(), WP_ForcePowerStop(), and WP_ForcePowerUsable().

Referenced by ClientThink_real(), Jedi_DodgeEvasion(), and WP_DoSpecificPower().

01597 {
01598         if ( self->health <= 0 )
01599         {
01600                 return;
01601         }
01602 
01603         if (self->client->ps.forceAllowDeactivateTime < level.time &&
01604                 (self->client->ps.fd.forcePowersActive & (1 << FP_SPEED)) )
01605         {
01606                 WP_ForcePowerStop( self, FP_SPEED );
01607                 return;
01608         }
01609 
01610         if ( !WP_ForcePowerUsable( self, FP_SPEED ) )
01611         {
01612                 return;
01613         }
01614 
01615         if ( self->client->holdingObjectiveItem >= MAX_CLIENTS  
01616                 && self->client->holdingObjectiveItem < ENTITYNUM_WORLD )
01617         {//holding Siege item
01618                 if ( g_entities[self->client->holdingObjectiveItem].genericValue15 )
01619                 {//disables force powers
01620                         return;
01621                 }
01622         }
01623 
01624         self->client->ps.forceAllowDeactivateTime = level.time + 1500;
01625 
01626         WP_ForcePowerStart( self, FP_SPEED, forceDuration );
01627         G_Sound( self, CHAN_BODY, G_SoundIndex("sound/weapons/force/speed.wav") );
01628         G_Sound( self, TRACK_CHANNEL_2, speedLoopSound );
01629 }

void ForceTeamForceReplenish gentity_t self  ) 
 

Definition at line 1424 of file w_force.c.

References BG_ForcePowerDrain(), gentity_s::client, EV_TEAM_POWER, entityState_s::eventParm, playerState_s::fd, FORCE_LEVEL_2, FORCE_LEVEL_3, forcedata_s::forcePower, forcedata_s::forcePowerDebounce, forcedata_s::forcePowerLevel, forcePowerNeeded, ForcePowerUsableOn(), FP_TEAM_FORCE, g_entities, G_TempEntity(), gentity_t, gentity_s::health, level, MAX_CLIENTS, NULL, OnSameTeam(), playerState_s::origin, gclient_s::ps, gentity_s::s, level_locals_t::time, trap_InPVS(), vec3_t, VectorSubtract, WP_AddToClientBitflags(), and WP_ForcePowerUsable().

Referenced by ClientThink_real(), and WP_DoSpecificPower().

01425 {
01426         float radius = 256;
01427         int i = 0;
01428         gentity_t *ent;
01429         vec3_t a;
01430         int numpl = 0;
01431         int pl[MAX_CLIENTS];
01432         int poweradd = 0;
01433         gentity_t *te = NULL;
01434 
01435         if ( self->health <= 0 )
01436         {
01437                 return;
01438         }
01439 
01440         if ( !WP_ForcePowerUsable( self, FP_TEAM_FORCE ) )
01441         {
01442                 return;
01443         }
01444 
01445         if (self->client->ps.fd.forcePowerDebounce[FP_TEAM_FORCE] >= level.time)
01446         {
01447                 return;
01448         }
01449 
01450         if (self->client->ps.fd.forcePowerLevel[FP_TEAM_FORCE] == FORCE_LEVEL_2)
01451         {
01452                 radius *= 1.5;
01453         }
01454         if (self->client->ps.fd.forcePowerLevel[FP_TEAM_FORCE] == FORCE_LEVEL_3)
01455         {
01456                 radius *= 2;
01457         }
01458 
01459         while (i < MAX_CLIENTS)
01460         {
01461                 ent = &g_entities[i];
01462 
01463                 if (ent && ent->client && self != ent && OnSameTeam(self, ent) && ent->client->ps.fd.forcePower < 100 && ForcePowerUsableOn(self, ent, FP_TEAM_FORCE) &&
01464                         trap_InPVS(self->client->ps.origin, ent->client->ps.origin))
01465                 {
01466                         VectorSubtract(self->client->ps.origin, ent->client->ps.origin, a);
01467 
01468                         if (VectorLength(a) <= radius)
01469                         {
01470                                 pl[numpl] = i;
01471                                 numpl++;
01472                         }
01473                 }
01474 
01475                 i++;
01476         }
01477 
01478         if (numpl < 1)
01479         {
01480                 return;
01481         }
01482 
01483         if (numpl == 1)
01484         {
01485                 poweradd = 50;
01486         }
01487         else if (numpl == 2)
01488         {
01489                 poweradd = 33;
01490         }
01491         else
01492         {
01493                 poweradd = 25;
01494         }
01495         self->client->ps.fd.forcePowerDebounce[FP_TEAM_FORCE] = level.time + 2000;
01496 
01497         BG_ForcePowerDrain( &self->client->ps, FP_TEAM_FORCE, forcePowerNeeded[self->client->ps.fd.forcePowerLevel[FP_TEAM_FORCE]][FP_TEAM_FORCE] );
01498 
01499         i = 0;
01500 
01501         while (i < numpl)
01502         {
01503                 g_entities[pl[i]].client->ps.fd.forcePower += poweradd;
01504                 if (g_entities[pl[i]].client->ps.fd.forcePower > 100)
01505                 {
01506                         g_entities[pl[i]].client->ps.fd.forcePower = 100;
01507                 }
01508 
01509                 //At this point we know we got one, so add him into the collective event client bitflag
01510                 if (!te)
01511                 {
01512                         te = G_TempEntity( self->client->ps.origin, EV_TEAM_POWER);
01513                         te->s.eventParm = 2; //eventParm 1 is heal, eventParm 2 is force regen
01514                 }
01515 
01516                 WP_AddToClientBitflags(te, pl[i]);
01517                 //Now cramming it all into one event.. doing this many g_sound events at once was a Bad Thing.
01518                 
01519                 i++;
01520         }
01521 }

void ForceTeamHeal gentity_t self  ) 
 

Definition at line 1319 of file w_force.c.

References BG_ForcePowerDrain(), gentity_s::client, EV_TEAM_POWER, entityState_s::eventParm, playerState_s::fd, FORCE_LEVEL_2, FORCE_LEVEL_3, forcedata_s::forcePowerDebounce, forcedata_s::forcePowerLevel, forcePowerNeeded, ForcePowerUsableOn(), FP_TEAM_HEAL, g_entities, G_TempEntity(), gentity_t, gentity_s::health, level, MAX_CLIENTS, NULL, OnSameTeam(), playerState_s::origin, gclient_s::ps, gentity_s::s, STAT_HEALTH, STAT_MAX_HEALTH, playerState_s::stats, level_locals_t::time, trap_InPVS(), vec3_t, VectorSubtract, WP_AddToClientBitflags(), and WP_ForcePowerUsable().

Referenced by ClientThink_real(), and WP_DoSpecificPower().

01320 {
01321         float radius = 256;
01322         int i = 0;
01323         gentity_t *ent;
01324         vec3_t a;
01325         int numpl = 0;
01326         int pl[MAX_CLIENTS];
01327         int healthadd = 0;
01328         gentity_t *te = NULL;
01329 
01330         if ( self->health <= 0 )
01331         {
01332                 return;
01333         }
01334 
01335         if ( !WP_ForcePowerUsable( self, FP_TEAM_HEAL ) )
01336         {
01337                 return;
01338         }
01339 
01340         if (self->client->ps.fd.forcePowerDebounce[FP_TEAM_HEAL] >= level.time)
01341         {
01342                 return;
01343         }
01344 
01345         if (self->client->ps.fd.forcePowerLevel[FP_TEAM_HEAL] == FORCE_LEVEL_2)
01346         {
01347                 radius *= 1.5;
01348         }
01349         if (self->client->ps.fd.forcePowerLevel[FP_TEAM_HEAL] == FORCE_LEVEL_3)
01350         {
01351                 radius *= 2;
01352         }
01353 
01354         while (i < MAX_CLIENTS)
01355         {
01356                 ent = &g_entities[i];
01357 
01358                 if (ent && ent->client && self != ent && OnSameTeam(self, ent) && ent->client->ps.stats[STAT_HEALTH] < ent->client->ps.stats[STAT_MAX_HEALTH] && ent->client->ps.stats[STAT_HEALTH] > 0 && ForcePowerUsableOn(self, ent, FP_TEAM_HEAL) &&
01359                         trap_InPVS(self->client->ps.origin, ent->client->ps.origin))
01360                 {
01361                         VectorSubtract(self->client->ps.origin, ent->client->ps.origin, a);
01362 
01363                         if (VectorLength(a) <= radius)
01364                         {
01365                                 pl[numpl] = i;
01366                                 numpl++;
01367                         }
01368                 }
01369 
01370                 i++;
01371         }
01372 
01373         if (numpl < 1)
01374         {
01375                 return;
01376         }
01377 
01378         if (numpl == 1)
01379         {
01380                 healthadd = 50;
01381         }
01382         else if (numpl == 2)
01383         {
01384                 healthadd = 33;
01385         }
01386         else
01387         {
01388                 healthadd = 25;
01389         }
01390 
01391         self->client->ps.fd.forcePowerDebounce[FP_TEAM_HEAL] = level.time + 2000;
01392         i = 0;
01393 
01394         while (i < numpl)
01395         {
01396                 if (g_entities[pl[i]].client->ps.stats[STAT_HEALTH] > 0 &&
01397                         g_entities[pl[i]].health > 0)
01398                 {
01399                         g_entities[pl[i]].client->ps.stats[STAT_HEALTH] += healthadd;
01400                         if (g_entities[pl[i]].client->ps.stats[STAT_HEALTH] > g_entities[pl[i]].client->ps.stats[STAT_MAX_HEALTH])
01401                         {
01402                                 g_entities[pl[i]].client->ps.stats[STAT_HEALTH] = g_entities[pl[i]].client->ps.stats[STAT_MAX_HEALTH];
01403                         }
01404 
01405                         g_entities[pl[i]].health = g_entities[pl[i]].client->ps.stats[STAT_HEALTH];
01406 
01407                         //At this point we know we got one, so add him into the collective event client bitflag
01408                         if (!te)
01409                         {
01410                                 te = G_TempEntity( self->client->ps.origin, EV_TEAM_POWER);
01411                                 te->s.eventParm = 1; //eventParm 1 is heal, eventParm 2 is force regen
01412 
01413                                 //since we had an extra check above, do the drain now because we got at least one guy
01414                                 BG_ForcePowerDrain( &self->client->ps, FP_TEAM_HEAL, forcePowerNeeded[self->client->ps.fd.forcePowerLevel[FP_TEAM_HEAL]][FP_TEAM_HEAL] );
01415                         }
01416 
01417                         WP_AddToClientBitflags(te, pl[i]);
01418                         //Now cramming it all into one event.. doing this many g_sound events at once was a Bad Thing.
01419                 }
01420                 i++;
01421         }
01422 }

void ForceTelepathy gentity_t self  ) 
 

Definition at line 2723 of file w_force.c.

References AngleVectors(), CHAN_AUTO, gentity_s::client, trace_t::entityNum, ENTITYNUM_NONE, playerState_s::fd, FORCE_LEVEL_1, FORCE_LEVEL_2, FORCE_LEVEL_3, playerState_s::forceAllowDeactivateTime, playerState_s::forceHandExtend, playerState_s::forceHandExtendTime, forcedata_s::forcePowerLevel, forcedata_s::forcePowersActive, ForcePowerUsableOn(), ForceTelepathyCheckDirectNPCTarget(), FP_TELEPATHY, trace_t::fraction, g_entities, G_Sound(), G_SoundIndex(), gentity_t, HANDEXTEND_FORCEPUSH, HANDEXTEND_NONE, gentity_s::health, InFieldOfVision(), level, MAX_GENTITIES, MAX_TRICK_DISTANCE, NULL, entityState_s::number, OnSameTeam(), playerState_s::origin, entityState_s::pos, playerState_s::powerups, gclient_s::ps, PW_BLUEFLAG, PW_REDFLAG, qboolean, qfalse, qtrue, gentity_s::s, TEAM_SPECTATOR, level_locals_t::time, trap_EntitiesInBox(), trajectory_t::trBase, vec3_t, vectoangles(), VectorCopy, VectorSubtract, playerState_s::viewangles, playerState_s::viewheight, playerState_s::weaponTime, WP_AddAsMindtricked(), WP_ForcePowerStart(), WP_ForcePowerStop(), and WP_ForcePowerUsable().

Referenced by ClientThink_real(), and WP_DoSpecificPower().

02724 {
02725         trace_t tr;
02726         vec3_t tto, thispush_org, a;
02727         vec3_t mins, maxs, fwdangles, forward, right, center;
02728         int i;
02729         float visionArc = 0;
02730         float radius = MAX_TRICK_DISTANCE;
02731         qboolean        tookPower = qfalse;
02732 
02733         if ( self->health <= 0 )
02734         {
02735                 return;
02736         }
02737 
02738         if (self->client->ps.forceHandExtend != HANDEXTEND_NONE)
02739         {
02740                 return;
02741         }
02742 
02743         if (self->client->ps.weaponTime > 0)
02744         {
02745                 return;
02746         }
02747 
02748         if (self->client->ps.powerups[PW_REDFLAG] ||
02749                 self->client->ps.powerups[PW_BLUEFLAG])
02750         { //can't mindtrick while carrying the flag
02751                 return;
02752         }
02753 
02754         if (self->client->ps.forceAllowDeactivateTime < level.time &&
02755                 (self->client->ps.fd.forcePowersActive & (1 << FP_TELEPATHY)) )
02756         {
02757                 WP_ForcePowerStop( self, FP_TELEPATHY );
02758                 return;
02759         }
02760 
02761         if ( !WP_ForcePowerUsable( self, FP_TELEPATHY ) )
02762         {
02763                 return;
02764         }
02765 
02766         if ( ForceTelepathyCheckDirectNPCTarget( self, &tr, &tookPower ) )
02767         {//hit an NPC directly
02768                 self->client->ps.forceAllowDeactivateTime = level.time + 1500;
02769                 G_Sound( self, CHAN_AUTO, G_SoundIndex("sound/weapons/force/distract.wav") );
02770                 self->client->ps.forceHandExtend = HANDEXTEND_FORCEPUSH;
02771                 self->client->ps.forceHandExtendTime = level.time + 1000;
02772                 return;
02773         }
02774 
02775         if (self->client->ps.fd.forcePowerLevel[FP_TELEPATHY] == FORCE_LEVEL_2)
02776         {
02777                 visionArc = 180;
02778         }
02779         else if (self->client->ps.fd.forcePowerLevel[FP_TELEPATHY] == FORCE_LEVEL_3)
02780         {
02781                 visionArc = 360;
02782                 radius = MAX_TRICK_DISTANCE*2.0f;
02783         }
02784 
02785         VectorCopy( self->client->ps.viewangles, fwdangles );
02786         AngleVectors( fwdangles, forward, right, NULL );
02787         VectorCopy( self->client->ps.origin, center );
02788 
02789         for ( i = 0 ; i < 3 ; i++ ) 
02790         {
02791                 mins[i] = center[i] - radius;
02792                 maxs[i] = center[i] + radius;
02793         }
02794 
02795         if (self->client->ps.fd.forcePowerLevel[FP_TELEPATHY] == FORCE_LEVEL_1)
02796         {
02797                 if (tr.fraction != 1.0 &&
02798                         tr.entityNum != ENTITYNUM_NONE &&
02799                         g_entities[tr.entityNum].inuse &&
02800                         g_entities[tr.entityNum].client &&
02801                         g_entities[tr.entityNum].client->pers.connected &&
02802                         g_entities[tr.entityNum].client->sess.sessionTeam != TEAM_SPECTATOR)
02803                 {
02804                         WP_AddAsMindtricked(&self->client->ps.fd, tr.entityNum);
02805                         if ( !tookPower )
02806                         {
02807                                 WP_ForcePowerStart( self, FP_TELEPATHY, 0 );
02808                         }
02809 
02810                         G_Sound( self, CHAN_AUTO, G_SoundIndex("sound/weapons/force/distract.wav") );
02811 
02812                         self->client->ps.forceHandExtend = HANDEXTEND_FORCEPUSH;
02813                         self->client->ps.forceHandExtendTime = level.time + 1000;
02814 
02815                         return;
02816                 }
02817                 else
02818                 {
02819                         return;
02820                 }
02821         }
02822         else    //level 2 & 3
02823         {
02824                 gentity_t *ent;
02825                 int entityList[MAX_GENTITIES];
02826                 int numListedEntities;
02827                 int e = 0;
02828                 qboolean gotatleastone = qfalse;
02829 
02830                 numListedEntities = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES );
02831 
02832                 while (e < numListedEntities)
02833                 {
02834                         ent = &g_entities[entityList[e]];
02835 
02836                         if (ent)
02837                         { //not in the arc, don't consider it
02838                                 if (ent->client)
02839                                 {
02840                                         VectorCopy(ent->client->ps.origin, thispush_org);
02841                                 }
02842                                 else
02843                                 {
02844                                         VectorCopy(ent->s.pos.trBase, thispush_org);
02845                                 }
02846                                 VectorCopy(self->client->ps.origin, tto);
02847                                 tto[2] += self->client->ps.viewheight;
02848                                 VectorSubtract(thispush_org, tto, a);
02849                                 vectoangles(a, a);
02850 
02851                                 if (!ent->client)
02852                                 {
02853                                         entityList[e] = ENTITYNUM_NONE;
02854                                 }
02855                                 else if (!InFieldOfVision(self->client->ps.viewangles, visionArc, a))
02856                                 { //only bother with arc rules if the victim is a client
02857                                         entityList[e] = ENTITYNUM_NONE;
02858                                 }
02859                                 else if (!ForcePowerUsableOn(self, ent, FP_TELEPATHY))
02860                                 {
02861                                         entityList[e] = ENTITYNUM_NONE;
02862                                 }
02863                                 else if (OnSameTeam(self, ent))
02864                                 {
02865                                         entityList[e] = ENTITYNUM_NONE;
02866                                 }
02867                         }
02868                         ent = &g_entities[entityList[e]];
02869                         if (ent && ent != self && ent->client)
02870                         {
02871                                 gotatleastone = qtrue;
02872                                 WP_AddAsMindtricked(&self->client->ps.fd, ent->s.number);
02873                         }
02874                         e++;
02875                 }
02876 
02877                 if (gotatleastone)
02878                 {
02879                         self->client->ps.forceAllowDeactivateTime = level.time + 1500;
02880 
02881                         if ( !tookPower )
02882                         {
02883                                 WP_ForcePowerStart( self, FP_TELEPATHY, 0 );
02884                         }
02885 
02886                         G_Sound( self, CHAN_AUTO, G_SoundIndex("sound/weapons/force/distract.wav") );
02887 
02888                         self->client->ps.forceHandExtend = HANDEXTEND_FORCEPUSH;
02889                         self->client->ps.forceHandExtendTime = level.time + 1000;
02890                 }
02891         }
02892 
02893 }

qboolean ForceTelepathyCheckDirectNPCTarget gentity_t self,
trace_t tr,
qboolean tookPower
 

Definition at line 2527 of file w_force.c.

References AddSightEvent(), AddSoundEvent(), AEL_SUSPICIOUS, trace_t::allsolid, AngleVectors(), BLOCKED_NONE, BSET_MINDTRICK, gNPC_t::charmedTime, CLASS_ATST, CLASS_BOBAFETT, CLASS_GALAKMECH, CLASS_GONK, CLASS_MARK1, CLASS_MARK2, CLASS_MOUSE, CLASS_PROBE, CLASS_PROTOCOL, CLASS_R2D2, CLASS_R5D2, CLASS_RANCOR, CLASS_REBORN, CLASS_REMOTE, CLASS_SEEKER, gentity_s::client, gNPC_t::confusionTime, trace_t::endpos, gentity_s::enemy, gclient_s::enemyTeam, trace_t::entityNum, ENTITYNUM_NONE, renderInfo_s::eyeAngles, renderInfo_s::eyePoint, playerState_s::fd, FORCE_LEVEL_1, FORCE_LEVEL_2, forcedata_s::forcePowerLevel, FP_TELEPATHY, trace_t::fraction, G_ActivateBehavior(), G_ClearEnemy(), G_EffectIndex(), g_entities, G_PlayEffectID(), gentity_s::genericValue1, gentity_s::genericValue2, gentity_s::genericValue3, gentity_t, gclient_s::leader, level, MASK_PLAYERSOLID, MAX_CLIENTS, MAX_TRICK_DISTANCE, mindTrickTime, cplane_s::normal, gentity_s::NPC, gclient_s::NPC_class, NPC_Jedi_PlayConfusionSound(), NPC_PlayConfusionSound(), NPC_UseResponse(), NPCTEAM_ENEMY, NPCTEAM_NEUTRAL, NPCTEAM_PLAYER, NULL, entityState_s::number, playerState_s::origin, trace_t::plane, gclient_s::playerTeam, PM_DEAD, playerState_s::pm_type, gclient_s::ps, qboolean, qfalse, qtrue, gclient_s::renderInfo, gentity_s::s, playerState_s::saberBlocked, SCF_NO_FORCE, SCF_NO_MIND_TRICK, SCF_NO_RESPONSE, gNPC_t::scriptFlags, gclient_s::sess, clientSession_t::sessionTeam, trace_t::startsolid, TEAM_BLUE, TEAM_RED, entityState_s::teamowner, level_locals_t::time, trap_Trace(), vec3_t, VectorCopy, VectorNormalize(), playerState_s::viewangles, playerState_s::viewheight, entityState_s::weapon, playerState_s::weaponTime, WP_ForcePowerStart(), WP_NONE, and WP_SABER.

Referenced by ForceTelepathy().

02528 {
02529         gentity_t       *traceEnt;
02530         qboolean        targetLive = qfalse, mindTrickDone = qfalse;
02531         vec3_t          tfrom, tto, fwd;
02532         float           radius = MAX_TRICK_DISTANCE;
02533 
02534         //Check for a direct usage on NPCs first
02535         VectorCopy(self->client->ps.origin, tfrom);
02536         tfrom[2] += self->client->ps.viewheight;
02537         AngleVectors(self->client->ps.viewangles, fwd, NULL, NULL);
02538         tto[0] = tfrom[0] + fwd[0]*radius/2;
02539         tto[1] = tfrom[1] + fwd[1]*radius/2;
02540         tto[2] = tfrom[2] + fwd[2]*radius/2;
02541 
02542         trap_Trace( tr, tfrom, NULL, NULL, tto, self->s.number, MASK_PLAYERSOLID );
02543         
02544         if ( tr->entityNum == ENTITYNUM_NONE 
02545                 || tr->fraction == 1.0f
02546                 || tr->allsolid 
02547                 || tr->startsolid )
02548         {
02549                 return qfalse;
02550         }
02551         
02552         traceEnt = &g_entities[tr->entityNum];
02553         
02554         if( traceEnt->NPC 
02555                 && traceEnt->NPC->scriptFlags & SCF_NO_FORCE )
02556         {
02557                 return qfalse;
02558         }
02559 
02560         if ( traceEnt && traceEnt->client  )
02561         {
02562                 switch ( traceEnt->client->NPC_class )
02563                 {
02564                 case CLASS_GALAKMECH://cant grip him, he's in armor
02565                 case CLASS_ATST://much too big to grip!
02566                 //no droids either
02567                 case CLASS_PROBE:
02568                 case CLASS_GONK:
02569                 case CLASS_R2D2:
02570                 case CLASS_R5D2:
02571                 case CLASS_MARK1:
02572                 case CLASS_MARK2:
02573                 case CLASS_MOUSE:
02574                 case CLASS_SEEKER:
02575                 case CLASS_REMOTE:
02576                 case CLASS_PROTOCOL:
02577                 case CLASS_BOBAFETT:
02578                 case CLASS_RANCOR:
02579                         break;
02580                 default:
02581                         targetLive = qtrue;
02582                         break;
02583                 }
02584         }
02585 
02586         if ( traceEnt->s.number < MAX_CLIENTS )
02587         {//a regular client
02588                 return qfalse;
02589         }
02590 
02591         if ( targetLive && traceEnt->NPC )
02592         {//hit an organic non-player
02593                 vec3_t  eyeDir;
02594                 if ( G_ActivateBehavior( traceEnt, BSET_MINDTRICK ) )
02595                 {//activated a script on him
02596                         //FIXME: do the visual sparkles effect on their heads, still?
02597                         WP_ForcePowerStart( self, FP_TELEPATHY, 0 );
02598                 }
02599                 else if ( (self->NPC && traceEnt->client->playerTeam != self->client->playerTeam)
02600                         || (!self->NPC && traceEnt->client->playerTeam != self->client->sess.sessionTeam) )
02601                 {//an enemy
02602                         int override = 0;
02603                         if ( (traceEnt->NPC->scriptFlags&SCF_NO_MIND_TRICK) )
02604                         {
02605                         }
02606                         else if ( traceEnt->s.weapon != WP_SABER 
02607                                 && traceEnt->client->NPC_class != CLASS_REBORN )
02608                         {//haha!  Jedi aren't easily confused!
02609                                 if ( self->client->ps.fd.forcePowerLevel[FP_TELEPATHY] > FORCE_LEVEL_2 )
02610                                 {//turn them to our side
02611                                         //if mind trick 3 and aiming at an enemy need more force power
02612                                         if ( traceEnt->s.weapon != WP_NONE )
02613                                         {//don't charm people who aren't capable of fighting... like ugnaughts and droids
02614                                                 int newPlayerTeam, newEnemyTeam;
02615 
02616                                                 if ( traceEnt->enemy )
02617                                                 {
02618                                                         G_ClearEnemy( traceEnt );
02619                                                 }
02620                                                 if ( traceEnt->NPC )
02621                                                 {
02622                                                         //traceEnt->NPC->tempBehavior = BS_FOLLOW_LEADER;
02623                                                         traceEnt->client->leader = self;
02624                                                 }
02625                                                 //FIXME: maybe pick an enemy right here?
02626                                                 if ( self->NPC )
02627                                                 {//NPC
02628                                                         newPlayerTeam = self->client->playerTeam;
02629                                                         newEnemyTeam = self->client->enemyTeam;
02630                                                 }
02631                                                 else
02632                                                 {//client/bot
02633                                                         if ( self->client->sess.sessionTeam == TEAM_BLUE )
02634                                                         {//rebel
02635                                                                 newPlayerTeam = NPCTEAM_PLAYER;
02636                                                                 newEnemyTeam = NPCTEAM_ENEMY;
02637                                                         }
02638                                                         else if ( self->client->sess.sessionTeam == TEAM_RED )
02639                                                         {//imperial
02640                                                                 newPlayerTeam = NPCTEAM_ENEMY;
02641                                                                 newEnemyTeam = NPCTEAM_PLAYER;
02642                                                         }
02643                                                         else
02644                                                         {//neutral - wan't attack anyone
02645                                                                 newPlayerTeam = NPCTEAM_NEUTRAL;
02646                                                                 newEnemyTeam = NPCTEAM_NEUTRAL;
02647                                                         }
02648                                                 }
02649                                                 //store these for retrieval later
02650                                                 traceEnt->genericValue1 = traceEnt->client->playerTeam;
02651                                                 traceEnt->genericValue2 = traceEnt->client->enemyTeam;
02652                                                 traceEnt->genericValue3 = traceEnt->s.teamowner;
02653                                                 //set the new values
02654                                                 traceEnt->client->playerTeam = newPlayerTeam;
02655                                                 traceEnt->client->enemyTeam = newEnemyTeam;
02656                                                 traceEnt->s.teamowner = newPlayerTeam;
02657                                                 //FIXME: need a *charmed* timer on this...?  Or do TEAM_PLAYERS assume that "confusion" means they should switch to team_enemy when done?
02658                                                 traceEnt->NPC->charmedTime = level.time + mindTrickTime[self->client->ps.fd.forcePowerLevel[FP_TELEPATHY]];
02659                                         }
02660                                 }
02661                                 else
02662                                 {//just confuse them
02663                                         //somehow confuse them?  Set don't fire to true for a while?  Drop their aggression?  Maybe just take their enemy away and don't let them pick one up for a while unless shot?
02664                                         traceEnt->NPC->confusionTime = level.time + mindTrickTime[self->client->ps.fd.forcePowerLevel[FP_TELEPATHY]];//confused for about 10 seconds
02665                                         NPC_PlayConfusionSound( traceEnt );
02666                                         if ( traceEnt->enemy )
02667                                         {
02668                                                 G_ClearEnemy( traceEnt );
02669                                         }
02670                                 }
02671                         }
02672                         else
02673                         {
02674                                 NPC_Jedi_PlayConfusionSound( traceEnt );
02675                         }
02676                         WP_ForcePowerStart( self, FP_TELEPATHY, override );
02677                 }
02678                 else if ( traceEnt->client->playerTeam == self->client->playerTeam )
02679                 {//an ally
02680                         //maybe just have him look at you?  Respond?  Take your enemy?
02681                         if ( traceEnt->client->ps.pm_type < PM_DEAD && traceEnt->NPC!=NULL && !(traceEnt->NPC->scriptFlags&SCF_NO_RESPONSE) )
02682                         {
02683                                 NPC_UseResponse( traceEnt, self, qfalse );
02684                                 WP_ForcePowerStart( self, FP_TELEPATHY, 1 );
02685                         }
02686                 }//NOTE: no effect on TEAM_NEUTRAL?
02687                 AngleVectors( traceEnt->client->renderInfo.eyeAngles, eyeDir, NULL, NULL );
02688                 VectorNormalize( eyeDir );
02689                 G_PlayEffectID( G_EffectIndex( "force/force_touch" ), traceEnt->client->renderInfo.eyePoint, eyeDir );
02690 
02691                 //make sure this plays and that you cannot press fire for about 1 second after this
02692                 //FIXME: BOTH_FORCEMINDTRICK or BOTH_FORCEDISTRACT
02693                 //NPC_SetAnim( self, SETANIM_TORSO, BOTH_MINDTRICK1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_RESTART|SETANIM_FLAG_HOLD );
02694                 //FIXME: build-up or delay this until in proper part of anim
02695                 mindTrickDone = qtrue;
02696         }
02697         else 
02698         {
02699                 if ( self->client->ps.fd.forcePowerLevel[FP_TELEPATHY] > FORCE_LEVEL_1 && tr->fraction * 2048 > 64 )
02700                 {//don't create a diversion less than 64 from you of if at power level 1
02701                         //use distraction anim instead
02702                         G_PlayEffectID( G_EffectIndex( "force/force_touch" ), tr->endpos, tr->plane.normal );
02703                         //FIXME: these events don't seem to always be picked up...?
02704                         AddSoundEvent( self, tr->endpos, 512, AEL_SUSPICIOUS, qtrue );//, qtrue );
02705                         AddSightEvent( self, tr->endpos, 512, AEL_SUSPICIOUS, 50 );
02706                         WP_ForcePowerStart( self, FP_TELEPATHY, 0 );
02707                         *tookPower = qtrue;
02708                 }
02709                 //NPC_SetAnim( self, SETANIM_TORSO, BOTH_MINDTRICK2, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_RESTART|SETANIM_FLAG_HOLD );
02710         }
02711         //self->client->ps.saberMove = self->client->ps.saberBounceMove = LS_READY;//don't finish whatever saber anim you may have been in
02712         self->client->ps.saberBlocked = BLOCKED_NONE;
02713         self->client->ps.weaponTime = 1000;
02714         /*
02715         if ( self->client->ps.fd.forcePowersActive&(1<<FP_SPEED) )
02716         {
02717                 self->client->ps.weaponTime = floor( self->client->ps.weaponTime * g_timescale->value );
02718         }
02719         */
02720         return qtrue;
02721 }

void ForceThrow gentity_t self,
qboolean  pull
 

Definition at line 3054 of file w_force.c.

References entityShared_t::absmax, entityShared_t::absmin, trace_t::allsolid, AngleVectors(), BG_KnockDownable(), bgEntity_t, entityShared_t::bmodel, CanCounterThrow(), CHAN_BODY, CLASS_ATST, CLASS_GALAKMECH, CLASS_RANCOR, gentity_s::classname, client, gentity_s::client, gclient_s::dangerTime, DotProduct, EF_INVULNERABLE, EF_MISSILE_STICK, EF_NODRAW, playerState_s::eFlags, entityState_s::eFlags, vehicleInfo_t::Eject, trace_t::entityNum, ENTITYNUM_NONE, ET_ITEM, ET_MISSILE, ET_NPC, entityState_s::eType, playerState_s::fd, FORCE_LEVEL_1, FORCE_LEVEL_2, FORCE_LEVEL_3, playerState_s::forceDodgeAnim, forcedata_s::forceGripBeingGripped, playerState_s::forceHandExtend, playerState_s::forceHandExtendTime, forcedata_s::forcePowerLevel, forcePowerNeeded, ForcePowerUsableOn(), FP_ABSORB, FP_GRIP, FP_PULL, FP_PUSH, trace_t::fraction, g_debugMelee, g_entities, g_gametype, G_InGetUpAnim(), G_LetGoOfWall(), G_ReflectMissile(), G_Sound(), G_SoundIndex(), g_useWhileThrowing, entityState_s::genericenemyindex, gentity_t, GEntity_UseFunc(), GT_SIEGE, HANDEXTEND_FORCEPULL, HANDEXTEND_FORCEPUSH, HANDEXTEND_KNOCKDOWN, HANDEXTEND_NONE, gentity_s::health, InFieldOfVision(), vmCvar_t::integer, gentity_s::inuse, gclient_s::invulnerableTimer, level, playerState_s::m_iVehicleNum, gentity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, MASK_PLAYERSOLID, MASK_SHOT, MAX_CLIENTS, MAX_GENTITIES, MOVER_POS1, MOVER_POS2, gentity_s::moverState, gclient_s::NPC_class, NULL, entityState_s::number, OnSameTeam(), playerState_s::origin, PMF_STUCK_TO_WALL, entityState_s::pos, playerState_s::powerups, gclient_s::ps, PW_DISINT_4, PW_PULL, Q_irand(), Q_stricmp(), qboolean, qfalse, qtrue, gentity_s::r, gentity_s::s, playerState_s::saberInFlight, playerState_s::saberLockFrame, playerState_s::saberLockHits, playerState_s::saberLockTime, gentity_s::spawnflags, SPF_BUTTON_FPUSHABLE, trace_t::startsolid, level_locals_t::time, TossClientWeapon(), Touch_Button(), TR_INTERPOLATE, TR_STATIONARY, trap_EntitiesInBox(), trap_InPVS(), trap_Trace(), trajectory_t::trBase, trajectory_t::trType, vehicleInfo_t::type, vec3_origin, vec3_t, vectoangles(), VectorAdd, VectorCopy, VectorMA, VectorNormalize(), VectorSubtract, VH_ANIMAL, VH_SPEEDER, playerState_s::viewangles, playerState_s::viewheight, entityState_s::weapon, playerState_s::weapon, playerState_s::weaponTime, WP_AbsorbConversion(), WP_ForcePowerStart(), WP_ForcePowerStop(), WP_ForcePowerUsable(), WP_SABER, and WP_THERMAL.

Referenced by ClientThink_real(), WP_DoSpecificPower(), and WP_SaberStartMissileBlockCheck().

03055 {
03056         //shove things in front of you away
03057         float           dist;
03058         gentity_t       *ent;
03059         int                     entityList[MAX_GENTITIES];
03060         gentity_t       *push_list[MAX_GENTITIES];
03061         int                     numListedEntities;
03062         vec3_t          mins, maxs;
03063         vec3_t          v;
03064         int                     i, e;
03065         int                     ent_count = 0;
03066         int                     radius = 1024; //since it's view-based now. //350;
03067         int                     powerLevel;
03068         int                     visionArc;
03069         int                     pushPower;
03070         int                     pushPowerMod;
03071         vec3_t          center, ent_org, size, forward, right, end, dir, fwdangles = {0};
03072         float           dot1;
03073         trace_t         tr;
03074         int                     x;
03075         vec3_t          pushDir;
03076         vec3_t          thispush_org;
03077         vec3_t          tfrom, tto, fwd, a;
03078         float           knockback = pull?0:200;
03079         int                     powerUse = 0;
03080 
03081         visionArc = 0;
03082 
03083         if (self->client->ps.forceHandExtend != HANDEXTEND_NONE && (self->client->ps.forceHandExtend != HANDEXTEND_KNOCKDOWN || !G_InGetUpAnim(&self->client->ps)))
03084         {
03085                 return;
03086         }
03087 
03088         if (!g_useWhileThrowing.integer && self->client->ps.saberInFlight)
03089         {
03090                 return;
03091         }
03092 
03093         if (self->client->ps.weaponTime > 0)
03094         {
03095                 return;
03096         }
03097 
03098         if ( self->health <= 0 )
03099         {
03100                 return;
03101         }
03102         if ( self->client->ps.powerups[PW_DISINT_4] > level.time )
03103         {
03104                 return;
03105         }
03106         if (pull)
03107         {
03108                 powerUse = FP_PULL;
03109         }
03110         else
03111         {
03112                 powerUse = FP_PUSH;
03113         }
03114 
03115         if ( !WP_ForcePowerUsable( self, powerUse ) )
03116         {
03117                 return;
03118         }
03119 
03120         if (!pull && self->client->ps.saberLockTime > level.time && self->client->ps.saberLockFrame)
03121         {
03122                 G_Sound( self, CHAN_BODY, G_SoundIndex( "sound/weapons/force/push.wav" ) );
03123                 self->client->ps.powerups[PW_DISINT_4] = level.time + 1500;
03124 
03125                 self->client->ps.saberLockHits += self->client->ps.fd.forcePowerLevel[FP_PUSH]*2;
03126 
03127                 WP_ForcePowerStart( self, FP_PUSH, 0 );
03128                 return;
03129         }
03130 
03131         WP_ForcePowerStart( self, powerUse, 0 );
03132 
03133         //make sure this plays and that you cannot press fire for about 1 second after this
03134         if ( pull )
03135         {
03136                 G_Sound( self, CHAN_BODY, G_SoundIndex( "sound/weapons/force/pull.wav" ) );
03137                 if (self->client->ps.forceHandExtend == HANDEXTEND_NONE)
03138                 {
03139                         self->client->ps.forceHandExtend = HANDEXTEND_FORCEPULL;
03140                         if ( g_gametype.integer == GT_SIEGE && self->client->ps.weapon == WP_SABER )
03141                         {//hold less so can attack right after a pull
03142                                 self->client->ps.forceHandExtendTime = level.time + 200;
03143                         }
03144                         else
03145                         {
03146                                 self->client->ps.forceHandExtendTime = level.time + 400;
03147                         }
03148                 }
03149                 self->client->ps.powerups[PW_DISINT_4] = self->client->ps.forceHandExtendTime + 200;
03150                 self->client->ps.powerups[PW_PULL] = self->client->ps.powerups[PW_DISINT_4];
03151         }
03152         else
03153         {
03154                 G_Sound( self, CHAN_BODY, G_SoundIndex( "sound/weapons/force/push.wav" ) );
03155                 if (self->client->ps.forceHandExtend == HANDEXTEND_NONE)
03156                 {
03157                         self->client->ps.forceHandExtend = HANDEXTEND_FORCEPUSH;
03158                         self->client->ps.forceHandExtendTime = level.time + 1000;
03159                 }
03160                 else if (self->client->ps.forceHandExtend == HANDEXTEND_KNOCKDOWN && G_InGetUpAnim(&self->client->ps))
03161                 {
03162                         if (self->client->ps.forceDodgeAnim > 4)
03163                         {
03164                                 self->client->ps.forceDodgeAnim -= 8;
03165                         }
03166                         self->client->ps.forceDodgeAnim += 8; //special case, play push on upper torso, but keep playing current knockdown anim on legs
03167                 }
03168                 self->client->ps.powerups[PW_DISINT_4] = level.time + 1100;
03169                 self->client->ps.powerups[PW_PULL] = 0;
03170         }
03171 
03172         VectorCopy( self->client->ps.viewangles, fwdangles );
03173         AngleVectors( fwdangles, forward, right, NULL );
03174         VectorCopy( self->client->ps.origin, center );
03175 
03176         for ( i = 0 ; i < 3 ; i++ ) 
03177         {
03178                 mins[i] = center[i] - radius;
03179                 maxs[i] = center[i] + radius;
03180         }
03181 
03182 
03183         if (pull)
03184         {
03185                 powerLevel = self->client->ps.fd.forcePowerLevel[FP_PULL];
03186                 pushPower = 256*self->client->ps.fd.forcePowerLevel[FP_PULL];
03187         }
03188         else
03189         {
03190                 powerLevel = self->client->ps.fd.forcePowerLevel[FP_PUSH];
03191                 pushPower = 256*self->client->ps.fd.forcePowerLevel[FP_PUSH];
03192         }
03193 
03194         if (!powerLevel)
03195         { //Shouldn't have made it here..
03196                 return;
03197         }
03198 
03199         if (powerLevel == FORCE_LEVEL_2)
03200         {
03201                 visionArc = 60;
03202         }
03203         else if (powerLevel == FORCE_LEVEL_3)
03204         {
03205                 visionArc = 180;
03206         }
03207 
03208         if (powerLevel == FORCE_LEVEL_1)
03209         { //can only push/pull targeted things at level 1
03210                 VectorCopy(self->client->ps.origin, tfrom);
03211                 tfrom[2] += self->client->ps.viewheight;
03212                 AngleVectors(self->client->ps.viewangles, fwd, NULL, NULL);
03213                 tto[0] = tfrom[0] + fwd[0]*radius/2;
03214                 tto[1] = tfrom[1] + fwd[1]*radius/2;
03215                 tto[2] = tfrom[2] + fwd[2]*radius/2;
03216 
03217                 trap_Trace(&tr, tfrom, NULL, NULL, tto, self->s.number, MASK_PLAYERSOLID);
03218 
03219                 if (tr.fraction != 1.0 &&
03220                         tr.entityNum != ENTITYNUM_NONE)
03221                 {
03222                         if (!g_entities[tr.entityNum].client && g_entities[tr.entityNum].s.eType == ET_NPC)
03223                         { //g2animent
03224                                 if (g_entities[tr.entityNum].s.genericenemyindex < level.time)
03225                                 {
03226                                         g_entities[tr.entityNum].s.genericenemyindex = level.time + 2000;
03227                                 }
03228                         }
03229 
03230                         numListedEntities = 0;
03231                         entityList[numListedEntities] = tr.entityNum;
03232 
03233                         if (pull)
03234                         {
03235                                 if (!ForcePowerUsableOn(self, &g_entities[tr.entityNum], FP_PULL))
03236                                 {
03237                                         return;
03238                                 }
03239                         }
03240                         else
03241                         {
03242                                 if (!ForcePowerUsableOn(self, &g_entities[tr.entityNum], FP_PUSH))
03243                                 {
03244                                         return;
03245                                 }
03246                         }
03247                         numListedEntities++;
03248                 }
03249                 else
03250                 {
03251                         //didn't get anything, so just
03252                         return;
03253                 }
03254         }
03255         else
03256         {
03257                 numListedEntities = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES );
03258 
03259                 e = 0;
03260 
03261                 while (e < numListedEntities)
03262                 {
03263                         ent = &g_entities[entityList[e]];
03264 
03265                         if (!ent->client && ent->s.eType == ET_NPC)
03266                         { //g2animent
03267                                 if (ent->s.genericenemyindex < level.time)
03268                                 {
03269                                         ent->s.genericenemyindex = level.time + 2000;
03270                                 }
03271                         }
03272 
03273                         if (ent)
03274                         {
03275                                 if (ent->client)
03276                                 {
03277                                         VectorCopy(ent->client->ps.origin, thispush_org);
03278                                 }
03279                                 else
03280                                 {
03281                                         VectorCopy(ent->s.pos.trBase, thispush_org);
03282                                 }
03283                         }
03284 
03285                         if (ent)
03286                         { //not in the arc, don't consider it
03287                                 VectorCopy(self->client->ps.origin, tto);
03288                                 tto[2] += self->client->ps.viewheight;
03289                                 VectorSubtract(thispush_org, tto, a);
03290                                 vectoangles(a, a);
03291 
03292                                 if (ent->client && !InFieldOfVision(self->client->ps.viewangles, visionArc, a) &&
03293                                         ForcePowerUsableOn(self, ent, powerUse))
03294                                 { //only bother with arc rules if the victim is a client
03295                                         entityList[e] = ENTITYNUM_NONE;
03296                                 }
03297                                 else if (ent->client)
03298                                 {
03299                                         if (pull)
03300                                         {
03301                                                 if (!ForcePowerUsableOn(self, ent, FP_PULL))
03302                                                 {
03303                                                         entityList[e] = ENTITYNUM_NONE;
03304                                                 }
03305                                         }
03306                                         else
03307                                         {
03308                                                 if (!ForcePowerUsableOn(self, ent, FP_PUSH))
03309                                                 {
03310                                                         entityList[e] = ENTITYNUM_NONE;
03311                                                 }
03312                                         }
03313                                 }
03314                         }
03315                         e++;
03316                 }
03317         }
03318 
03319         for ( e = 0 ; e < numListedEntities ; e++ ) 
03320         {
03321                 if (entityList[e] != ENTITYNUM_NONE &&
03322                         entityList[e] >= 0 &&
03323                         entityList[e] < MAX_GENTITIES)
03324                 {
03325                         ent = &g_entities[entityList[e]];
03326                 }
03327                 else
03328                 {
03329                         ent = NULL;
03330                 }
03331 
03332                 if (!ent)
03333                         continue;
03334                 if (ent == self)
03335                         continue;
03336                 if (ent->client && OnSameTeam(ent, self))
03337                 {
03338                         continue;
03339                 }
03340                 if ( !(ent->inuse) )
03341                         continue;
03342                 if ( ent->s.eType != ET_MISSILE )
03343                 {
03344                         if ( ent->s.eType != ET_ITEM )
03345                         {
03346                                 //FIXME: need pushable objects
03347                                 if ( Q_stricmp( "func_button", ent->classname ) == 0 )
03348                                 {//we might push it
03349                                         if ( pull || !(ent->spawnflags&SPF_BUTTON_FPUSHABLE) )
03350                                         {//not force-pushable, never pullable
03351                                                 continue;
03352                                         }
03353                                 }
03354                                 else
03355                                 {
03356                                         if ( ent->s.eFlags & EF_NODRAW )
03357                                         {
03358                                                 continue;
03359                                         }
03360                                         if ( !ent->client )
03361                                         {
03362                                                 if ( Q_stricmp( "lightsaber", ent->classname ) != 0 )
03363                                                 {//not a lightsaber 
03364                                                         if ( Q_stricmp( "func_door", ent->classname ) != 0 || !(ent->spawnflags & 2/*MOVER_FORCE_ACTIVATE*/) )
03365                                                         {//not a force-usable door
03366                                                                 if ( Q_stricmp( "func_static", ent->classname ) != 0 || (!(ent->spawnflags&1/*F_PUSH*/)&&!(ent->spawnflags&2/*F_PULL*/)) )
03367                                                                 {//not a force-usable func_static
03368                                                                         if ( Q_stricmp( "limb", ent->classname ) )
03369                                                                         {//not a limb
03370                                                                                 continue;
03371                                                                         }
03372                                                                 }
03373                                                         }
03374                                                         else if ( ent->moverState != MOVER_POS1 && ent->moverState != MOVER_POS2 )
03375                                                         {//not at rest
03376                                                                 continue;
03377                                                         }
03378                                                 }
03379                                         }
03380                                         else if ( ent->client->NPC_class == CLASS_GALAKMECH 
03381                                                 || ent->client->NPC_class == CLASS_ATST
03382                                                 || ent->client->NPC_class == CLASS_RANCOR )
03383                                         {//can't push ATST or Galak or Rancor
03384                                                 continue;
03385                                         }
03386                                 }
03387                         }
03388                 }
03389                 else
03390                 {
03391                         if ( ent->s.pos.trType == TR_STATIONARY && (ent->s.eFlags&EF_MISSILE_STICK) )
03392                         {//can't force-push/pull stuck missiles (detpacks, tripmines)
03393                                 continue;
03394                         }
03395                         if ( ent->s.pos.trType == TR_STATIONARY && ent->s.weapon != WP_THERMAL )
03396                         {//only thermal detonators can be pushed once stopped
03397                                 continue;
03398                         }
03399                 }
03400 
03401                 //this is all to see if we need to start a saber attack, if it's in flight, this doesn't matter
03402                 // find the distance from the edge of the bounding box
03403                 for ( i = 0 ; i < 3 ; i++ ) 
03404                 {
03405                         if ( center[i] < ent->r.absmin[i] ) 
03406                         {
03407                                 v[i] = ent->r.absmin[i] - center[i];
03408                         } else if ( center[i] > ent->r.absmax[i] ) 
03409                         {
03410                                 v[i] = center[i] - ent->r.absmax[i];
03411                         } else 
03412                         {
03413                                 v[i] = 0;
03414                         }
03415                 }
03416 
03417                 VectorSubtract( ent->r.absmax, ent->r.absmin, size );
03418                 VectorMA( ent->r.absmin, 0.5, size, ent_org );
03419 
03420                 VectorSubtract( ent_org, center, dir );
03421                 VectorNormalize( dir );
03422                 if ( (dot1 = DotProduct( dir, forward )) < 0.6 )
03423                         continue;
03424 
03425                 dist = VectorLength( v );
03426 
03427                 //Now check and see if we can actually deflect it
03428                 //method1
03429                 //if within a certain range, deflect it
03430                 if ( dist >= radius ) 
03431                 {
03432                         continue;
03433                 }
03434         
03435                 //in PVS?
03436                 if ( !ent->r.bmodel && !trap_InPVS( ent_org, self->client->ps.origin ) )
03437                 {//must be in PVS
03438                         continue;
03439                 }
03440 
03441                 //really should have a clear LOS to this thing...
03442                 trap_Trace( &tr, self->client->ps.origin, vec3_origin, vec3_origin, ent_org, self->s.number, MASK_SHOT );
03443                 if ( tr.fraction < 1.0f && tr.entityNum != ent->s.number )
03444                 {//must have clear LOS
03445                         //try from eyes too before you give up
03446                         vec3_t eyePoint;
03447                         VectorCopy(self->client->ps.origin, eyePoint);
03448                         eyePoint[2] += self->client->ps.viewheight;
03449                         trap_Trace( &tr, eyePoint, vec3_origin, vec3_origin, ent_org, self->s.number, MASK_SHOT );
03450 
03451                         if ( tr.fraction < 1.0f && tr.entityNum != ent->s.number )
03452                         {
03453                                 continue;
03454                         }
03455                 }
03456 
03457                 // ok, we are within the radius, add us to the incoming list
03458                 push_list[ent_count] = ent;
03459                 ent_count++;
03460         }
03461 
03462         if ( ent_count )
03463         {
03464                 //method1:
03465                 for ( x = 0; x < ent_count; x++ )
03466                 {
03467                         int modPowerLevel = powerLevel;
03468 
03469         
03470                         if (push_list[x]->client)
03471                         {
03472                                 modPowerLevel = WP_AbsorbConversion(push_list[x], push_list[x]->client->ps.fd.forcePowerLevel[FP_ABSORB], self, powerUse, powerLevel, forcePowerNeeded[self->client->ps.fd.forcePowerLevel[powerUse]][powerUse]);
03473                                 if (modPowerLevel == -1)
03474                                 {
03475                                         modPowerLevel = powerLevel;
03476                                 }
03477                         }
03478 
03479                         pushPower = 256*modPowerLevel;
03480 
03481                         if (push_list[x]->client)
03482                         {
03483                                 VectorCopy(push_list[x]->client->ps.origin, thispush_org);
03484                         }
03485                         else
03486                         {
03487                                 VectorCopy(push_list[x]->s.origin, thispush_org);
03488                         }
03489 
03490                         if ( push_list[x]->client )
03491                         {//FIXME: make enemy jedi able to hunker down and resist this?
03492                                 int otherPushPower = push_list[x]->client->ps.fd.forcePowerLevel[powerUse];
03493                                 qboolean canPullWeapon = qtrue;
03494                                 float dirLen = 0;
03495 
03496                                 if ( g_debugMelee.integer )
03497                                 {
03498                                         if ( (push_list[x]->client->ps.pm_flags&PMF_STUCK_TO_WALL) )
03499                                         {//no resistance if stuck to wall
03500                                                 //push/pull them off the wall
03501                                                 otherPushPower = 0;
03502                                                 G_LetGoOfWall( push_list[x] );
03503                                         }
03504                                 }
03505 
03506                                 knockback = pull?0:200;
03507 
03508                                 pushPowerMod = pushPower;
03509 
03510                                 if (push_list[x]->client->pers.cmd.forwardmove ||
03511                                         push_list[x]->client->pers.cmd.rightmove)
03512                                 { //if you are moving, you get one less level of defense
03513                                         otherPushPower--;
03514 
03515                                         if (otherPushPower < 0)
03516                                         {
03517                                                 otherPushPower = 0;
03518                                         }
03519                                 }
03520 
03521                                 if (otherPushPower && CanCounterThrow(push_list[x], self, pull))
03522                                 {
03523                                         if ( pull )
03524                                         {
03525                                                 G_Sound( push_list[x], CHAN_BODY, G_SoundIndex( "sound/weapons/force/pull.wav" ) );
03526                                                 push_list[x]->client->ps.forceHandExtend = HANDEXTEND_FORCEPULL;
03527                                                 push_list[x]->client->ps.forceHandExtendTime = level.time + 400;
03528                                         }
03529                                         else
03530                                         {
03531                                                 G_Sound( push_list[x], CHAN_BODY, G_SoundIndex( "sound/weapons/force/push.wav" ) );
03532                                                 push_list[x]->client->ps.forceHandExtend = HANDEXTEND_FORCEPUSH;
03533                                                 push_list[x]->client->ps.forceHandExtendTime = level.time + 1000;
03534                                         }
03535                                         push_list[x]->client->ps.powerups[PW_DISINT_4] = push_list[x]->client->ps.forceHandExtendTime + 200;
03536 
03537                                         if (pull)
03538                                         {
03539                                                 push_list[x]->client->ps.powerups[PW_PULL] = push_list[x]->client->ps.powerups[PW_DISINT_4];
03540                                         }
03541                                         else
03542                                         {
03543                                                 push_list[x]->client->ps.powerups[PW_PULL] = 0;
03544                                         }
03545 
03546                                         //Make a counter-throw effect
03547 
03548                                         if (otherPushPower >= modPowerLevel)
03549                                         {
03550                                                 pushPowerMod = 0;
03551                                                 canPullWeapon = qfalse;
03552                                         }
03553                                         else
03554                                         {
03555                                                 int powerDif = (modPowerLevel - otherPushPower);
03556 
03557                                                 if (powerDif >= 3)
03558                                                 {
03559                                                         pushPowerMod -= pushPowerMod*0.2;
03560                                                 }
03561                                                 else if (powerDif == 2)
03562                                                 {
03563                                                         pushPowerMod -= pushPowerMod*0.4;
03564                                                 }
03565                                                 else if (powerDif == 1)
03566                                                 {
03567                                                         pushPowerMod -= pushPowerMod*0.8;
03568                                                 }
03569 
03570                                                 if (pushPowerMod < 0)
03571                                                 {
03572                                                         pushPowerMod = 0;
03573                                                 }
03574                                         }
03575                                 }
03576 
03577                                 //shove them
03578                                 if ( pull )
03579                                 {
03580                                         VectorSubtract( self->client->ps.origin, thispush_org, pushDir );
03581 
03582                                         if (push_list[x]->client && VectorLength(pushDir) <= 256)
03583                                         {
03584                                                 int randfact = 0;
03585 
03586                                                 if (modPowerLevel == FORCE_LEVEL_1)
03587                                                 {
03588                                                         randfact = 3;
03589                                                 }
03590                                                 else if (modPowerLevel == FORCE_LEVEL_2)
03591                                                 {
03592                                                         randfact = 7;
03593                                                 }
03594                                                 else if (modPowerLevel == FORCE_LEVEL_3)
03595                                                 {
03596                                                         randfact = 10;
03597                                                 }
03598 
03599                                                 if (!OnSameTeam(self, push_list[x]) && Q_irand(1, 10) <= randfact && canPullWeapon)
03600                                                 {
03601                                                         vec3_t uorg, vecnorm;
03602 
03603                                                         VectorCopy(self->client->ps.origin, uorg);
03604                                                         uorg[2] += 64;
03605 
03606                                                         VectorSubtract(uorg, thispush_org, vecnorm);
03607                                                         VectorNormalize(vecnorm);
03608 
03609                                                         TossClientWeapon(push_list[x], vecnorm, 500);
03610                                                 }
03611                                         }
03612                                 }
03613                                 else
03614                                 {
03615                                         VectorSubtract( thispush_org, self->client->ps.origin, pushDir );
03616                                 }
03617 
03618                                 if ((modPowerLevel > otherPushPower || push_list[x]->client->ps.m_iVehicleNum) && push_list[x]->client)
03619                                 {
03620                                         if (modPowerLevel == FORCE_LEVEL_3 &&
03621                                                 push_list[x]->client->ps.forceHandExtend != HANDEXTEND_KNOCKDOWN)
03622                                         {
03623                                                 dirLen = VectorLength(pushDir);
03624 
03625                                                 if (BG_KnockDownable(&push_list[x]->client->ps) &&
03626                                                         dirLen <= (64*((modPowerLevel - otherPushPower)-1)))
03627                                                 { //can only do a knockdown if fairly close
03628                                                         push_list[x]->client->ps.forceHandExtend = HANDEXTEND_KNOCKDOWN;
03629                                                         push_list[x]->client->ps.forceHandExtendTime = level.time + 700;
03630                                                         push_list[x]->client->ps.forceDodgeAnim = 0; //this toggles between 1 and 0, when it's 1 we should play the get up anim
03631                                                         push_list[x]->client->ps.quickerGetup = qtrue;
03632                                                 }
03633                                                 else if (push_list[x]->s.number < MAX_CLIENTS && push_list[x]->client->ps.m_iVehicleNum &&
03634                                                         dirLen <= 128.0f )
03635                                                 { //a player on a vehicle
03636                                                         gentity_t *vehEnt = &g_entities[push_list[x]->client->ps.m_iVehicleNum];
03637                                                         if (vehEnt->inuse && vehEnt->client && vehEnt->m_pVehicle)
03638                                                         {
03639                                                                 if (vehEnt->m_pVehicle->m_pVehicleInfo->type == VH_SPEEDER ||
03640                                                                         vehEnt->m_pVehicle->m_pVehicleInfo->type == VH_ANIMAL)
03641                                                                 { //push the guy off
03642                                                                         vehEnt->m_pVehicle->m_pVehicleInfo->Eject(vehEnt->m_pVehicle, (bgEntity_t *)push_list[x], qfalse);
03643                                                                 }
03644                                                         }
03645                                                 }
03646                                         }
03647                                 }
03648 
03649                                 if (!dirLen)
03650                                 {
03651                                         dirLen = VectorLength(pushDir);
03652                                 }
03653 
03654                                 VectorNormalize(pushDir);
03655 
03656                                 if (push_list[x]->client)
03657                                 {
03658                                         //escape a force grip if we're in one
03659                                         if (self->client->ps.fd.forceGripBeingGripped > level.time)
03660                                         { //force the enemy to stop gripping me if I managed to push him
03661                                                 if (push_list[x]->client->ps.fd.forceGripEntityNum == self->s.number)
03662                                                 {
03663                                                         if (modPowerLevel >= push_list[x]->client->ps.fd.forcePowerLevel[FP_GRIP])
03664                                                         { //only break the grip if our push/pull level is >= their grip level
03665                                                                 WP_ForcePowerStop(push_list[x], FP_GRIP);
03666                                                                 self->client->ps.fd.forceGripBeingGripped = 0;
03667                                                                 push_list[x]->client->ps.fd.forceGripUseTime = level.time + 1000; //since we just broke out of it..
03668                                                         }
03669                                                 }
03670                                         }
03671 
03672                                         push_list[x]->client->ps.otherKiller = self->s.number;
03673                                         push_list[x]->client->ps.otherKillerTime = level.time + 5000;
03674                                         push_list[x]->client->ps.otherKillerDebounceTime = level.time + 100;
03675 
03676                                         pushPowerMod -= (dirLen*0.7);
03677                                         if (pushPowerMod < 16)
03678                                         {
03679                                                 pushPowerMod = 16;
03680                                         }
03681 
03682                                         //fullbody push effect
03683                                         push_list[x]->client->pushEffectTime = level.time + 600;
03684 
03685                                         push_list[x]->client->ps.velocity[0] = pushDir[0]*pushPowerMod;
03686                                         push_list[x]->client->ps.velocity[1] = pushDir[1]*pushPowerMod;
03687 
03688                                         if ((int)push_list[x]->client->ps.velocity[2] == 0)
03689                                         { //if not going anywhere vertically, boost them up a bit
03690                                                 push_list[x]->client->ps.velocity[2] = pushDir[2]*pushPowerMod;
03691 
03692                                                 if (push_list[x]->client->ps.velocity[2] < 128)
03693                                                 {
03694                                                         push_list[x]->client->ps.velocity[2] = 128;
03695                                                 }
03696                                         }
03697                                         else
03698                                         {
03699                                                 push_list[x]->client->ps.velocity[2] = pushDir[2]*pushPowerMod;
03700                                         }
03701                                 }
03702                         }
03703                         else if ( push_list[x]->s.eType == ET_MISSILE && push_list[x]->s.pos.trType != TR_STATIONARY && (push_list[x]->s.pos.trType != TR_INTERPOLATE||push_list[x]->s.weapon != WP_THERMAL) )//rolling and stationary thermal detonators are dealt with below
03704                         {
03705                                 if ( pull )
03706                                 {//deflect rather than reflect?
03707                                 }
03708                                 else 
03709                                 {
03710                                         G_ReflectMissile( self, push_list[x], forward );
03711                                 }
03712                         }
03713                         else if ( !Q_stricmp( "func_static", push_list[x]->classname ) )
03714                         {//force-usable func_static
03715                                 if ( !pull && (push_list[x]->spawnflags&1/*F_PUSH*/) )
03716                                 {
03717                                         GEntity_UseFunc( push_list[x], self, self );
03718                                 }
03719                                 else if ( pull && (push_list[x]->spawnflags&2/*F_PULL*/) )
03720                                 {
03721                                         GEntity_UseFunc( push_list[x], self, self );
03722                                 }
03723                         }
03724                         else if ( !Q_stricmp( "func_door", push_list[x]->classname ) && (push_list[x]->spawnflags&2) )
03725                         {//push/pull the door
03726                                 vec3_t  pos1, pos2;
03727                                 vec3_t  trFrom;
03728 
03729                                 VectorCopy(self->client->ps.origin, trFrom);
03730                                 trFrom[2] += self->client->ps.viewheight;
03731 
03732                                 AngleVectors( self->client->ps.viewangles, forward, NULL, NULL );
03733                                 VectorNormalize( forward );
03734                                 VectorMA( trFrom, radius, forward, end );
03735                                 trap_Trace( &tr, trFrom, vec3_origin, vec3_origin, end, self->s.number, MASK_SHOT );
03736                                 if ( tr.entityNum != push_list[x]->s.number || tr.fraction == 1.0 || tr.allsolid || tr.startsolid )
03737                                 {//must be pointing right at it
03738                                         continue;
03739                                 }
03740 
03741                                 if ( VectorCompare( vec3_origin, push_list[x]->s.origin ) )
03742                                 {//does not have an origin brush, so pos1 & pos2 are relative to world origin, need to calc center
03743                                         VectorSubtract( push_list[x]->r.absmax, push_list[x]->r.absmin, size );
03744                                         VectorMA( push_list[x]->r.absmin, 0.5, size, center );
03745                                         if ( (push_list[x]->spawnflags&1) && push_list[x]->moverState == MOVER_POS1 )
03746                                         {//if at pos1 and started open, make sure we get the center where it *started* because we're going to add back in the relative values pos1 and pos2
03747                                                 VectorSubtract( center, push_list[x]->pos1, center );
03748                                         }
03749                                         else if ( !(push_list[x]->spawnflags&1) && push_list[x]->moverState == MOVER_POS2 )
03750                                         {//if at pos2, make sure we get the center where it *started* because we're going to add back in the relative values pos1 and pos2
03751                                                 VectorSubtract( center, push_list[x]->pos2, center );
03752                                         }
03753                                         VectorAdd( center, push_list[x]->pos1, pos1 );
03754                                         VectorAdd( center, push_list[x]->pos2, pos2 );
03755                                 }
03756                                 else
03757                                 {//actually has an origin, pos1 and pos2 are absolute
03758                                         VectorCopy( push_list[x]->r.currentOrigin, center );
03759                                         VectorCopy( push_list[x]->pos1, pos1 );
03760                                         VectorCopy( push_list[x]->pos2, pos2 );
03761                                 }
03762 
03763                                 if ( Distance( pos1, trFrom ) < Distance( pos2, trFrom ) )
03764                                 {//pos1 is closer
03765                                         if ( push_list[x]->moverState == MOVER_POS1 )
03766                                         {//at the closest pos
03767                                                 if ( pull )
03768                                                 {//trying to pull, but already at closest point, so screw it
03769                                                         continue;
03770                                                 }
03771                                         }
03772                                         else if ( push_list[x]->moverState == MOVER_POS2 )
03773                                         {//at farthest pos
03774                                                 if ( !pull )
03775                                                 {//trying to push, but already at farthest point, so screw it
03776                                                         continue;
03777                                                 }
03778                                         }
03779                                 }
03780                                 else
03781                                 {//pos2 is closer
03782                                         if ( push_list[x]->moverState == MOVER_POS1 )
03783                                         {//at the farthest pos
03784                                                 if ( !pull )
03785                                                 {//trying to push, but already at farthest point, so screw it
03786                                                         continue;
03787                                                 }
03788                                         }
03789                                         else if ( push_list[x]->moverState == MOVER_POS2 )
03790                                         {//at closest pos
03791                                                 if ( pull )
03792                                                 {//trying to pull, but already at closest point, so screw it
03793                                                         continue;
03794                                                 }
03795                                         }
03796                                 }
03797                                 GEntity_UseFunc( push_list[x], self, self );
03798                         }
03799                         else if ( Q_stricmp( "func_button", push_list[x]->classname ) == 0 )
03800                         {//pretend you pushed it
03801                                 Touch_Button( push_list[x], self, NULL );
03802                                 continue;
03803                         }
03804                 }
03805         }
03806 
03807         //attempt to break any leftover grips
03808         //if we're still in a current grip that wasn't broken by the push, it will still remain
03809         self->client->dangerTime = level.time;
03810         self->client->ps.eFlags &= ~EF_INVULNERABLE;
03811         self->client->invulnerableTimer = 0;
03812 
03813         if (self->client->ps.fd.forceGripBeingGripped > level.time)
03814         {
03815                 self->client->ps.fd.forceGripBeingGripped = 0;
03816         }
03817 }

qboolean G_InGetUpAnim playerState_t ps  ) 
 

Definition at line 2970 of file w_force.c.

References BOTH_FORCE_GETUP_B1, BOTH_FORCE_GETUP_B2, BOTH_FORCE_GETUP_B3, BOTH_FORCE_GETUP_B4, BOTH_FORCE_GETUP_B5, 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_FROLL_B, BOTH_GETUP_FROLL_F, BOTH_GETUP_FROLL_L, BOTH_GETUP_FROLL_R, playerState_s::legsAnim, playerState_t, qboolean, qfalse, qtrue, and playerState_s::torsoAnim.

Referenced by ForceThrow().

02971 {
02972         switch( (ps->legsAnim) )
02973         {
02974         case BOTH_GETUP1:
02975         case BOTH_GETUP2:
02976         case BOTH_GETUP3:
02977         case BOTH_GETUP4:
02978         case BOTH_GETUP5:
02979         case BOTH_FORCE_GETUP_F1:
02980         case BOTH_FORCE_GETUP_F2:
02981         case BOTH_FORCE_GETUP_B1:
02982         case BOTH_FORCE_GETUP_B2:
02983         case BOTH_FORCE_GETUP_B3:
02984         case BOTH_FORCE_GETUP_B4:
02985         case BOTH_FORCE_GETUP_B5:
02986         case BOTH_GETUP_BROLL_B:
02987         case BOTH_GETUP_BROLL_F:
02988         case BOTH_GETUP_BROLL_L:
02989         case BOTH_GETUP_BROLL_R:
02990         case BOTH_GETUP_FROLL_B:
02991         case BOTH_GETUP_FROLL_F:
02992         case BOTH_GETUP_FROLL_L:
02993         case BOTH_GETUP_FROLL_R:
02994                 return qtrue;
02995         }
02996 
02997         switch( (ps->torsoAnim) )
02998         {
02999         case BOTH_GETUP1:
03000         case BOTH_GETUP2:
03001         case BOTH_GETUP3:
03002         case BOTH_GETUP4:
03003         case BOTH_GETUP5:
03004         case BOTH_FORCE_GETUP_F1:
03005         case BOTH_FORCE_GETUP_F2:
03006         case BOTH_FORCE_GETUP_B1:
03007         case BOTH_FORCE_GETUP_B2:
03008         case BOTH_FORCE_GETUP_B3:
03009         case BOTH_FORCE_GETUP_B4:
03010         case BOTH_FORCE_GETUP_B5:
03011         case BOTH_GETUP_BROLL_B:
03012         case BOTH_GETUP_BROLL_F:
03013         case BOTH_GETUP_BROLL_L:
03014         case BOTH_GETUP_BROLL_R:
03015         case BOTH_GETUP_FROLL_B:
03016         case BOTH_GETUP_FROLL_F:
03017         case BOTH_GETUP_FROLL_L:
03018         case BOTH_GETUP_FROLL_R:
03019                 return qtrue;
03020         }
03021 
03022         return qfalse;
03023 }

qboolean G_IsMindTricked forcedata_t fd,
int  client
 

Definition at line 4155 of file w_force.c.

References client, forcedata_t, forcedata_s::forceMindtrickTargetIndex, forcedata_s::forceMindtrickTargetIndex2, forcedata_s::forceMindtrickTargetIndex3, forcedata_s::forceMindtrickTargetIndex4, qboolean, qfalse, and qtrue.

04156 {
04157         int checkIn;
04158         int trickIndex1, trickIndex2, trickIndex3, trickIndex4;
04159         int sub = 0;
04160 
04161         if (!fd)
04162         {
04163                 return qfalse;
04164         }
04165 
04166         trickIndex1 = fd->forceMindtrickTargetIndex;
04167         trickIndex2 = fd->forceMindtrickTargetIndex2;
04168         trickIndex3 = fd->forceMindtrickTargetIndex3;
04169         trickIndex4 = fd->forceMindtrickTargetIndex4;
04170 
04171         if (client > 47)
04172         {
04173                 checkIn = trickIndex4;
04174                 sub = 48;
04175         }
04176         else if (client > 31)
04177         {
04178                 checkIn = trickIndex3;
04179                 sub = 32;
04180         }
04181         else if (client > 15)
04182         {
04183                 checkIn = trickIndex2;
04184                 sub = 16;
04185         }
04186         else
04187         {
04188                 checkIn = trickIndex1;
04189         }
04190 
04191         if (checkIn & (1 << (client-sub)))
04192         {
04193                 return qtrue;
04194         }
04195         
04196         return qfalse;
04197 }

void G_LetGoOfWall gentity_t ent  ) 
 

Definition at line 3025 of file w_force.c.

References BG_InReboundHold(), BG_InReboundJump(), gentity_s::client, gentity_t, playerState_s::legsAnim, playerState_s::legsTimer, playerState_s::pm_flags, PMF_STUCK_TO_WALL, gclient_s::ps, playerState_s::torsoAnim, and playerState_s::torsoTimer.

Referenced by ForceThrow(), and G_Damage().

03026 {
03027         if ( !ent || !ent->client )
03028         {
03029                 return;
03030         }
03031         ent->client->ps.pm_flags &= ~PMF_STUCK_TO_WALL;
03032         if ( BG_InReboundJump( ent->client->ps.legsAnim ) 
03033                 || BG_InReboundHold( ent->client->ps.legsAnim ) )
03034         {
03035                 ent->client->ps.legsTimer = 0;
03036         }
03037         if ( BG_InReboundJump( ent->client->ps.torsoAnim ) 
03038                 || BG_InReboundHold( ent->client->ps.torsoAnim ) )
03039         {
03040                 ent->client->ps.torsoTimer = 0;
03041         }
03042 }

gentity_t* G_PreDefSound vec3_t  org,
int  pdSound
 

Definition at line 40 of file w_force.c.

References EV_PREDEFSOUND, entityState_s::eventParm, G_TempEntity(), gentity_t, entityState_s::origin, gentity_s::s, vec3_t, and VectorCopy.

Referenced by ClientThink_real(), ForceAbsorb(), ForcePowerUsableOn(), ForceProtect(), G_Damage(), G_SpecialRollGetup(), WP_AbsorbConversion(), WP_ForcePowersUpdate(), and WP_GetVelocityForForceJump().

00041 {
00042         gentity_t       *te;
00043 
00044         te = G_TempEntity( org, EV_PREDEFSOUND );
00045         te->s.eventParm = pdSound;
00046         VectorCopy(org, te->s.origin);
00047 
00048         return te;
00049 }

qboolean G_SpecialRollGetup gentity_t self  ) 
 

Definition at line 5028 of file w_force.c.

References BOTH_GETUP_BROLL_B, BOTH_GETUP_BROLL_F, BOTH_GETUP_BROLL_L, BOTH_GETUP_BROLL_R, CHAN_VOICE, gentity_s::client, clientPersistant_t::cmd, playerState_s::forceDodgeAnim, playerState_s::forceHandExtendTime, usercmd_s::forwardmove, G_EntitySound(), G_PreDefSound(), G_SetAnim(), G_SoundIndex(), gentity_t, level, playerState_s::origin, PDSOUND_FORCEJUMP, gclient_s::pers, gclient_s::ps, qboolean, qfalse, qtrue, usercmd_s::rightmove, SETANIM_BOTH, SETANIM_FLAG_HOLD, SETANIM_FLAG_OVERRIDE, level_locals_t::time, and usercmd_s::upmove.

Referenced by WP_ForcePowersUpdate().

05029 { //fixme: currently no knockdown will actually land you on your front... so froll's are pretty useless at the moment.
05030         qboolean rolled = qfalse;
05031 
05032         /*
05033         if (self->client->ps.weapon != WP_SABER &&
05034                 self->client->ps.weapon != WP_MELEE)
05035         { //can't do acrobatics without saber selected
05036                 return qfalse;
05037         }
05038         */
05039 
05040         if (
05041                 self->client->pers.cmd.rightmove > 0 &&
05042                 !self->client->pers.cmd.forwardmove)
05043         {
05044                 G_SetAnim(self, &self->client->pers.cmd, SETANIM_BOTH, BOTH_GETUP_BROLL_R, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD, 0);
05045                 rolled = qtrue;
05046         }
05047         else if (
05048                 self->client->pers.cmd.rightmove < 0 &&
05049                 !self->client->pers.cmd.forwardmove)
05050         {
05051                 G_SetAnim(self, &self->client->pers.cmd, SETANIM_BOTH, BOTH_GETUP_BROLL_L, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD, 0);
05052                 rolled = qtrue;
05053         }
05054         else if (/*self->client->pers.cmd.upmove > 0 &&*/
05055                 !self->client->pers.cmd.rightmove &&
05056                 self->client->pers.cmd.forwardmove > 0)
05057         {
05058                 G_SetAnim(self, &self->client->pers.cmd, SETANIM_BOTH, BOTH_GETUP_BROLL_F, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD, 0);
05059                 rolled = qtrue;
05060         }
05061         else if (/*self->client->pers.cmd.upmove > 0 &&*/
05062                 !self->client->pers.cmd.rightmove &&
05063                 self->client->pers.cmd.forwardmove < 0)
05064         {
05065                 G_SetAnim(self, &self->client->pers.cmd, SETANIM_BOTH, BOTH_GETUP_BROLL_B, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD, 0);
05066                 rolled = qtrue;
05067         }
05068         else if (self->client->pers.cmd.upmove)
05069         {
05070                 G_PreDefSound(self->client->ps.origin, PDSOUND_FORCEJUMP);
05071                 self->client->ps.forceDodgeAnim = 2;
05072                 self->client->ps.forceHandExtendTime = level.time + 500;
05073 
05074                 //self->client->ps.velocity[2] = 300;
05075         }
05076 
05077         if (rolled)
05078         {
05079                 G_EntitySound( self, CHAN_VOICE, G_SoundIndex("*jump1.wav") );
05080         }
05081 
05082         return rolled;
05083 }

void GEntity_UseFunc gentity_t self,
gentity_t other,
gentity_t activator
 

Definition at line 2895 of file w_force.c.

References gentity_t, and GlobalUse().

Referenced by ForceThrow().

02896 {
02897         GlobalUse(self, other, activator);
02898 }

void HolocronUpdate gentity_t self  ) 
 

Definition at line 4861 of file w_force.c.

References gentity_s::client, playerState_s::fd, FORCE_LEVEL_0, FORCE_LEVEL_1, FORCE_LEVEL_3, forcedata_s::forcePowerLevel, forcedata_s::forcePowersActive, forcedata_s::forcePowersKnown, FP_LEVITATION, FP_SABER_DEFENSE, FP_SABER_OFFENSE, g_MaxHolocronCarry, gentity_t, HasSetSaberOnly(), playerState_s::holocronBits, playerState_s::holocronsCarried, NUM_FORCE_POWERS, gclient_s::ps, trap_Cvar_Update(), and WP_ForcePowerStop().

Referenced by WP_ForcePowersUpdate().

04862 { //keep holocron status updated in holocron mode
04863         int i = 0;
04864         int noHRank = 0;
04865 
04866         if (noHRank < FORCE_LEVEL_0)
04867         {
04868                 noHRank = FORCE_LEVEL_0;
04869         }
04870         if (noHRank > FORCE_LEVEL_3)
04871         {
04872                 noHRank = FORCE_LEVEL_3;
04873         }
04874 
04875         trap_Cvar_Update(&g_MaxHolocronCarry);
04876 
04877         while (i < NUM_FORCE_POWERS)
04878         {
04879                 if (self->client->ps.holocronsCarried[i])
04880                 { //carrying it, make sure we have the power
04881                         self->client->ps.holocronBits |= (1 << i);
04882                         self->client->ps.fd.forcePowersKnown |= (1 << i);
04883                         self->client->ps.fd.forcePowerLevel[i] = FORCE_LEVEL_3;
04884                 }
04885                 else
04886                 { //otherwise, make sure the power is cleared from us
04887                         self->client->ps.fd.forcePowerLevel[i] = 0;
04888                         if (self->client->ps.holocronBits & (1 << i))
04889                         {
04890                                 self->client->ps.holocronBits -= (1 << i);
04891                         }
04892 
04893                         if ((self->client->ps.fd.forcePowersKnown & (1 << i)) && i != FP_LEVITATION && i != FP_SABER_OFFENSE)
04894                         {
04895                                 self->client->ps.fd.forcePowersKnown -= (1 << i);
04896                         }
04897 
04898                         if ((self->client->ps.fd.forcePowersActive & (1 << i)) && i != FP_LEVITATION && i != FP_SABER_OFFENSE)
04899                         {
04900                                 WP_ForcePowerStop(self, i);
04901                         }
04902 
04903                         if (i == FP_LEVITATION)
04904                         {
04905                                 if (noHRank >= FORCE_LEVEL_1)
04906                                 {
04907                                         self->client->ps.fd.forcePowerLevel[i] = noHRank;
04908                                 }
04909                                 else
04910                                 {
04911                                         self->client->ps.fd.forcePowerLevel[i] = FORCE_LEVEL_1;
04912                                 }
04913                         }
04914                         else if (i == FP_SABER_OFFENSE)
04915                         {
04916                                 self->client->ps.fd.forcePowersKnown |= (1 << i);
04917 
04918                                 if (noHRank >= FORCE_LEVEL_1)
04919                                 {
04920                                         self->client->ps.fd.forcePowerLevel[i] = noHRank;
04921                                 }
04922                                 else
04923                                 {
04924                                         self->client->ps.fd.forcePowerLevel[i] = FORCE_LEVEL_1;
04925                                 }
04926                         }
04927                         else
04928                         {
04929                                 self->client->ps.fd.forcePowerLevel[i] = FORCE_LEVEL_0;
04930                         }
04931                 }
04932 
04933                 i++;
04934         }
04935 
04936         if (HasSetSaberOnly())
04937         { //if saberonly, we get these powers no matter what (still need the holocrons for level 3)
04938                 if (self->client->ps.fd.forcePowerLevel[FP_SABER_OFFENSE] < FORCE_LEVEL_1)
04939                 {
04940                         self->client->ps.fd.forcePowerLevel[FP_SABER_OFFENSE] = FORCE_LEVEL_1;
04941                 }
04942                 if (self->client->ps.fd.forcePowerLevel[FP_SABER_DEFENSE] < FORCE_LEVEL_1)
04943                 {
04944                         self->client->ps.fd.forcePowerLevel[FP_SABER_DEFENSE] = FORCE_LEVEL_1;
04945                 }
04946         }
04947 }

void Jedi_Decloak gentity_t self  ) 
 

Definition at line 818 of file NPC_AI_Jedi.c.

References CHAN_ITEM, gentity_s::client, FL_NOTARGET, gentity_s::flags, G_Sound(), G_SoundIndex(), gentity_t, playerState_s::powerups, gclient_s::ps, and PW_CLOAKED.

Referenced by ClientThink_real(), DEMP2_AltRadiusDamage(), ForceLightningDamage(), G_MissileImpact(), G_RunFrame(), ItemUse_UseCloak(), Jedi_Ambush(), and Jedi_CheckCloak().

00819 {
00820         if ( self )
00821         {
00822                 self->flags &= ~FL_NOTARGET;
00823                 if ( self->client )
00824                 {
00825                         if ( self->client->ps.powerups[PW_CLOAKED] )
00826                         {//Uncloak
00827                                 self->client->ps.powerups[PW_CLOAKED] = 0;
00828 
00829                                 G_Sound( self, CHAN_ITEM, G_SoundIndex("sound/chars/shadowtrooper/decloak.wav") );
00830                         }
00831                 }
00832         }
00833 }

qboolean Jedi_DodgeEvasion gentity_t self,
gentity_t shooter,
trace_t tr,
int  hitLoc
 

Definition at line 5664 of file w_force.c.

References BOTH_DODGE_FL, BOTH_DODGE_FR, BOTH_DODGE_L, BOTH_DODGE_R, CHAN_BODY, gentity_s::client, ENTITYNUM_NONE, playerState_s::fd, FORCE_LEVEL_3, playerState_s::forceDodgeAnim, playerState_s::forceHandExtend, playerState_s::forceHandExtendTime, forcedata_s::forcePowerLevel, forcedata_s::forcePowersActive, ForceSpeed(), FP_SEE, FP_SPEED, g_forceDodge, G_Sound(), G_SoundIndex(), gentity_t, playerState_s::groundEntityNum, HANDEXTEND_DODGE, HANDEXTEND_NONE, gentity_s::health, HL_ARM_LT, HL_ARM_RT, HL_BACK, HL_BACK_LT, HL_BACK_RT, HL_CHEST, HL_CHEST_LT, HL_CHEST_RT, HL_FOOT_LT, HL_FOOT_RT, HL_HAND_LT, HL_HAND_RT, HL_HEAD, HL_LEG_LT, HL_LEG_RT, HL_NONE, HL_WAIST, vmCvar_t::integer, level, playerState_s::powerups, gclient_s::ps, PW_SPEEDBURST, Q_irand(), qboolean, qfalse, qtrue, level_locals_t::time, playerState_s::weaponTime, and WP_ForcePowerUsable().

Referenced by WP_DisruptorAltFire().

05665 {
05666         int     dodgeAnim = -1;
05667 
05668         if ( !self || !self->client || self->health <= 0 )
05669         {
05670                 return qfalse;
05671         }
05672 
05673         if (!g_forceDodge.integer)
05674         {
05675                 return qfalse;
05676         }
05677 
05678         if (g_forceDodge.integer != 2)
05679         {
05680                 if (!(self->client->ps.fd.forcePowersActive & (1 << FP_SEE)))
05681                 {
05682                         return qfalse;
05683                 }
05684         }
05685 
05686         if ( self->client->ps.groundEntityNum == ENTITYNUM_NONE )
05687         {//can't dodge in mid-air
05688                 return qfalse;
05689         }
05690 
05691         if ( self->client->ps.weaponTime > 0 || self->client->ps.forceHandExtend != HANDEXTEND_NONE )
05692         {//in some effect that stops me from moving on my own
05693                 return qfalse;
05694         }
05695 
05696         if (g_forceDodge.integer == 2)
05697         {
05698                 if (self->client->ps.fd.forcePowersActive)
05699                 { //for now just don't let us dodge if we're using a force power at all
05700                         return qfalse;
05701                 }
05702         }
05703 
05704         if (g_forceDodge.integer == 2)
05705         {
05706                 if ( !WP_ForcePowerUsable( self, FP_SPEED ) )
05707                 {//make sure we have it and have enough force power
05708                         return qfalse;
05709                 }
05710         }
05711 
05712         if (g_forceDodge.integer == 2)
05713         {
05714                 if ( Q_irand( 1, 7 ) > self->client->ps.fd.forcePowerLevel[FP_SPEED] )
05715                 {//more likely to fail on lower force speed level
05716                         return qfalse;
05717                 }
05718         }
05719         else
05720         {
05721                 //We now dodge all the time, but only on level 3
05722                 if (self->client->ps.fd.forcePowerLevel[FP_SEE] < FORCE_LEVEL_3)
05723                 {//more likely to fail on lower force sight level
05724                         return qfalse;
05725                 }
05726         }
05727 
05728         switch( hitLoc )
05729         {
05730         case HL_NONE:
05731                 return qfalse;
05732                 break;
05733 
05734         case HL_FOOT_RT:
05735         case HL_FOOT_LT:
05736         case HL_LEG_RT:
05737         case HL_LEG_LT:
05738                 return qfalse;
05739 
05740         case HL_BACK_RT:
05741                 dodgeAnim = BOTH_DODGE_FL;
05742                 break;
05743         case HL_CHEST_RT:
05744                 dodgeAnim = BOTH_DODGE_FR;
05745                 break;
05746         case HL_BACK_LT:
05747                 dodgeAnim = BOTH_DODGE_FR;
05748                 break;
05749         case HL_CHEST_LT:
05750                 dodgeAnim = BOTH_DODGE_FR;
05751                 break;
05752         case HL_BACK:
05753         case HL_CHEST:
05754         case HL_WAIST:
05755                 dodgeAnim = BOTH_DODGE_FL;
05756                 break;
05757         case HL_ARM_RT:
05758         case HL_HAND_RT:
05759                 dodgeAnim = BOTH_DODGE_L;
05760                 break;
05761         case HL_ARM_LT:
05762         case HL_HAND_LT:
05763                 dodgeAnim = BOTH_DODGE_R;
05764                 break;
05765         case HL_HEAD:
05766                 dodgeAnim = BOTH_DODGE_FL;
05767                 break;
05768         default:
05769                 return qfalse;
05770         }
05771 
05772         if ( dodgeAnim != -1 )
05773         {
05774                 //Our own happy way of forcing an anim:
05775                 self->client->ps.forceHandExtend = HANDEXTEND_DODGE;
05776                 self->client->ps.forceDodgeAnim = dodgeAnim;
05777                 self->client->ps.forceHandExtendTime = level.time + 300;
05778 
05779                 self->client->ps.powerups[PW_SPEEDBURST] = level.time + 100;
05780 
05781                 if (g_forceDodge.integer == 2)
05782                 {
05783                         ForceSpeed( self, 500 );
05784                 }
05785                 else
05786                 {
05787                         G_Sound( self, CHAN_BODY, G_SoundIndex("sound/weapons/force/speed.wav") );
05788                 }
05789                 return qtrue;
05790         }
05791         return qfalse;
05792 }

void JediMasterUpdate gentity_t self  ) 
 

Definition at line 4949 of file w_force.c.

References gentity_s::client, playerState_s::fd, FORCE_LEVEL_0, FORCE_LEVEL_1, FORCE_LEVEL_2, FORCE_LEVEL_3, forcedata_s::forcePowerLevel, forcedata_s::forcePowersActive, forcedata_s::forcePowersKnown, FP_ABSORB, FP_DRAIN, FP_LEVITATION, FP_TEAM_FORCE, FP_TEAM_HEAL, FP_TELEPATHY, g_MaxHolocronCarry, gentity_t, playerState_s::isJediMaster, NUM_FORCE_POWERS, gclient_s::ps, trap_Cvar_Update(), and WP_ForcePowerStop().

Referenced by WP_ForcePowersUpdate().

04950 { //keep jedi master status updated for JM gametype
04951         int i = 0;
04952 
04953         trap_Cvar_Update(&g_MaxHolocronCarry);
04954 
04955         while (i < NUM_FORCE_POWERS)
04956         {
04957                 if (self->client->ps.isJediMaster)
04958                 {
04959                         self->client->ps.fd.forcePowersKnown |= (1 << i);
04960                         self->client->ps.fd.forcePowerLevel[i] = FORCE_LEVEL_3;
04961 
04962                         if (i == FP_TEAM_HEAL || i == FP_TEAM_FORCE ||
04963                                 i == FP_DRAIN || i == FP_ABSORB)
04964                         { //team powers are useless in JM, absorb is too because no one else has powers to absorb. Drain is just
04965                           //relatively useless in comparison, because its main intent is not to heal, but rather to cripple others
04966                           //by draining their force at the same time. And no one needs force in JM except the JM himself.
04967                                 self->client->ps.fd.forcePowersKnown &= ~(1 << i);
04968                                 self->client->ps.fd.forcePowerLevel[i] = 0;
04969                         }
04970 
04971                         if (i == FP_TELEPATHY)
04972                         { //this decision was made because level 3 mindtrick allows the JM to just hide too much, and no one else has force
04973                           //sight to counteract it. Since the JM himself is the focus of gameplay in this mode, having him hidden for large
04974                           //durations is indeed a bad thing.
04975                                 self->client->ps.fd.forcePowerLevel[i] = FORCE_LEVEL_2;
04976                         }
04977                 }
04978                 else
04979                 {
04980                         if ((self->client->ps.fd.forcePowersKnown & (1 << i)) && i != FP_LEVITATION)
04981                         {
04982                                 self->client->ps.fd.forcePowersKnown -= (1 << i);
04983                         }
04984 
04985                         if ((self->client->ps.fd.forcePowersActive & (1 << i)) && i != FP_LEVITATION)
04986                         {
04987                                 WP_ForcePowerStop(self, i);
04988                         }
04989 
04990                         if (i == FP_LEVITATION)
04991                         {
04992                                 self->client->ps.fd.forcePowerLevel[i] = FORCE_LEVEL_1;
04993                         }
04994                         else
04995                         {
04996                                 self->client->ps.fd.forcePowerLevel[i] = FORCE_LEVEL_0;
04997                         }
04998                 }
04999 
05000                 i++;
05001         }
05002 }

void NPC_Jedi_PlayConfusionSound gentity_t self  ) 
 

Definition at line 163 of file NPC_AI_Jedi.c.

References CLASS_DESANN, CLASS_TAVION, gentity_s::client, EV_CONFUSE1, EV_CONFUSE3, EV_GLOAT1, EV_GLOAT3, EV_TAUNT1, EV_TAUNT3, G_AddVoiceEvent(), gentity_t, gentity_s::health, gclient_s::NPC_class, and Q_irand().

Referenced by ForceTelepathyCheckDirectNPCTarget().

00164 {
00165         if ( self->health > 0 )
00166         {
00167                 if ( self->client && ( self->client->NPC_class == CLASS_TAVION || self->client->NPC_class == CLASS_DESANN ) )
00168                 {
00169                         G_AddVoiceEvent( self, Q_irand( EV_CONFUSE1, EV_CONFUSE3 ), 2000 );
00170                 }
00171                 else if ( Q_irand( 0, 1 ) )
00172                 {
00173                         G_AddVoiceEvent( self, Q_irand( EV_TAUNT1, EV_TAUNT3 ), 2000 );
00174                 }
00175                 else
00176                 {
00177                         G_AddVoiceEvent( self, Q_irand( EV_GLOAT1, EV_GLOAT3 ), 2000 );
00178                 }
00179         }
00180 }

void NPC_PlayConfusionSound gentity_t self  ) 
 

Definition at line 66 of file NPC_sounds.c.

References gNPC_t::blockedSpeechDebounceTime, BS_DEFAULT, gentity_s::client, gentity_s::enemy, EV_CONFUSE1, EV_CONFUSE2, EV_CONFUSE3, G_AddVoiceEvent(), G_ClearEnemy(), gentity_t, gentity_s::health, gNPC_t::investigateCount, gNPC_t::investigateDebounceTime, level, renderInfo_s::lookTarget, gentity_s::NPC, gNPC_t::pauseTime, Q_irand(), gclient_s::renderInfo, gNPC_t::tempBehavior, level_locals_t::time, TIMER_Done(), and TIMER_Set().

Referenced by ForceTelepathyCheckDirectNPCTarget().

00067 {
00068         if ( self->health > 0 )
00069         {
00070                 if ( self->enemy ||//was mad
00071                                 !TIMER_Done( self, "enemyLastVisible" ) ||//saw something suspicious
00072                                 self->client->renderInfo.lookTarget     == 0//was looking at player
00073                         )
00074                 {
00075                         self->NPC->blockedSpeechDebounceTime = 0;//make sure we say this
00076                         G_AddVoiceEvent( self, Q_irand( EV_CONFUSE2, EV_CONFUSE3 ), 2000 );
00077                 }
00078                 else if ( self->NPC && self->NPC->investigateDebounceTime+self->NPC->pauseTime > level.time )//was checking something out
00079                 {
00080                         self->NPC->blockedSpeechDebounceTime = 0;//make sure we say this
00081                         G_AddVoiceEvent( self, EV_CONFUSE1, 2000 );
00082                 }
00083                 //G_AddVoiceEvent( self, Q_irand(EV_CONFUSE1, EV_CONFUSE3), 2000 );
00084         }
00085         //reset him to be totally unaware again
00086         TIMER_Set( self, "enemyLastVisible", 0 );
00087         self->NPC->tempBehavior = BS_DEFAULT;
00088         
00089         //self->NPC->behaviorState = BS_PATROL;
00090         G_ClearEnemy( self );//FIXME: or just self->enemy = NULL;?
00091 
00092         self->NPC->investigateCount = 0;
00093 }

void NPC_UseResponse gentity_t self,
gentity_t user,
qboolean  useWhenDone
 

Definition at line 950 of file NPC_reactions.c.

References gNPC_t::blockedSpeechDebounceTime, BSET_USE, gentity_s::client, G_ActivateBehavior(), gentity_t, level, gentity_s::NPC, NPC_Respond(), NPCTEAM_NEUTRAL, entityState_s::number, gclient_s::playerTeam, gentity_s::s, and level_locals_t::time.

Referenced by ForceTelepathyCheckDirectNPCTarget(), and NPC_Use().

00951 {
00952         if ( !self->NPC || !self->client )
00953         {
00954                 return;
00955         }
00956 
00957         if ( user->s.number != 0 )
00958         {//not used by the player
00959                 if ( useWhenDone )
00960                 {
00961                         G_ActivateBehavior( self, BSET_USE );
00962                 }
00963                 return;
00964         }
00965 
00966         if ( user->client && self->client->playerTeam != user->client->playerTeam && self->client->playerTeam != NPCTEAM_NEUTRAL )
00967         {//only those on the same team react
00968                 if ( useWhenDone )
00969                 {
00970                         G_ActivateBehavior( self, BSET_USE );
00971                 }
00972                 return;
00973         }
00974 
00975         if ( self->NPC->blockedSpeechDebounceTime > level.time )
00976         {//I'm not responding right now
00977                 return;
00978         }
00979 
00980         /*
00981         if ( gi.VoiceVolume[self->s.number] )
00982         {//I'm talking already
00983                 if ( !useWhenDone )
00984                 {//you're not trying to use me
00985                         return;
00986                 }
00987         }
00988         */
00989         //rwwFIXMEFIXME: Support for this?
00990 
00991         if ( useWhenDone )
00992         {
00993                 G_ActivateBehavior( self, BSET_USE );
00994         }
00995         else
00996         {
00997                 NPC_Respond( self, user->s.number );
00998         }
00999 }

void SeekerDroneUpdate gentity_t self  ) 
 

Definition at line 4702 of file w_force.c.

References trace_t::allsolid, CHAN_BODY, CHAN_WEAPON, gentity_s::client, cos(), playerState_s::droneExistTime, playerState_s::droneFireTime, EF_SEEKERDRONE, EFFECT_SPARK_EXPLOSION, playerState_s::eFlags, ENTITYNUM_NONE, FindGenericEnemyIndex(), trace_t::fraction, g_entities, G_PlayEffect(), G_Sound(), G_SoundAtLoc(), G_SoundIndex(), playerState_s::genericEnemyIndex, gentity_t, gentity_s::health, InFront(), level, M_PI, MASK_SOLID, MOD_BLASTER, NULL, entityState_s::number, OnSameTeam(), OrgVisible(), playerState_s::origin, PITCH, gclient_s::ps, Q_irand(), ROLL, gentity_s::s, sin(), trace_t::startsolid, level_locals_t::time, trap_Trace(), vec3_t, VectorAdd, VectorCopy, VectorNormalize(), VectorSubtract, playerState_s::viewangles, WP_FireGenericBlasterMissile(), and YAW.

Referenced by WP_ForcePowersUpdate().

04703 {
04704         vec3_t org, elevated, dir, a, endir;
04705         gentity_t *en;
04706         float angle;
04707         float prefig = 0;
04708         trace_t tr;
04709 
04710         if (!(self->client->ps.eFlags & EF_SEEKERDRONE))
04711         {
04712                 self->client->ps.genericEnemyIndex = -1;
04713                 return;
04714         }
04715 
04716         if (self->health < 1)
04717         {
04718                 VectorCopy(self->client->ps.origin, elevated);
04719                 elevated[2] += 40;
04720 
04721                 angle = ((level.time / 12) & 255) * (M_PI * 2) / 255; //magical numbers make magic happen
04722                 dir[0] = cos(angle) * 20;
04723                 dir[1] = sin(angle) * 20;
04724                 dir[2] = cos(angle) * 5;
04725                 VectorAdd(elevated, dir, org);
04726 
04727                 a[ROLL] = 0;
04728                 a[YAW] = 0;
04729                 a[PITCH] = 1;
04730 
04731                 G_PlayEffect(EFFECT_SPARK_EXPLOSION, org, a);
04732 
04733                 self->client->ps.eFlags -= EF_SEEKERDRONE;
04734                 self->client->ps.genericEnemyIndex = -1;
04735 
04736                 return;
04737         }
04738 
04739         if (self->client->ps.droneExistTime >= level.time && 
04740                 self->client->ps.droneExistTime < (level.time+5000))
04741         {
04742                 self->client->ps.genericEnemyIndex = 1024+self->client->ps.droneExistTime;
04743                 if (self->client->ps.droneFireTime < level.time)
04744                 {
04745                         G_Sound( self, CHAN_BODY, G_SoundIndex("sound/weapons/laser_trap/warning.wav") );
04746                         self->client->ps.droneFireTime = level.time + 100;
04747                 }
04748                 return;
04749         }
04750         else if (self->client->ps.droneExistTime < level.time)
04751         {
04752                 VectorCopy(self->client->ps.origin, elevated);
04753                 elevated[2] += 40;
04754 
04755                 prefig = (self->client->ps.droneExistTime-level.time)/80;
04756 
04757                 if (prefig > 55)
04758                 {
04759                         prefig = 55;
04760                 }
04761                 else if (prefig < 1)
04762                 {
04763                         prefig = 1;
04764                 }
04765 
04766                 elevated[2] -= 55-prefig;
04767 
04768                 angle = ((level.time / 12) & 255) * (M_PI * 2) / 255; //magical numbers make magic happen
04769                 dir[0] = cos(angle) * 20;
04770                 dir[1] = sin(angle) * 20;
04771                 dir[2] = cos(angle) * 5;
04772                 VectorAdd(elevated, dir, org);
04773 
04774                 a[ROLL] = 0;
04775                 a[YAW] = 0;
04776                 a[PITCH] = 1;
04777 
04778                 G_PlayEffect(EFFECT_SPARK_EXPLOSION, org, a);
04779 
04780                 self->client->ps.eFlags -= EF_SEEKERDRONE;
04781                 self->client->ps.genericEnemyIndex = -1;
04782 
04783                 return;
04784         }
04785 
04786         if (self->client->ps.genericEnemyIndex == -1)
04787         {
04788                 self->client->ps.genericEnemyIndex = ENTITYNUM_NONE;
04789         }
04790 
04791         if (self->client->ps.genericEnemyIndex != ENTITYNUM_NONE && self->client->ps.genericEnemyIndex != -1)
04792         {
04793                 en = &g_entities[self->client->ps.genericEnemyIndex];
04794 
04795                 if (!en || !en->client)
04796                 {
04797                         self->client->ps.genericEnemyIndex = ENTITYNUM_NONE;
04798                 }
04799                 else if (en->s.number == self->s.number)
04800                 {
04801                         self->client->ps.genericEnemyIndex = ENTITYNUM_NONE;
04802                 }
04803                 else if (en->health < 1)
04804                 {
04805                         self->client->ps.genericEnemyIndex = ENTITYNUM_NONE;
04806                 }
04807                 else if (OnSameTeam(self, en))
04808                 {
04809                         self->client->ps.genericEnemyIndex = ENTITYNUM_NONE;
04810                 }
04811                 else
04812                 {
04813                         if (!InFront(en->client->ps.origin, self->client->ps.origin, self->client->ps.viewangles, 0.8f ))
04814                         {
04815                                 self->client->ps.genericEnemyIndex = ENTITYNUM_NONE;
04816                         }
04817                         else if (!OrgVisible(self->client->ps.origin, en->client->ps.origin, self->s.number))
04818                         {
04819                                 self->client->ps.genericEnemyIndex = ENTITYNUM_NONE;
04820                         }
04821                 }
04822         }
04823 
04824         if (self->client->ps.genericEnemyIndex == ENTITYNUM_NONE || self->client->ps.genericEnemyIndex == -1)
04825         {
04826                 FindGenericEnemyIndex(self);
04827         }
04828 
04829         if (self->client->ps.genericEnemyIndex != ENTITYNUM_NONE && self->client->ps.genericEnemyIndex != -1)
04830         {
04831                 en = &g_entities[self->client->ps.genericEnemyIndex];
04832 
04833                 VectorCopy(self->client->ps.origin, elevated);
04834                 elevated[2] += 40;
04835 
04836                 angle = ((level.time / 12) & 255) * (M_PI * 2) / 255; //magical numbers make magic happen
04837                 dir[0] = cos(angle) * 20;
04838                 dir[1] = sin(angle) * 20;
04839                 dir[2] = cos(angle) * 5;
04840                 VectorAdd(elevated, dir, org);
04841 
04842                 //org is now where the thing should be client-side because it uses the same time-based offset
04843                 if (self->client->ps.droneFireTime < level.time)
04844                 {
04845                         trap_Trace(&tr, org, NULL, NULL, en->client->ps.origin, -1, MASK_SOLID);
04846 
04847                         if (tr.fraction == 1 && !tr.startsolid && !tr.allsolid)
04848                         {
04849                                 VectorSubtract(en->client->ps.origin, org, endir);
04850                                 VectorNormalize(endir);
04851 
04852                                 WP_FireGenericBlasterMissile(self, org, endir, 0, 15, 2000, MOD_BLASTER);
04853                                 G_SoundAtLoc( org, CHAN_WEAPON, G_SoundIndex("sound/weapons/bryar/fire.wav") );
04854 
04855                                 self->client->ps.droneFireTime = level.time + Q_irand(400, 700);
04856                         }
04857                 }
04858         }
04859 }

void Touch_Button gentity_t ent,
gentity_t other,
trace_t trace
 

Definition at line 1623 of file g_mover.c.

References gentity_s::client, gentity_t, MOVER_POS1, gentity_s::moverState, and Use_BinaryMover().

Referenced by ForceThrow(), SP_func_button(), and TryUse().

01623                                                                      {
01624         if ( !other->client ) {
01625                 return;
01626         }
01627 
01628         if ( ent->moverState == MOVER_POS1 ) {
01629                 Use_BinaryMover( ent, other, other );
01630         }
01631 }

int WP_AbsorbConversion gentity_t attacked,
int  atdAbsLevel,
gentity_t attacker,
int  atPower,
int  atPowerLevel,
int  atForceSpent
 

Definition at line 940 of file w_force.c.

References gentity_s::client, playerState_s::fd, forcedata_s::forcePower, forcedata_s::forcePowerLevel, forcedata_s::forcePowersActive, gclient_s::forcePowerSoundDebounce, FP_ABSORB, FP_DRAIN, FP_GRIP, FP_LIGHTNING, FP_PULL, FP_PUSH, G_PreDefSound(), gentity_t, level, entityState_s::number, playerState_s::origin, PDSOUND_ABSORBHIT, gclient_s::ps, gentity_s::s, level_locals_t::time, and entityState_s::trickedentindex.

Referenced by DoGripAction(), ForceDrainDamage(), ForceLightningDamage(), and ForceThrow().

00941 {
00942         int getLevel = 0;
00943         int addTot = 0;
00944         gentity_t *abSound;
00945 
00946         if (atPower != FP_LIGHTNING &&
00947                 atPower != FP_DRAIN &&
00948                 atPower != FP_GRIP &&
00949                 atPower != FP_PUSH &&
00950                 atPower != FP_PULL)
00951         { //Only these powers can be absorbed
00952                 return -1;
00953         }
00954 
00955         if (!atdAbsLevel)
00956         { //looks like attacker doesn't have any absorb power
00957                 return -1;
00958         }
00959 
00960         if (!(attacked->client->ps.fd.forcePowersActive & (1 << FP_ABSORB)))
00961         { //absorb is not active
00962                 return -1;
00963         }
00964 
00965         //Subtract absorb power level from the offensive force power
00966         getLevel = atPowerLevel;
00967         getLevel -= atdAbsLevel;
00968 
00969         if (getLevel < 0)
00970         {
00971                 getLevel = 0;
00972         }
00973 
00974         //let the attacker absorb an amount of force used in this attack based on his level of absorb
00975         addTot = (atForceSpent/3)*attacked->client->ps.fd.forcePowerLevel[FP_ABSORB];
00976 
00977         if (addTot < 1 && atForceSpent >= 1)
00978         {
00979                 addTot = 1;
00980         }
00981         attacked->client->ps.fd.forcePower += addTot;
00982         if (attacked->client->ps.fd.forcePower > 100)
00983         {
00984                 attacked->client->ps.fd.forcePower = 100;
00985         }
00986 
00987         //play sound indicating that attack was absorbed
00988         if (attacked->client->forcePowerSoundDebounce < level.time)
00989         {
00990                 abSound = G_PreDefSound(attacked->client->ps.origin, PDSOUND_ABSORBHIT);
00991                 abSound->s.trickedentindex = attacked->s.number;
00992 
00993                 attacked->client->forcePowerSoundDebounce = level.time + 400;
00994         }
00995 
00996         return getLevel;
00997 }

void WP_AddAsMindtricked forcedata_t fd,
int  entNum
 

Definition at line 2502 of file w_force.c.

References forcedata_t, forcedata_s::forceMindtrickTargetIndex, forcedata_s::forceMindtrickTargetIndex2, forcedata_s::forceMindtrickTargetIndex3, and forcedata_s::forceMindtrickTargetIndex4.

Referenced by ForceTelepathy().

02503 {
02504         if (!fd)
02505         {
02506                 return;
02507         }
02508 
02509         if (entNum > 47)
02510         {
02511                 fd->forceMindtrickTargetIndex4 |= (1 << (entNum-48));
02512         }
02513         else if (entNum > 31)
02514         {
02515                 fd->forceMindtrickTargetIndex3 |= (1 << (entNum-32));
02516         }
02517         else if (entNum > 15)
02518         {
02519                 fd->forceMindtrickTargetIndex2 |= (1 << (entNum-16));
02520         }
02521         else
02522         {
02523                 fd->forceMindtrickTargetIndex |= (1 << entNum);
02524         }
02525 }

void WP_AddToClientBitflags gentity_t ent,
int  entNum
 

Definition at line 1294 of file w_force.c.

References gentity_t, gentity_s::s, entityState_s::trickedentindex, entityState_s::trickedentindex2, entityState_s::trickedentindex3, and entityState_s::trickedentindex4.

Referenced by ForceTeamForceReplenish(), and ForceTeamHeal().

01295 {
01296         if (!ent)
01297         {
01298                 return;
01299         }
01300 
01301         if (entNum > 47)
01302         {
01303                 ent->s.trickedentindex4 |= (1 << (entNum-48));
01304         }
01305         else if (entNum > 31)
01306         {
01307                 ent->s.trickedentindex3 |= (1 << (entNum-32));
01308         }
01309         else if (entNum > 15)
01310         {
01311                 ent->s.trickedentindex2 |= (1 << (entNum-16));
01312         }
01313         else
01314         {
01315                 ent->s.trickedentindex |= (1 << entNum);
01316         }
01317 }

int WP_DoSpecificPower gentity_t self,
usercmd_t ucmd,
forcePowers_t  forcepower
 

Definition at line 4499 of file w_force.c.

References BG_ForcePowerDrain(), CHAN_VOICE, gentity_s::client, ENTITYNUM_NONE, playerState_s::fd, ForceAbsorb(), forcedata_s::forceButtonNeedRelease, ForceDrain(), ForceGrip(), forcedata_s::forceGripEntityNum, ForceHeal(), ForceJump(), forcedata_s::forceJumpCharge, ForceLightning(), forcePowers_t, forcedata_s::forcePowersActive, ForceProtect(), ForceRage(), ForceSeeing(), ForceSpeed(), ForceTeamForceReplenish(), ForceTeamHeal(), ForceTelepathy(), ForceThrow(), FP_ABSORB, FP_DRAIN, FP_GRIP, FP_HEAL, FP_LEVITATION, FP_LIGHTNING, FP_PROTECT, FP_PULL, FP_PUSH, FP_RAGE, FP_SABER_DEFENSE, FP_SABER_OFFENSE, FP_SABERTHROW, FP_SEE, FP_SPEED, FP_TEAM_FORCE, FP_TEAM_HEAL, FP_TELEPATHY, G_MuteSound(), gentity_t, GRIP_DRAIN_AMOUNT, playerState_s::groundEntityNum, forcedata_s::killSoundEntIndex, gclient_s::ps, qfalse, qtrue, gentity_s::r, SVF_BOT, entityShared_t::svFlags, TRACK_CHANNEL_1, ucmd, usercmd_t, WP_ForcePowerAvailable(), and WP_ForcePowerStart().

Referenced by WP_ForcePowersUpdate().

04500 {
04501         int powerSucceeded;
04502 
04503         powerSucceeded = 1;
04504 
04505         // OVERRIDEFIXME
04506         if ( !WP_ForcePowerAvailable( self, forcepower, 0 ) )
04507         {
04508                 return 0;
04509         }
04510 
04511         switch(forcepower)
04512         {
04513         case FP_HEAL:
04514                 powerSucceeded = 0; //always 0 for nonhold powers
04515                 if (self->client->ps.fd.forceButtonNeedRelease)
04516                 { //need to release before we can use nonhold powers again
04517                         break;
04518                 }
04519                 ForceHeal(self);
04520                 self->client->ps.fd.forceButtonNeedRelease = 1;
04521                 break;
04522         case FP_LEVITATION:
04523                 //if leave the ground by some other means, cancel the force jump so we don't suddenly jump when we land.
04524                 
04525                 if ( self->client->ps.groundEntityNum == ENTITYNUM_NONE )
04526                 {
04527                         self->client->ps.fd.forceJumpCharge = 0;
04528                         G_MuteSound( self->client->ps.fd.killSoundEntIndex[TRACK_CHANNEL_1-50], CHAN_VOICE );
04529                         //This only happens if the groundEntityNum == ENTITYNUM_NONE when the button is actually released
04530                 }
04531                 else
04532                 {//still on ground, so jump
04533                         ForceJump( self, ucmd );
04534                 }
04535                 break;
04536         case FP_SPEED:
04537                 powerSucceeded = 0; //always 0 for nonhold powers
04538                 if (self->client->ps.fd.forceButtonNeedRelease)
04539                 { //need to release before we can use nonhold powers again
04540                         break;
04541                 }
04542                 ForceSpeed(self, 0);
04543                 self->client->ps.fd.forceButtonNeedRelease = 1;
04544                 break;
04545         case FP_GRIP:
04546                 if (self->client->ps.fd.forceGripEntityNum == ENTITYNUM_NONE)
04547                 {
04548                         ForceGrip( self );
04549                 }
04550 
04551                 if (self->client->ps.fd.forceGripEntityNum != ENTITYNUM_NONE)
04552                 {
04553                         if (!(self->client->ps.fd.forcePowersActive & (1 << FP_GRIP)))
04554                         {
04555                                 WP_ForcePowerStart( self, FP_GRIP, 0 );
04556                                 BG_ForcePowerDrain( &self->client->ps, FP_GRIP, GRIP_DRAIN_AMOUNT );
04557                         }
04558                 }
04559                 else
04560                 {
04561                         powerSucceeded = 0;
04562                 }
04563                 break;
04564         case FP_LIGHTNING:
04565                 ForceLightning(self);
04566                 break;
04567         case FP_PUSH:
04568                 powerSucceeded = 0; //always 0 for nonhold powers
04569                 if (self->client->ps.fd.forceButtonNeedRelease && !(self->r.svFlags & SVF_BOT))
04570                 { //need to release before we can use nonhold powers again
04571                         break;
04572                 }
04573                 ForceThrow(self, qfalse);
04574                 self->client->ps.fd.forceButtonNeedRelease = 1;
04575                 break;
04576         case FP_PULL:
04577                 powerSucceeded = 0; //always 0 for nonhold powers
04578                 if (self->client->ps.fd.forceButtonNeedRelease)
04579                 { //need to release before we can use nonhold powers again
04580                         break;
04581                 }
04582                 ForceThrow(self, qtrue);
04583                 self->client->ps.fd.forceButtonNeedRelease = 1;
04584                 break;
04585         case FP_TELEPATHY:
04586                 powerSucceeded = 0; //always 0 for nonhold powers
04587                 if (self->client->ps.fd.forceButtonNeedRelease)
04588                 { //need to release before we can use nonhold powers again
04589                         break;
04590                 }
04591                 ForceTelepathy(self);
04592                 self->client->ps.fd.forceButtonNeedRelease = 1;
04593                 break;
04594         case FP_RAGE:
04595                 powerSucceeded = 0; //always 0 for nonhold powers
04596                 if (self->client->ps.fd.forceButtonNeedRelease)
04597                 { //need to release before we can use nonhold powers again
04598                         break;
04599                 }
04600                 ForceRage(self);
04601                 self->client->ps.fd.forceButtonNeedRelease = 1;
04602                 break;
04603         case FP_PROTECT:
04604                 powerSucceeded = 0; //always 0 for nonhold powers
04605                 if (self->client->ps.fd.forceButtonNeedRelease)
04606                 { //need to release before we can use nonhold powers again
04607                         break;
04608                 }
04609                 ForceProtect(self);
04610                 self->client->ps.fd.forceButtonNeedRelease = 1;
04611                 break;
04612         case FP_ABSORB:
04613                 powerSucceeded = 0; //always 0 for nonhold powers
04614                 if (self->client->ps.fd.forceButtonNeedRelease)
04615                 { //need to release before we can use nonhold powers again
04616                         break;
04617                 }
04618                 ForceAbsorb(self);
04619                 self->client->ps.fd.forceButtonNeedRelease = 1;
04620                 break;
04621         case FP_TEAM_HEAL:
04622                 powerSucceeded = 0; //always 0 for nonhold powers
04623                 if (self->client->ps.fd.forceButtonNeedRelease)
04624                 { //need to release before we can use nonhold powers again
04625                         break;
04626                 }
04627                 ForceTeamHeal(self);
04628                 self->client->ps.fd.forceButtonNeedRelease = 1;
04629                 break;
04630         case FP_TEAM_FORCE:
04631                 powerSucceeded = 0; //always 0 for nonhold powers
04632                 if (self->client->ps.fd.forceButtonNeedRelease)
04633                 { //need to release before we can use nonhold powers again
04634                         break;
04635                 }
04636                 ForceTeamForceReplenish(self);
04637                 self->client->ps.fd.forceButtonNeedRelease = 1;
04638                 break;
04639         case FP_DRAIN:
04640                 ForceDrain(self);
04641                 break;
04642         case FP_SEE:
04643                 powerSucceeded = 0; //always 0 for nonhold powers
04644                 if (self->client->ps.fd.forceButtonNeedRelease)
04645                 { //need to release before we can use nonhold powers again
04646                         break;
04647                 }
04648                 ForceSeeing(self);
04649                 self->client->ps.fd.forceButtonNeedRelease = 1;
04650                 break;
04651         case FP_SABER_OFFENSE:
04652                 break;
04653         case FP_SABER_DEFENSE:
04654                 break;
04655         case FP_SABERTHROW:
04656                 break;
04657         default:
04658                 break;
04659         }
04660 
04661         return powerSucceeded;
04662 }

qboolean WP_ForcePowerAvailable gentity_t self,
forcePowers_t  forcePower,
int  overrideAmt
 

Definition at line 774 of file w_force.c.

References gentity_s::client, playerState_s::fd, forcedata_s::forcePower, forcedata_s::forcePowerLevel, forcePowerNeeded, forcePowers_t, forcedata_s::forcePowersActive, FP_DRAIN, FP_LEVITATION, FP_LIGHTNING, gentity_t, gclient_s::ps, qboolean, qfalse, and qtrue.

Referenced by WP_DoSpecificPower(), WP_ForcePowerStart(), and WP_ForcePowerUsable().

00775 {
00776         int     drain = overrideAmt ? overrideAmt :
00777                                 forcePowerNeeded[self->client->ps.fd.forcePowerLevel[forcePower]][forcePower];
00778 
00779         if (self->client->ps.fd.forcePowersActive & (1 << forcePower))
00780         { //we're probably going to deactivate it..
00781                 return qtrue;
00782         }
00783         if ( forcePower == FP_LEVITATION )
00784         {
00785                 return qtrue;
00786         }
00787         if ( !drain )
00788         {
00789                 return qtrue;
00790         }
00791         if ((forcePower == FP_DRAIN || forcePower == FP_LIGHTNING) &&
00792                 self->client->ps.fd.forcePower >= 25)
00793         { //it's ok then, drain/lightning are actually duration
00794                 return qtrue;
00795         }
00796         if ( self->client->ps.fd.forcePower < drain )
00797         {
00798                 return qfalse;
00799         }
00800         return qtrue;
00801 }

qboolean WP_ForcePowerInUse gentity_t self,
forcePowers_t  forcePower
 

Definition at line 803 of file w_force.c.

References gentity_s::client, playerState_s::fd, forcePowers_t, forcedata_s::forcePowersActive, gentity_t, gclient_s::ps, qboolean, qfalse, and qtrue.

00804 {
00805         if ( (self->client->ps.fd.forcePowersActive & ( 1 << forcePower )) )
00806         {//already using this power
00807                 return qtrue;
00808         }
00809 
00810         return qfalse;
00811 }

void WP_ForcePowerRegenerate gentity_t self,
int  overrideAmt
 

Definition at line 999 of file w_force.c.

References gentity_s::client, playerState_s::fd, forcedata_s::forcePower, forcedata_s::forcePowerMax, gentity_t, and gclient_s::ps.

Referenced by WP_ForcePowersUpdate().

01000 { //called on a regular interval to regenerate force power.
01001         if ( !self->client )
01002         {
01003                 return;
01004         }
01005 
01006         if ( overrideAmt )
01007         { //custom regen amount
01008                 self->client->ps.fd.forcePower += overrideAmt;
01009         }
01010         else
01011         { //otherwise, just 1
01012                 self->client->ps.fd.forcePower++;
01013         }
01014 
01015         if ( self->client->ps.fd.forcePower > self->client->ps.fd.forcePowerMax )
01016         { //cap it off at the max (default 100)
01017                 self->client->ps.fd.forcePower = self->client->ps.fd.forcePowerMax;
01018         }
01019 }

void WP_ForcePowerStart gentity_t self,
forcePowers_t  forcePower,
int  overrideAmt
 

Definition at line 1021 of file w_force.c.

References playerState_s::activeForcePass, BG_ForcePowerDrain(), BG_FullBodyTauntAnim(), gentity_s::client, playerState_s::fd, FORCE_LEVEL_1, FORCE_LEVEL_2, FORCE_LEVEL_3, forcedata_s::forcePowerDebounce, forcedata_s::forcePowerDuration, forcedata_s::forcePowerLevel, forcePowers_t, forcedata_s::forcePowersActive, FP_ABSORB, FP_DRAIN, FP_GRIP, FP_HEAL, FP_LEVITATION, FP_LIGHTNING, FP_PROTECT, FP_PULL, FP_PUSH, FP_RAGE, FP_SABER_DEFENSE, FP_SABER_OFFENSE, FP_SABERTHROW, FP_SEE, FP_SPEED, FP_TEAM_FORCE, FP_TEAM_HEAL, FP_TELEPATHY, gentity_t, playerState_s::legsAnim, playerState_s::legsTimer, level, playerState_s::otherSoundLen, playerState_s::otherSoundTime, playerState_s::powerups, gclient_s::ps, PW_DISINT_4, qboolean, qfalse, qtrue, level_locals_t::time, playerState_s::torsoAnim, playerState_s::torsoTimer, and WP_ForcePowerAvailable().

Referenced by ForceAbsorb(), ForceDrain(), ForceJump(), ForceLightning(), ForceProtect(), ForceRage(), ForceSeeing(), ForceSpeed(), ForceTelepathy(), ForceTelepathyCheckDirectNPCTarget(), ForceThrow(), and WP_DoSpecificPower().

01022 { //activate the given force power
01023         int     duration = 0;
01024         qboolean hearable = qfalse;
01025         float hearDist = 0;
01026 
01027         if (!WP_ForcePowerAvailable( self, forcePower, overrideAmt ))
01028         {
01029                 return;
01030         }
01031 
01032         if ( BG_FullBodyTauntAnim( self->client->ps.legsAnim ) )
01033         {//stop taunt
01034                 self->client->ps.legsTimer = 0;
01035         }
01036         if ( BG_FullBodyTauntAnim( self->client->ps.torsoAnim ) )
01037         {//stop taunt
01038                 self->client->ps.torsoTimer = 0;
01039         }
01040         //hearable and hearDist are merely for the benefit of bots, and not related to if a sound is actually played.
01041         //If duration is set, the force power will assume to be timer-based.
01042         switch( (int)forcePower )
01043         {
01044         case FP_HEAL:
01045                 hearable = qtrue;
01046                 hearDist = 256;
01047                 self->client->ps.fd.forcePowersActive |= ( 1 << forcePower );
01048                 break;
01049         case FP_LEVITATION:
01050                 hearable = qtrue;
01051                 hearDist = 256;
01052                 self->client->ps.fd.forcePowersActive |= ( 1 << forcePower );
01053                 break;
01054         case FP_SPEED:
01055                 hearable = qtrue;
01056                 hearDist = 256;
01057                 if (self->client->ps.fd.forcePowerLevel[FP_SPEED] == FORCE_LEVEL_1)
01058                 {
01059                         duration = 10000;
01060                 }
01061                 else if (self->client->ps.fd.forcePowerLevel[FP_SPEED] == FORCE_LEVEL_2)
01062                 {
01063                         duration = 15000;
01064                 }
01065                 else if (self->client->ps.fd.forcePowerLevel[FP_SPEED] == FORCE_LEVEL_3)
01066                 {
01067                         duration = 20000;
01068                 }
01069                 else //shouldn't get here
01070                 {
01071                         break;
01072                 }
01073 
01074                 if (overrideAmt)
01075                 {
01076                         duration = overrideAmt;
01077                 }
01078 
01079                 self->client->ps.fd.forcePowersActive |= ( 1 << forcePower );
01080                 break;
01081         case FP_PUSH:
01082                 hearable = qtrue;
01083                 hearDist = 256;
01084                 break;
01085         case FP_PULL:
01086                 hearable = qtrue;
01087                 hearDist = 256;
01088                 break;
01089         case FP_TELEPATHY:
01090                 hearable = qtrue;
01091                 hearDist = 256;
01092                 if (self->client->ps.fd.forcePowerLevel[FP_TELEPATHY] == FORCE_LEVEL_1)
01093                 {
01094                         duration = 20000;
01095                 }
01096                 else if (self->client->ps.fd.forcePowerLevel[FP_TELEPATHY] == FORCE_LEVEL_2)
01097                 {
01098                         duration = 25000;
01099                 }
01100                 else if (self->client->ps.fd.forcePowerLevel[FP_TELEPATHY] == FORCE_LEVEL_3)
01101                 {
01102                         duration = 30000;
01103                 }
01104                 else //shouldn't get here
01105                 {
01106                         break;
01107                 }
01108 
01109                 self->client->ps.fd.forcePowersActive |= ( 1 << forcePower );
01110                 break;
01111         case FP_GRIP:
01112                 hearable = qtrue;
01113                 hearDist = 256;
01114                 self->client->ps.fd.forcePowersActive |= ( 1 << forcePower );
01115                 self->client->ps.powerups[PW_DISINT_4] = level.time + 60000;
01116                 break;
01117         case FP_LIGHTNING:
01118                 hearable = qtrue;
01119                 hearDist = 512;
01120                 duration = overrideAmt;
01121                 overrideAmt = 0;
01122                 self->client->ps.fd.forcePowersActive |= ( 1 << forcePower );
01123                 self->client->ps.activeForcePass = self->client->ps.fd.forcePowerLevel[FP_LIGHTNING];
01124                 break;
01125         case FP_RAGE:
01126                 hearable = qtrue;
01127                 hearDist = 256;
01128                 if (self->client->ps.fd.forcePowerLevel[FP_RAGE] == FORCE_LEVEL_1)
01129                 {
01130                         duration = 8000;
01131                 }
01132                 else if (self->client->ps.fd.forcePowerLevel[FP_RAGE] == FORCE_LEVEL_2)
01133                 {
01134                         duration = 14000;
01135                 }
01136                 else if (self->client->ps.fd.forcePowerLevel[FP_RAGE] == FORCE_LEVEL_3)
01137                 {
01138                         duration = 20000;
01139                 }
01140                 else //shouldn't get here
01141                 {
01142                         break;
01143                 }
01144 
01145                 self->client->ps.fd.forcePowersActive |= ( 1 << forcePower );
01146                 break;
01147         case FP_PROTECT:
01148                 hearable = qtrue;
01149                 hearDist = 256;
01150                 duration = 20000;
01151                 self->client->ps.fd.forcePowersActive |= ( 1 << forcePower );
01152                 break;
01153         case FP_ABSORB:
01154                 hearable = qtrue;
01155                 hearDist = 256;
01156                 duration = 20000;
01157                 self->client->ps.fd.forcePowersActive |= ( 1 << forcePower );
01158                 break;
01159         case FP_TEAM_HEAL:
01160                 hearable = qtrue;
01161                 hearDist = 256;
01162                 self->client->ps.fd.forcePowersActive |= ( 1 << forcePower );
01163                 break;
01164         case FP_TEAM_FORCE:
01165                 hearable = qtrue;
01166                 hearDist = 256;
01167                 self->client->ps.fd.forcePowersActive |= ( 1 << forcePower );
01168                 break;
01169         case FP_DRAIN:
01170                 hearable = qtrue;
01171                 hearDist = 256;
01172                 duration = overrideAmt;
01173                 overrideAmt = 0;
01174                 self->client->ps.fd.forcePowersActive |= ( 1 << forcePower );
01175                 //self->client->ps.activeForcePass = self->client->ps.fd.forcePowerLevel[FP_DRAIN];
01176                 break;
01177         case FP_SEE:
01178                 hearable = qtrue;
01179                 hearDist = 256;
01180                 if (self->client->ps.fd.forcePowerLevel[FP_SEE] == FORCE_LEVEL_1)
01181                 {
01182                         duration = 10000;
01183                 }
01184                 else if (self->client->ps.fd.forcePowerLevel[FP_SEE] == FORCE_LEVEL_2)
01185                 {
01186                         duration = 20000;
01187                 }
01188                 else if (self->client->ps.fd.forcePowerLevel[FP_SEE] == FORCE_LEVEL_3)
01189                 {
01190                         duration = 30000;
01191                 }
01192                 else //shouldn't get here
01193                 {
01194                         break;
01195                 }
01196 
01197                 self->client->ps.fd.forcePowersActive |= ( 1 << forcePower );
01198                 break;
01199         case FP_SABER_OFFENSE:
01200                 break;
01201         case FP_SABER_DEFENSE:
01202                 break;
01203         case FP_SABERTHROW:
01204                 break;
01205         default:
01206                 break;
01207         }
01208 
01209         if ( duration )
01210         {
01211                 self->client->ps.fd.forcePowerDuration[forcePower] = level.time + duration;
01212         }
01213         else
01214         {
01215                 self->client->ps.fd.forcePowerDuration[forcePower] = 0;
01216         }
01217 
01218         if (hearable)
01219         {
01220                 self->client->ps.otherSoundLen = hearDist;
01221                 self->client->ps.otherSoundTime = level.time + 100;
01222         }
01223         
01224         self->client->ps.fd.forcePowerDebounce[forcePower] = 0;
01225 
01226         if ((int)forcePower == FP_SPEED && overrideAmt)
01227         {
01228                 BG_ForcePowerDrain( &self->client->ps, forcePower, overrideAmt*0.025 );
01229         }
01230         else if ((int)forcePower != FP_GRIP && (int)forcePower != FP_DRAIN)
01231         { //grip and drain drain as damage is done
01232                 BG_ForcePowerDrain( &self->client->ps, forcePower, overrideAmt );
01233         }
01234 }

void WP_ForcePowerStop gentity_t self,
forcePowers_t  forcePower
 

Definition at line 3819 of file w_force.c.

References playerState_s::activeForcePass, CHAN_AUTO, CHAN_VOICE, gentity_s::client, ENTITYNUM_NONE, playerState_s::fd, FORCE_LEVEL_1, FORCE_LEVEL_2, forcedata_s::forceGripEntityNum, forcedata_s::forceGripUseTime, playerState_s::forceHandExtend, playerState_s::forceHandExtendTime, forcedata_s::forceHealAmount, forcedata_s::forceHealTime, forcedata_s::forceMindtrickTargetIndex, forcedata_s::forceMindtrickTargetIndex2, forcedata_s::forceMindtrickTargetIndex3, forcedata_s::forceMindtrickTargetIndex4, forcedata_s::forcePowerDebounce, forcedata_s::forcePowerLevel, forcePowers_t, forcedata_s::forcePowersActive, forcedata_s::forceRageRecoveryTime, FP_ABSORB, FP_DRAIN, FP_GRIP, FP_HEAL, FP_LEVITATION, FP_LIGHTNING, FP_PROTECT, FP_PULL, FP_PUSH, FP_RAGE, FP_SEE, FP_SPEED, FP_TELEPATHY, g_entities, G_EntitySound(), G_MuteSound(), G_Sound(), G_SoundIndex(), gentity_t, HANDEXTEND_FORCE_HOLD, forcedata_s::killSoundEntIndex, level, PM_NORMAL, playerState_s::powerups, gclient_s::ps, PW_DISINT_4, level_locals_t::time, TRACK_CHANNEL_2, TRACK_CHANNEL_3, and TRACK_CHANNEL_5.

Referenced by ClientBegin(), ClientDisconnect(), DoGripAction(), ForceAbsorb(), ForceProtect(), ForceRage(), ForceSeeing(), ForceSpeed(), ForceTelepathy(), ForceThrow(), HolocronUpdate(), Jedi_SaberBlockGo(), JediMasterUpdate(), NPC_Jedi_Pain(), WP_ForcePowersUpdate(), and WP_SpawnInitForcePowers().

03820 {
03821         int wasActive = self->client->ps.fd.forcePowersActive;
03822 
03823         self->client->ps.fd.forcePowersActive &= ~( 1 << forcePower );
03824 
03825         switch( (int)forcePower )
03826         {
03827         case FP_HEAL:
03828                 self->client->ps.fd.forceHealAmount = 0;
03829                 self->client->ps.fd.forceHealTime = 0;
03830                 break;
03831         case FP_LEVITATION:
03832                 break;
03833         case FP_SPEED:
03834                 if (wasActive & (1 << FP_SPEED))
03835                 {
03836                         G_MuteSound(self->client->ps.fd.killSoundEntIndex[TRACK_CHANNEL_2-50], CHAN_VOICE);
03837                 }
03838                 break;
03839         case FP_PUSH:
03840                 break;
03841         case FP_PULL:
03842                 break;
03843         case FP_TELEPATHY:
03844                 if (wasActive & (1 << FP_TELEPATHY))
03845                 {
03846                         G_Sound( self, CHAN_AUTO, G_SoundIndex("sound/weapons/force/distractstop.wav") );
03847                 }
03848                 self->client->ps.fd.forceMindtrickTargetIndex = 0;
03849                 self->client->ps.fd.forceMindtrickTargetIndex2 = 0;
03850                 self->client->ps.fd.forceMindtrickTargetIndex3 = 0;
03851                 self->client->ps.fd.forceMindtrickTargetIndex4 = 0;
03852                 break;
03853         case FP_SEE:
03854                 if (wasActive & (1 << FP_SEE))
03855                 {
03856                         G_MuteSound(self->client->ps.fd.killSoundEntIndex[TRACK_CHANNEL_5-50], CHAN_VOICE);
03857                 }
03858                 break;
03859         case FP_GRIP:
03860                 self->client->ps.fd.forceGripUseTime = level.time + 3000;
03861                 if (self->client->ps.fd.forcePowerLevel[FP_GRIP] > FORCE_LEVEL_1 &&
03862                         g_entities[self->client->ps.fd.forceGripEntityNum].client &&
03863                         g_entities[self->client->ps.fd.forceGripEntityNum].health > 0 &&
03864                         g_entities[self->client->ps.fd.forceGripEntityNum].inuse &&
03865                         (level.time - g_entities[self->client->ps.fd.forceGripEntityNum].client->ps.fd.forceGripStarted) > 500)
03866                 { //if we had our throat crushed in for more than half a second, gasp for air when we're let go
03867                         if (wasActive & (1 << FP_GRIP))
03868                         {
03869                                 G_EntitySound( &g_entities[self->client->ps.fd.forceGripEntityNum], CHAN_VOICE, G_SoundIndex("*gasp.wav") );
03870                         }
03871                 }
03872 
03873                 if (g_entities[self->client->ps.fd.forceGripEntityNum].client &&
03874                         g_entities[self->client->ps.fd.forceGripEntityNum].inuse)
03875                 {
03876                         
03877                         g_entities[self->client->ps.fd.forceGripEntityNum].client->ps.forceGripChangeMovetype = PM_NORMAL;
03878                 }
03879 
03880                 if (self->client->ps.forceHandExtend == HANDEXTEND_FORCE_HOLD)
03881                 {
03882                         self->client->ps.forceHandExtendTime = 0;
03883                 }
03884 
03885                 self->client->ps.fd.forceGripEntityNum = ENTITYNUM_NONE;
03886 
03887                 self->client->ps.powerups[PW_DISINT_4] = 0;
03888                 break;
03889         case FP_LIGHTNING:
03890                 if ( self->client->ps.fd.forcePowerLevel[FP_LIGHTNING] < FORCE_LEVEL_2 )
03891                 {//don't do it again for 3 seconds, minimum... FIXME: this should be automatic once regeneration is slower (normal)
03892                         self->client->ps.fd.forcePowerDebounce[FP_LIGHTNING] = level.time + 3000;
03893                 }
03894                 else
03895                 {
03896                         self->client->ps.fd.forcePowerDebounce[FP_LIGHTNING] = level.time + 1500;
03897                 }
03898                 if (self->client->ps.forceHandExtend == HANDEXTEND_FORCE_HOLD)
03899                 {
03900                         self->client->ps.forceHandExtendTime = 0; //reset hand position
03901                 }
03902 
03903                 self->client->ps.activeForcePass = 0;
03904                 break;
03905         case FP_RAGE:
03906                 self->client->ps.fd.forceRageRecoveryTime = level.time + 10000;
03907                 if (wasActive & (1 << FP_RAGE))
03908                 {
03909                         G_MuteSound(self->client->ps.fd.killSoundEntIndex[TRACK_CHANNEL_3-50], CHAN_VOICE);
03910                 }
03911                 break;
03912         case FP_ABSORB:
03913                 if (wasActive & (1 << FP_ABSORB))
03914                 {
03915                         G_MuteSound(self->client->ps.fd.killSoundEntIndex[TRACK_CHANNEL_3-50], CHAN_VOICE);
03916                 }
03917                 break;
03918         case FP_PROTECT:
03919                 if (wasActive & (1 << FP_PROTECT))
03920                 {
03921                         G_MuteSound(self->client->ps.fd.killSoundEntIndex[TRACK_CHANNEL_3-50], CHAN_VOICE);
03922                 }
03923                 break;
03924         case FP_DRAIN:
03925                 if ( self->client->ps.fd.forcePowerLevel[FP_DRAIN] < FORCE_LEVEL_2 )
03926                 {//don't do it again for 3 seconds, minimum...
03927                         self->client->ps.fd.forcePowerDebounce[FP_DRAIN] = level.time + 3000;
03928                 }
03929                 else
03930                 {
03931                         self->client->ps.fd.forcePowerDebounce[FP_DRAIN] = level.time + 1500;
03932                 }
03933 
03934                 if (self->client->ps.forceHandExtend == HANDEXTEND_FORCE_HOLD)
03935                 {
03936                         self->client->ps.forceHandExtendTime = 0; //reset hand position
03937                 }
03938 
03939                 self->client->ps.activeForcePass = 0;
03940         default:
03941                 break;
03942         }
03943 }

void WP_ForcePowersUpdate gentity_t self,
usercmd_t ucmd
 

Definition at line 5085 of file w_force.c.

References BG_CanUseFPNow(), BG_HasYsalamiri(), BG_SaberInSpecial(), bgSiegeClasses, BUTTON_FORCE_DRAIN, BUTTON_FORCE_LIGHTNING, BUTTON_FORCEGRIP, BUTTON_FORCEPOWER, usercmd_s::buttons, CFL_FASTFORCEREGEN, CHAN_VOICE, gentity_s::client, clientPersistant_t::cmd, Cmd_ToggleSaber_f(), clientSession_t::duelTeam, DUELTEAM_LONE, EF_DEAD, playerState_s::eFlags, ENTITYNUM_NONE, playerState_s::fd, gclient_s::fjDidJump, FORCE_LEVEL_1, FORCE_LEVEL_3, forcedata_s::forceButtonNeedRelease, forcedata_s::forceDeactivateAll, playerState_s::forceDodgeAnim, forcedata_s::forceGripBeingGripped, forcedata_s::forceGripCripple, forcedata_s::forceGripSoundTime, playerState_s::forceHandExtend, playerState_s::forceHandExtendTime, ForceJumpCharge(), forcedata_s::forceJumpCharge, forcedata_s::forceJumpSound, forcedata_s::forceMindtrickTargetIndex, forcedata_s::forceMindtrickTargetIndex2, forcedata_s::forceMindtrickTargetIndex3, forcedata_s::forceMindtrickTargetIndex4, forcedata_s::forcePower, forcedata_s::forcePowerBaseLevel, forcePowerDarkLight, forcedata_s::forcePowerDuration, forcedata_s::forcePowerLevel, forcedata_s::forcePowerRegenDebounceTime, forcePowers_t, forcedata_s::forcePowersActive, forcedata_s::forcePowerSelected, forcedata_s::forcePowersKnown, forcedata_s::forceRageRecoveryTime, forcedata_s::forceSide, forcedata_s::forceUsingAdded, FP_DRAIN, FP_GRIP, FP_LEVITATION, FP_LIGHTNING, FP_SPEED, FP_TELEPATHY, g_duel_fraglimit, g_entities, G_EntitySound(), g_forceRegenTime, g_gametype, g_LastFrameTime, g_MaxHolocronCarry, G_MuteSound(), G_PreDefSound(), G_SoundIndex(), G_SpecialRollGetup(), gentity_t, playerState_s::groundEntityNum, playerState_s::groundTime, GT_HOLOCRON, GT_JEDIMASTER, GT_POWERDUEL, GT_SIEGE, HANDEXTEND_KNOCKDOWN, HANDEXTEND_NONE, HANDEXTEND_POSTTHROWN, HANDEXTEND_WEAPONREADY, gentity_s::health, gclient_s::holdingObjectiveItem, playerState_s::holocronsCarried, HolocronUpdate(), vmCvar_t::integer, playerState_s::isJediMaster, JediMasterUpdate(), forcedata_s::killSoundEntIndex, level, NULL, NUM_FORCE_POWERS, playerState_s::origin, PDSOUND_FORCEGRIP, PDSOUND_FORCEJUMP, gclient_s::pers, playerState_s::pm_flags, PMF_FOLLOW, PMF_JUMP_HELD, playerState_s::powerups, gclient_s::ps, PW_FORCE_BOON, PW_FORCE_ENLIGHTENED_DARK, PW_FORCE_ENLIGHTENED_LIGHT, PW_SPEED, qboolean, qfalse, qtrue, playerState_s::quickerGetup, gentity_s::r, forcedata_s::saberAnimLevel, playerState_s::saberBlocked, playerState_s::saberBlocking, playerState_s::saberEntityNum, playerState_s::saberHolstered, playerState_s::saberInFlight, clientSession_t::saberLevel, playerState_s::saberMove, SeekerDroneUpdate(), clientSession_t::selectedFP, gclient_s::sess, clientSession_t::sessionTeam, gclient_s::siegeClass, SVF_BOT, entityShared_t::svFlags, TEAM_SPECTATOR, gclient_s::tempSpectate, level_locals_t::time, TR_LINEAR, TRACK_CHANNEL_1, ucmd, clientSession_t::updateUITime, usercmd_s::upmove, usercmd_t, vmCvar_t::value, playerState_s::velocity, playerState_s::weapon, WEAPON_READY, playerState_s::weaponstate, playerState_s::weaponTime, clientSession_t::wins, WP_DoSpecificPower(), WP_ForcePowerRegenerate(), WP_ForcePowerStop(), WP_SABER, playerState_s::zoomFov, playerState_s::zoomLocked, playerState_s::zoomMode, and playerState_s::zoomTime.

Referenced by G_RunFrame().

05086 {
05087         qboolean        usingForce = qfalse;
05088         int                     i, holo, holoregen;
05089         int                     prepower = 0;
05090         //see if any force powers are running
05091         if ( !self )
05092         {
05093                 return;
05094         }
05095 
05096         if ( !self->client )
05097         {
05098                 return;
05099         }
05100 
05101         if (self->client->ps.pm_flags & PMF_FOLLOW)
05102         { //not a "real" game client, it's a spectator following someone
05103                 return;
05104         }
05105         if (self->client->sess.sessionTeam == TEAM_SPECTATOR)
05106         {
05107                 return;
05108         }
05109 
05110         /*
05111         if (self->client->ps.fd.saberAnimLevel > self->client->ps.fd.forcePowerLevel[FP_SABER_OFFENSE])
05112         {
05113                 self->client->ps.fd.saberAnimLevel = self->client->ps.fd.forcePowerLevel[FP_SABER_OFFENSE];
05114         }
05115         else if (!self->client->ps.fd.saberAnimLevel)
05116         {
05117                 self->client->ps.fd.saberAnimLevel = FORCE_LEVEL_1;
05118         }
05119         */
05120         //The stance in relation to power level is no longer applicable with the crazy new akimbo/staff stances.
05121         if (!self->client->ps.fd.saberAnimLevel)
05122         {
05123                 self->client->ps.fd.saberAnimLevel = FORCE_LEVEL_1;
05124         }
05125 
05126         if (g_gametype.integer != GT_SIEGE)
05127         {
05128                 if (!(self->client->ps.fd.forcePowersKnown & (1 << FP_LEVITATION)))
05129                 {
05130                         self->client->ps.fd.forcePowersKnown |= (1 << FP_LEVITATION);
05131                 }
05132 
05133                 if (self->client->ps.fd.forcePowerLevel[FP_LEVITATION] < FORCE_LEVEL_1)
05134                 {
05135                         self->client->ps.fd.forcePowerLevel[FP_LEVITATION] = FORCE_LEVEL_1;
05136                 }
05137         }
05138 
05139         if (self->client->ps.fd.forcePowerSelected < 0)
05140         { //bad
05141                 self->client->ps.fd.forcePowerSelected = 0;
05142         }
05143 
05144         if ( ((self->client->sess.selectedFP != self->client->ps.fd.forcePowerSelected) ||
05145                 (self->client->sess.saberLevel != self->client->ps.fd.saberAnimLevel)) &&
05146                 !(self->r.svFlags & SVF_BOT) )
05147         {
05148                 if (self->client->sess.updateUITime < level.time)
05149                 { //a bit hackish, but we don't want the client to flood with userinfo updates if they rapidly cycle
05150                   //through their force powers or saber attack levels
05151 
05152                         self->client->sess.selectedFP = self->client->ps.fd.forcePowerSelected;
05153                         self->client->sess.saberLevel = self->client->ps.fd.saberAnimLevel;
05154                 }
05155         }
05156 
05157         if (!g_LastFrameTime)
05158         {
05159                 g_LastFrameTime = level.time;
05160         }
05161 
05162         if (self->client->ps.forceHandExtend == HANDEXTEND_KNOCKDOWN)
05163         {
05164                 self->client->ps.zoomFov = 0;
05165                 self->client->ps.zoomMode = 0;
05166                 self->client->ps.zoomLocked = qfalse;
05167                 self->client->ps.zoomTime = 0;
05168         }
05169 
05170         if (self->client->ps.forceHandExtend == HANDEXTEND_KNOCKDOWN &&
05171                 self->client->ps.forceHandExtendTime >= level.time)
05172         {
05173                 self->client->ps.saberMove = 0;
05174                 self->client->ps.saberBlocking = 0;
05175                 self->client->ps.saberBlocked = 0;
05176                 self->client->ps.weaponTime = 0;
05177                 self->client->ps.weaponstate = WEAPON_READY;
05178         }
05179         else if (self->client->ps.forceHandExtend != HANDEXTEND_NONE &&
05180                 self->client->ps.forceHandExtendTime < level.time)
05181         {
05182                 if (self->client->ps.forceHandExtend == HANDEXTEND_KNOCKDOWN &&
05183                         !self->client->ps.forceDodgeAnim)
05184                 {
05185                         if (self->health < 1 || (self->client->ps.eFlags & EF_DEAD))
05186                         {
05187                                 self->client->ps.forceHandExtend = HANDEXTEND_NONE;
05188                         }
05189                         else if (G_SpecialRollGetup(self))
05190                         {
05191                                 self->client->ps.forceHandExtend = HANDEXTEND_NONE;
05192                         }
05193                         else
05194                         { //hmm.. ok.. no more getting up on your own, you've gotta push something, unless..
05195                                 if ((level.time-self->client->ps.forceHandExtendTime) > 4000)
05196                                 { //4 seconds elapsed, I guess they're too dumb to push something to get up!
05197                                         if (self->client->pers.cmd.upmove &&
05198                                                 self->client->ps.fd.forcePowerLevel[FP_LEVITATION] > FORCE_LEVEL_1)
05199                                         { //force getup
05200                                                 G_PreDefSound(self->client->ps.origin, PDSOUND_FORCEJUMP);
05201                                                 self->client->ps.forceDodgeAnim = 2;
05202                                                 self->client->ps.forceHandExtendTime = level.time + 500;
05203 
05204                                                 //self->client->ps.velocity[2] = 400;
05205                                         }
05206                                         else if (self->client->ps.quickerGetup)
05207                                         {
05208                                                 G_EntitySound( self, CHAN_VOICE, G_SoundIndex("*jump1.wav") );
05209                                                 self->client->ps.forceDodgeAnim = 3;
05210                                                 self->client->ps.forceHandExtendTime = level.time + 500;
05211                                                 self->client->ps.velocity[2] = 300;
05212                                         }
05213                                         else
05214                                         {
05215                                                 self->client->ps.forceDodgeAnim = 1;
05216                                                 self->client->ps.forceHandExtendTime = level.time + 1000;
05217                                         }
05218                                 }
05219                         }
05220                         self->client->ps.quickerGetup = qfalse;
05221                 }
05222                 else if (self->client->ps.forceHandExtend == HANDEXTEND_POSTTHROWN)
05223                 {
05224                         if (self->health < 1 || (self->client->ps.eFlags & EF_DEAD))
05225                         {
05226                                 self->client->ps.forceHandExtend = HANDEXTEND_NONE;
05227                         }
05228                         else if (self->client->ps.groundEntityNum != ENTITYNUM_NONE && !self->client->ps.forceDodgeAnim)
05229                         {
05230                                 self->client->ps.forceDodgeAnim = 1;
05231                                 self->client->ps.forceHandExtendTime = level.time + 1000;
05232                                 G_EntitySound( self, CHAN_VOICE, G_SoundIndex("*jump1.wav") );
05233                                 self->client->ps.velocity[2] = 100;
05234                         }
05235                         else if (!self->client->ps.forceDodgeAnim)
05236                         {
05237                                 self->client->ps.forceHandExtendTime = level.time + 100;
05238                         }
05239                         else
05240                         {
05241                                 self->client->ps.forceHandExtend = HANDEXTEND_WEAPONREADY;
05242                         }
05243                 }
05244                 else
05245                 {
05246                         self->client->ps.forceHandExtend = HANDEXTEND_WEAPONREADY;
05247                 }
05248         }
05249 
05250         if (g_gametype.integer == GT_HOLOCRON)
05251         {
05252                 HolocronUpdate(self);
05253         }
05254         if (g_gametype.integer == GT_JEDIMASTER)
05255         {
05256                 JediMasterUpdate(self);
05257         }
05258 
05259         SeekerDroneUpdate(self);
05260 
05261         if (self->client->ps.powerups[PW_FORCE_BOON])
05262         {
05263                 prepower = self->client->ps.fd.forcePower;
05264         }
05265 
05266         if (self && self->client && (BG_HasYsalamiri(g_gametype.integer, &self->client->ps) ||
05267                 self->client->ps.fd.forceDeactivateAll || self->client->tempSpectate >= level.time))
05268         { //has ysalamiri.. or we want to forcefully stop all his active powers
05269                 i = 0;
05270 
05271                 while (i < NUM_FORCE_POWERS)
05272                 {
05273                         if ((self->client->ps.fd.forcePowersActive & (1 << i)) && i != FP_LEVITATION)
05274                         {
05275                                 WP_ForcePowerStop(self, i);
05276                         }
05277 
05278                         i++;
05279                 }
05280 
05281                 if (self->client->tempSpectate >= level.time)
05282                 {
05283                         self->client->ps.fd.forcePower = 100;
05284                         self->client->ps.fd.forceRageRecoveryTime = 0;
05285                 }
05286 
05287                 self->client->ps.fd.forceDeactivateAll = 0;
05288 
05289                 if (self->client->ps.fd.forceJumpCharge)
05290                 {
05291                         G_MuteSound(self->client->ps.fd.killSoundEntIndex[TRACK_CHANNEL_1-50], CHAN_VOICE);
05292                         self->client->ps.fd.forceJumpCharge = 0;
05293                 }
05294         }
05295         else
05296         { //otherwise just do a check through them all to see if they need to be stopped for any reason.
05297                 i = 0;
05298 
05299                 while (i < NUM_FORCE_POWERS)
05300                 {
05301                         if ((self->client->ps.fd.forcePowersActive & (1 << i)) && i != FP_LEVITATION &&
05302                                 !BG_CanUseFPNow(g_gametype.integer, &self->client->ps, level.time, i))
05303                         {
05304                                 WP_ForcePowerStop(self, i);
05305                         }
05306 
05307                         i++;
05308                 }
05309         }
05310 
05311         i = 0;
05312 
05313         if (self->client->ps.powerups[PW_FORCE_ENLIGHTENED_LIGHT] || self->client->ps.powerups[PW_FORCE_ENLIGHTENED_DARK])
05314         { //enlightenment
05315                 if (!self->client->ps.fd.forceUsingAdded)
05316                 {
05317                         i = 0;
05318 
05319                         while (i < NUM_FORCE_POWERS)
05320                         {
05321                                 self->client->ps.fd.forcePowerBaseLevel[i] = self->client->ps.fd.forcePowerLevel[i];
05322 
05323                                 if (!forcePowerDarkLight[i] ||
05324                                         self->client->ps.fd.forceSide == forcePowerDarkLight[i])
05325                                 {
05326                                         self->client->ps.fd.forcePowerLevel[i] = FORCE_LEVEL_3;
05327                                         self->client->ps.fd.forcePowersKnown |= (1 << i);
05328                                 }
05329 
05330                                 i++;
05331                         }
05332 
05333                         self->client->ps.fd.forceUsingAdded = 1;
05334                 }
05335         }
05336         else if (self->client->ps.fd.forceUsingAdded)
05337         { //we don't have enlightenment but we're still using enlightened powers, so clear them back to how they should be.
05338                 i = 0;
05339 
05340                 while (i < NUM_FORCE_POWERS)
05341                 {
05342                         self->client->ps.fd.forcePowerLevel[i] = self->client->ps.fd.forcePowerBaseLevel[i];
05343                         if (!self->client->ps.fd.forcePowerLevel[i])
05344                         {
05345                                 if (self->client->ps.fd.forcePowersActive & (1 << i))
05346                                 {
05347                                         WP_ForcePowerStop(self, i);
05348                                 }
05349                                 self->client->ps.fd.forcePowersKnown &= ~(1 << i);
05350                         }
05351 
05352                         i++;
05353                 }
05354 
05355                 self->client->ps.fd.forceUsingAdded = 0;
05356         }
05357 
05358         i = 0;
05359 
05360         if (!(self->client->ps.fd.forcePowersActive & (1 << FP_TELEPATHY)))
05361         { //clear the mindtrick index values
05362                 self->client->ps.fd.forceMindtrickTargetIndex = 0;
05363                 self->client->ps.fd.forceMindtrickTargetIndex2 = 0;
05364                 self->client->ps.fd.forceMindtrickTargetIndex3 = 0;
05365                 self->client->ps.fd.forceMindtrickTargetIndex4 = 0;
05366         }
05367         
05368         if (self->health < 1)
05369         {
05370                 self->client->ps.fd.forceGripBeingGripped = 0;
05371         }
05372 
05373         if (self->client->ps.fd.forceGripBeingGripped > level.time)
05374         {
05375                 self->client->ps.fd.forceGripCripple = 1;
05376 
05377                 //keep the saber off during this period
05378                 if (self->client->ps.weapon == WP_SABER && !self->client->ps.saberHolstered)
05379                 {
05380                         Cmd_ToggleSaber_f(self);
05381                 }
05382         }
05383         else
05384         {
05385                 self->client->ps.fd.forceGripCripple = 0;
05386         }
05387 
05388         if (self->client->ps.fd.forceJumpSound)
05389         {
05390                 G_PreDefSound(self->client->ps.origin, PDSOUND_FORCEJUMP);
05391                 self->client->ps.fd.forceJumpSound = 0;
05392         }
05393 
05394         if (self->client->ps.fd.forceGripCripple)
05395         {
05396                 if (self->client->ps.fd.forceGripSoundTime < level.time)
05397                 {
05398                         G_PreDefSound(self->client->ps.origin, PDSOUND_FORCEGRIP);
05399                         self->client->ps.fd.forceGripSoundTime = level.time + 1000;
05400                 }
05401         }
05402 
05403         if (self->client->ps.fd.forcePowersActive & (1 << FP_SPEED))
05404         {
05405                 self->client->ps.powerups[PW_SPEED] = level.time + 100;
05406         }
05407 
05408         if ( self->health <= 0 )
05409         {//if dead, deactivate any active force powers
05410                 for ( i = 0; i < NUM_FORCE_POWERS; i++ )
05411                 {
05412                         if ( self->client->ps.fd.forcePowerDuration[i] || (self->client->ps.fd.forcePowersActive&( 1 << i )) )
05413                         {
05414                                 WP_ForcePowerStop( self, (forcePowers_t)i );
05415                                 self->client->ps.fd.forcePowerDuration[i] = 0;
05416                         }
05417                 }
05418                 goto powersetcheck;
05419         }
05420 
05421         if (self->client->ps.groundEntityNum != ENTITYNUM_NONE)
05422         {
05423                 self->client->fjDidJump = qfalse;
05424         }
05425 
05426         if (self->client->ps.fd.forceJumpCharge && self->client->ps.groundEntityNum == ENTITYNUM_NONE && self->client->fjDidJump)
05427         { //this was for the "charge" jump method... I guess
05428                 if (ucmd->upmove < 10 && (!(ucmd->buttons & BUTTON_FORCEPOWER) || self->client->ps.fd.forcePowerSelected != FP_LEVITATION))
05429                 {
05430                         G_MuteSound(self->client->ps.fd.killSoundEntIndex[TRACK_CHANNEL_1-50], CHAN_VOICE);
05431                         self->client->ps.fd.forceJumpCharge = 0;
05432                 }
05433         }
05434 
05435 #ifndef METROID_JUMP
05436         else if ( (ucmd->upmove > 10) && (self->client->ps.pm_flags & PMF_JUMP_HELD) && self->client->ps.groundTime && (level.time - self->client->ps.groundTime) > 150 && !BG_HasYsalamiri(g_gametype.integer, &self->client->ps) && BG_CanUseFPNow(g_gametype.integer, &self->client->ps, level.time, FP_LEVITATION) )
05437         {//just charging up
05438                 ForceJumpCharge( self, ucmd );
05439                 usingForce = qtrue;
05440         }
05441         else if (ucmd->upmove < 10 && self->client->ps.groundEntityNum == ENTITYNUM_NONE && self->client->ps.fd.forceJumpCharge)
05442         {
05443                 self->client->ps.pm_flags &= ~(PMF_JUMP_HELD);
05444         }
05445 #endif
05446 
05447         if (!(self->client->ps.pm_flags & PMF_JUMP_HELD) && self->client->ps.fd.forceJumpCharge)
05448         {
05449                 if (!(ucmd->buttons & BUTTON_FORCEPOWER) ||
05450                         self->client->ps.fd.forcePowerSelected != FP_LEVITATION)
05451                 {
05452                         if (WP_DoSpecificPower( self, ucmd, FP_LEVITATION ))
05453                         {
05454                                 usingForce = qtrue;
05455                         }
05456                 }
05457         }
05458 
05459         if ( ucmd->buttons & BUTTON_FORCEGRIP )
05460         { //grip is one of the powers with its own button.. if it's held, call the specific grip power function.
05461                 if (WP_DoSpecificPower( self, ucmd, FP_GRIP ))
05462                 {
05463                         usingForce = qtrue;
05464                 }
05465                 else
05466                 { //don't let recharge even if the grip misses if the player still has the button down
05467                         usingForce = qtrue;
05468                 }
05469         }
05470         else
05471         { //see if we're using it generically.. if not, stop.
05472                 if (self->client->ps.fd.forcePowersActive & (1 << FP_GRIP))
05473                 {
05474                         if (!(ucmd->buttons & BUTTON_FORCEPOWER) || self->client->ps.fd.forcePowerSelected != FP_GRIP)
05475                         {
05476                                 WP_ForcePowerStop(self, FP_GRIP);
05477                         }
05478                 }
05479         }
05480 
05481         if ( ucmd->buttons & BUTTON_FORCE_LIGHTNING )
05482         { //lightning
05483                 WP_DoSpecificPower(self, ucmd, FP_LIGHTNING);
05484                 usingForce = qtrue;
05485         }
05486         else
05487         { //see if we're using it generically.. if not, stop.
05488                 if (self->client->ps.fd.forcePowersActive & (1 << FP_LIGHTNING))
05489                 {
05490                         if (!(ucmd->buttons & BUTTON_FORCEPOWER) || self->client->ps.fd.forcePowerSelected != FP_LIGHTNING)
05491                         {
05492                                 WP_ForcePowerStop(self, FP_LIGHTNING);
05493                         }
05494                 }
05495         }
05496 
05497         if ( ucmd->buttons & BUTTON_FORCE_DRAIN )
05498         { //drain
05499                 WP_DoSpecificPower(self, ucmd, FP_DRAIN);
05500                 usingForce = qtrue;
05501         }
05502         else
05503         { //see if we're using it generically.. if not, stop.
05504                 if (self->client->ps.fd.forcePowersActive & (1 << FP_DRAIN))
05505                 {
05506                         if (!(ucmd->buttons & BUTTON_FORCEPOWER) || self->client->ps.fd.forcePowerSelected != FP_DRAIN)
05507                         {
05508                                 WP_ForcePowerStop(self, FP_DRAIN);
05509                         }
05510                 }
05511         }
05512 
05513         if ( (ucmd->buttons & BUTTON_FORCEPOWER) &&
05514                 BG_CanUseFPNow(g_gametype.integer, &self->client->ps, level.time, self->client->ps.fd.forcePowerSelected))
05515         {
05516                 if (self->client->ps.fd.forcePowerSelected == FP_LEVITATION)
05517                 {
05518                         ForceJumpCharge( self, ucmd );
05519                         usingForce = qtrue;
05520                 }
05521                 else if (WP_DoSpecificPower( self, ucmd, self->client->ps.fd.forcePowerSelected ))
05522                 {
05523                         usingForce = qtrue;
05524                 }
05525                 else if (self->client->ps.fd.forcePowerSelected == FP_GRIP)
05526                 {
05527                         usingForce = qtrue;
05528                 }
05529         }
05530         else
05531         {
05532                 self->client->ps.fd.forceButtonNeedRelease = 0;
05533         }
05534 
05535         for ( i = 0; i < NUM_FORCE_POWERS; i++ )
05536         {
05537                 if ( self->client->ps.fd.forcePowerDuration[i] )
05538                 {
05539                         if ( self->client->ps.fd.forcePowerDuration[i] < level.time )
05540                         {
05541                                 if ( (self->client->ps.fd.forcePowersActive&( 1 << i )) )
05542                                 {//turn it off
05543                                         WP_ForcePowerStop( self, (forcePowers_t)i );
05544                                 }
05545                                 self->client->ps.fd.forcePowerDuration[i] = 0;
05546                         }
05547                 }
05548                 if ( (self->client->ps.fd.forcePowersActive&( 1 << i )) )
05549                 {
05550                         usingForce = qtrue;
05551                         WP_ForcePowerRun( self, (forcePowers_t)i, ucmd );
05552                 }
05553         }
05554         if ( self->client->ps.saberInFlight && self->client->ps.saberEntityNum )
05555         {//don't regen force power while throwing saber
05556                 if ( self->client->ps.saberEntityNum < ENTITYNUM_NONE && self->client->ps.saberEntityNum > 0 )//player is 0
05557                 {//
05558                         if ( &g_entities[self->client->ps.saberEntityNum] != NULL && g_entities[self->client->ps.saberEntityNum].s.pos.trType == TR_LINEAR )
05559                         {//fell to the ground and we're trying to pull it back
05560                                 usingForce = qtrue;
05561                         }
05562                 }
05563         }
05564         if ( !self->client->ps.fd.forcePowersActive || self->client->ps.fd.forcePowersActive == (1 << FP_DRAIN) )
05565         {//when not using the force, regenerate at 1 point per half second
05566                 if ( !self->client->ps.saberInFlight && self->client->ps.fd.forcePowerRegenDebounceTime < level.time &&
05567                         (self->client->ps.weapon != WP_SABER || !BG_SaberInSpecial(self->client->ps.saberMove)) )
05568                 {
05569                         if (g_gametype.integer != GT_HOLOCRON || g_MaxHolocronCarry.value)
05570                         {
05571                                 //if (!g_trueJedi.integer || self->client->ps.weapon == WP_SABER)
05572                                 //let non-jedi force regen since we're doing a more strict jedi/non-jedi thing... this gives dark jedi something to drain
05573                                 {
05574                                         if (self->client->ps.powerups[PW_FORCE_BOON])
05575                                         {
05576                                                 WP_ForcePowerRegenerate( self, 6 );
05577                                         }
05578                                         else if (self->client->ps.isJediMaster && g_gametype.integer == GT_JEDIMASTER)
05579                                         {
05580                                                 WP_ForcePowerRegenerate( self, 4 ); //jedi master regenerates 4 times as fast
05581                                         }
05582                                         else
05583                                         {
05584                                                 WP_ForcePowerRegenerate( self, 0 );
05585                                         }
05586                                 }
05587                                 /*
05588                                 else if (g_trueJedi.integer && self->client->ps.weapon != WP_SABER)
05589                                 {
05590                                         self->client->ps.fd.forcePower = 0;
05591                                 }
05592                                 */
05593                         }
05594                         else
05595                         { //regenerate based on the number of holocrons carried
05596                                 holoregen = 0;
05597                                 holo = 0;
05598                                 while (holo < NUM_FORCE_POWERS)
05599                                 {
05600                                         if (self->client->ps.holocronsCarried[holo])
05601                                         {
05602                                                 holoregen++;
05603                                         }
05604                                         holo++;
05605                                 }
05606 
05607                                 WP_ForcePowerRegenerate(self, holoregen);
05608                         }
05609 
05610                         if (g_gametype.integer == GT_SIEGE)
05611                         {
05612                                 if (self->client->holdingObjectiveItem &&
05613                                         g_entities[self->client->holdingObjectiveItem].inuse &&
05614                                         g_entities[self->client->holdingObjectiveItem].genericValue15)
05615                                 { //1 point per 7 seconds.. super slow
05616                                         self->client->ps.fd.forcePowerRegenDebounceTime = level.time + 7000;
05617                                 }
05618                                 else if (self->client->siegeClass != -1 &&
05619                                         (bgSiegeClasses[self->client->siegeClass].classflags & (1<<CFL_FASTFORCEREGEN)))
05620                                 { //if this is siege and our player class has the fast force regen ability, then recharge with 1/5th the usual delay
05621                                         self->client->ps.fd.forcePowerRegenDebounceTime = level.time + (g_forceRegenTime.integer*0.2);
05622                                 }
05623                                 else
05624                                 {
05625                                         self->client->ps.fd.forcePowerRegenDebounceTime = level.time + g_forceRegenTime.integer;
05626                                 }
05627                         }
05628                         else
05629                         {
05630                                 if ( g_gametype.integer == GT_POWERDUEL && self->client->sess.duelTeam == DUELTEAM_LONE )
05631                                 {
05632                                         if ( g_duel_fraglimit.integer )
05633                                         {
05634                                                 self->client->ps.fd.forcePowerRegenDebounceTime = level.time + (g_forceRegenTime.integer*
05635                                                         (0.6 + (.3 * (float)self->client->sess.wins / (float)g_duel_fraglimit.integer)));
05636                                         }
05637                                         else
05638                                         {
05639                                                 self->client->ps.fd.forcePowerRegenDebounceTime = level.time + (g_forceRegenTime.integer*0.7);
05640                                         }
05641                                 }
05642                                 else
05643                                 {
05644                                         self->client->ps.fd.forcePowerRegenDebounceTime = level.time + g_forceRegenTime.integer;
05645                                 }
05646                         }
05647                 }
05648         }
05649 
05650 powersetcheck:
05651 
05652         if (prepower && self->client->ps.fd.forcePower < prepower)
05653         {
05654                 int dif = ((prepower - self->client->ps.fd.forcePower)/2);
05655                 if (dif < 1)
05656                 {
05657                         dif = 1;
05658                 }
05659 
05660                 self->client->ps.fd.forcePower = (prepower-dif);
05661         }
05662 }

qboolean WP_ForcePowerUsable gentity_t self,
forcePowers_t  forcePower
 

Definition at line 813 of file w_force.c.

References BG_CanUseFPNow(), BG_HasYsalamiri(), gentity_s::client, EF_DEAD, playerState_s::eFlags, playerState_s::fd, gclient_s::fjDidJump, forcedata_s::forcePowerLevel, forcePowers_t, forcedata_s::forcePowersActive, forcedata_s::forcePowersKnown, saberInfo_t::forceRestrictions, FP_DRAIN, FP_GRIP, FP_LEVITATION, FP_LIGHTNING, FP_PULL, FP_PUSH, FP_SABER_DEFENSE, FP_SABER_OFFENSE, FP_SABERTHROW, FP_TELEPATHY, g_debugMelee, g_gametype, g_saberRestrictForce, gentity_t, gentity_s::health, vmCvar_t::integer, level, saberInfo_t::model, playerState_s::pm_flags, PMF_FOLLOW, PMF_STUCK_TO_WALL, gclient_s::ps, qboolean, qfalse, gclient_s::saber, saberInfo_t::saberFlags, playerState_s::saberHolstered, gclient_s::sess, clientSession_t::sessionTeam, SFL_TWO_HANDED, STAT_HEALTH, playerState_s::stats, TEAM_SPECTATOR, gclient_s::tempSpectate, level_locals_t::time, and WP_ForcePowerAvailable().

Referenced by CanCounterThrow(), ForceAbsorb(), ForceDrain(), ForceGrip(), ForceHeal(), ForceJump(), ForceLightning(), ForceProtect(), ForceRage(), ForceSeeing(), ForceSpeed(), ForceTeamForceReplenish(), ForceTeamHeal(), ForceTelepathy(), ForceThrow(), Jedi_DodgeEvasion(), and WP_SaberStartMissileBlockCheck().

00814 {
00815         if (BG_HasYsalamiri(g_gametype.integer, &self->client->ps))
00816         {
00817                 return qfalse;
00818         }
00819 
00820         if (self->health <= 0 || self->client->ps.stats[STAT_HEALTH] <= 0 ||
00821                 (self->client->ps.eFlags & EF_DEAD))
00822         {
00823                 return qfalse;
00824         }
00825 
00826         if (self->client->ps.pm_flags & PMF_FOLLOW)
00827         { //specs can't use powers through people
00828                 return qfalse;
00829         }
00830         if (self->client->sess.sessionTeam == TEAM_SPECTATOR)
00831         {
00832                 return qfalse;
00833         }
00834         if (self->client->tempSpectate >= level.time)
00835         {
00836                 return qfalse;
00837         }
00838 
00839         if (!BG_CanUseFPNow(g_gametype.integer, &self->client->ps, level.time, forcePower))
00840         {
00841                 return qfalse;
00842         }
00843 
00844         if ( !(self->client->ps.fd.forcePowersKnown & ( 1 << forcePower )) )
00845         {//don't know this power
00846                 return qfalse;
00847         }
00848         
00849         if ( (self->client->ps.fd.forcePowersActive & ( 1 << forcePower )) )
00850         {//already using this power
00851                 if (forcePower != FP_LEVITATION)
00852                 {
00853                         return qfalse;
00854                 }
00855         }
00856 
00857         if (forcePower == FP_LEVITATION && self->client->fjDidJump)
00858         {
00859                 return qfalse;
00860         }
00861 
00862         if (!self->client->ps.fd.forcePowerLevel[forcePower])
00863         {
00864                 return qfalse;
00865         }
00866 
00867         if ( g_debugMelee.integer )
00868         {
00869                 if ( (self->client->ps.pm_flags&PMF_STUCK_TO_WALL) )
00870                 {//no offensive force powers when stuck to wall
00871                         switch ( forcePower )
00872                         {
00873                         case FP_GRIP:
00874                         case FP_LIGHTNING:
00875                         case FP_DRAIN:
00876                         case FP_SABER_OFFENSE:
00877                         case FP_SABER_DEFENSE:
00878                         case FP_SABERTHROW:
00879                                 return qfalse;
00880                                 break;
00881                         }
00882                 }
00883         }
00884 
00885         if ( !self->client->ps.saberHolstered )
00886         {
00887                 if ( (self->client->saber[0].saberFlags&SFL_TWO_HANDED) )
00888                 {
00889                         if ( g_saberRestrictForce.integer )
00890                         {
00891                                 switch ( forcePower )
00892                                 {
00893                                 case FP_PUSH:
00894                                 case FP_PULL:
00895                                 case FP_TELEPATHY:
00896                                 case FP_GRIP:
00897                                 case FP_LIGHTNING:
00898                                 case FP_DRAIN:
00899                                         return qfalse;
00900                                         break;
00901                                 }
00902                         }
00903                 }
00904 
00905                 if ( (self->client->saber[0].saberFlags&SFL_TWO_HANDED)
00906                         || (self->client->saber[0].model && self->client->saber[0].model[0]) )
00907                 {//this saber requires the use of two hands OR our other hand is using an active saber too
00908                         if ( (self->client->saber[0].forceRestrictions&(1<<forcePower)) )
00909                         {//this power is verboten when using this saber
00910                                 return qfalse;
00911                         }
00912                 }
00913 
00914                 if ( self->client->saber[0].model 
00915                         && self->client->saber[0].model[0] )
00916                 {//both sabers on
00917                         if ( g_saberRestrictForce.integer )
00918                         {
00919                                 switch ( forcePower )
00920                                 {
00921                                 case FP_PUSH:
00922                                 case FP_PULL:
00923                                 case FP_TELEPATHY:
00924                                 case FP_GRIP:
00925                                 case FP_LIGHTNING:
00926                                 case FP_DRAIN:
00927                                         return qfalse;
00928                                         break;
00929                                 }
00930                         }
00931                         if ( (self->client->saber[1].forceRestrictions&(1<<forcePower)) )
00932                         {//this power is verboten when using this saber
00933                                 return qfalse;
00934                         }
00935                 }
00936         }
00937         return WP_ForcePowerAvailable( self, forcePower, 0 );   // OVERRIDEFIXME
00938 }

int WP_GetVelocityForForceJump gentity_t self,
vec3_t  jumpVel,
usercmd_t ucmd
 

Definition at line 2377 of file w_force.c.

References AngleVectors(), CHAN_VOICE, gentity_s::client, playerState_s::fd, FJ_BACKWARD, FJ_FORWARD, FJ_LEFT, FJ_RIGHT, FJ_UP, forcedata_s::forceJumpCharge, usercmd_s::forwardmove, G_MuteSound(), G_PreDefSound(), gentity_t, JUMP_VELOCITY, forcedata_s::killSoundEntIndex, NULL, playerState_s::origin, PDSOUND_FORCEJUMP, gclient_s::ps, usercmd_s::rightmove, TRACK_CHANNEL_1, ucmd, usercmd_t, vec3_t, VectorCopy, VectorMA, playerState_s::velocity, and playerState_s::viewangles.

Referenced by ForceJump().

02378 {
02379         float pushFwd = 0, pushRt = 0;
02380         vec3_t  view, forward, right;
02381         VectorCopy( self->client->ps.viewangles, view );
02382         view[0] = 0;
02383         AngleVectors( view, forward, right, NULL );
02384         if ( ucmd->forwardmove && ucmd->rightmove )
02385         {
02386                 if ( ucmd->forwardmove > 0 )
02387                 {
02388                         pushFwd = 50;
02389                 }
02390                 else
02391                 {
02392                         pushFwd = -50;
02393                 }
02394                 if ( ucmd->rightmove > 0 )
02395                 {
02396                         pushRt = 50;
02397                 }
02398                 else
02399                 {
02400                         pushRt = -50;
02401                 }
02402         }
02403         else if ( ucmd->forwardmove || ucmd->rightmove )
02404         {
02405                 if ( ucmd->forwardmove > 0 )
02406                 {
02407                         pushFwd = 100;
02408                 }
02409                 else if ( ucmd->forwardmove < 0 )
02410                 {
02411                         pushFwd = -100;
02412                 }
02413                 else if ( ucmd->rightmove > 0 )
02414                 {
02415                         pushRt = 100;
02416                 }
02417                 else if ( ucmd->rightmove < 0 )
02418                 {
02419                         pushRt = -100;
02420                 }
02421         }
02422 
02423         G_MuteSound(self->client->ps.fd.killSoundEntIndex[TRACK_CHANNEL_1-50], CHAN_VOICE);
02424 
02425         G_PreDefSound(self->client->ps.origin, PDSOUND_FORCEJUMP);
02426 
02427         if (self->client->ps.fd.forceJumpCharge < JUMP_VELOCITY+40)
02428         { //give him at least a tiny boost from just a tap
02429                 self->client->ps.fd.forceJumpCharge = JUMP_VELOCITY+400;
02430         }
02431 
02432         if (self->client->ps.velocity[2] < -30)
02433         { //so that we can get a good boost when force jumping in a fall
02434                 self->client->ps.velocity[2] = -30;
02435         }
02436 
02437         VectorMA( self->client->ps.velocity, pushFwd, forward, jumpVel );
02438         VectorMA( self->client->ps.velocity, pushRt, right, jumpVel );
02439         jumpVel[2] += self->client->ps.fd.forceJumpCharge;
02440         if ( pushFwd > 0 && self->client->ps.fd.forceJumpCharge > 200 )
02441         {
02442                 return FJ_FORWARD;
02443         }
02444         else if ( pushFwd < 0 && self->client->ps.fd.forceJumpCharge > 200 )
02445         {
02446                 return FJ_BACKWARD;
02447         }
02448         else if ( pushRt > 0 && self->client->ps.fd.forceJumpCharge > 200 )
02449         {
02450                 return FJ_RIGHT;
02451         }
02452         else if ( pushRt < 0 && self->client->ps.fd.forceJumpCharge > 200 )
02453         {
02454                 return FJ_LEFT;
02455         }
02456         else
02457         {
02458                 return FJ_UP;
02459         }
02460 }

qboolean WP_HasForcePowers const playerState_t ps  ) 
 

Definition at line 5004 of file w_force.c.

References playerState_s::fd, FORCE_LEVEL_0, FORCE_LEVEL_1, forcedata_s::forcePowerLevel, FP_LEVITATION, NUM_FORCE_POWERS, playerState_t, qboolean, qfalse, and qtrue.

Referenced by ClientSpawn().

05005 {
05006         int i;
05007         if ( ps )
05008         {
05009                 for ( i = 0; i < NUM_FORCE_POWERS; i++ )
05010                 {
05011                         if ( i == FP_LEVITATION )
05012                         {
05013                                 if ( ps->fd.forcePowerLevel[i] > FORCE_LEVEL_1 )
05014                                 {
05015                                         return qtrue;
05016                                 }
05017                         }
05018                         else if ( ps->fd.forcePowerLevel[i] > FORCE_LEVEL_0 )
05019                         {
05020                                 return qtrue;
05021                         }
05022                 }
05023         }
05024         return qfalse;
05025 }

void WP_InitForcePowers gentity_t ent  ) 
 

Definition at line 147 of file w_force.c.

References absorbLoopSound, atoi(), BG_LegalizedForcePowers(), bgSiegeClasses, entityState_s::bolt1, entityState_s::bolt2, botstates, gentity_s::client, Com_sprintf(), ET_NPC, entityState_s::eType, EV_GIVE_NEW_RANK, EV_SET_FORCE_DISABLE, EV_SET_FREE_SABER, entityState_s::eventParm, playerState_s::fd, FORCE_DARKSIDE, FORCE_LEVEL_1, FORCE_LEVEL_3, FORCE_LIGHTSIDE, FORCE_MASTERY_JEDI_MASTER, forcedata_s::forcePowerBaseLevel, forcedata_s::forcePowerLevel, forcedata_s::forcePowerSelected, forcedata_s::forcePowersKnown, forcedata_s::forceRank, forcedata_s::forceSide, forcedata_s::forceUsingAdded, FP_ABSORB, FP_DRAIN, FP_GRIP, FP_HEAL, FP_LEVITATION, FP_LIGHTNING, FP_PROTECT, FP_PULL, FP_PUSH, FP_RAGE, FP_SABER_DEFENSE, FP_SABER_OFFENSE, FP_SABERTHROW, g_entities, g_forceBasedTeams, g_forcePowerDisable, g_gametype, g_maxForceRank, G_SoundIndex(), g_teamAutoJoin, G_TempEntity(), gentity_t, GT_HOLOCRON, GT_JEDIMASTER, GT_SIEGE, HasSetSaberOnly(), Info_ValueForKey(), vmCvar_t::integer, MAX_CLIENTS, MAX_INFO_STRING, NUM_FORCE_MASTERY_LEVELS, NUM_FORCE_POWERS, entityState_s::number, gclient_s::pers, protectLoopSound, gclient_s::ps, Q_strncpyz(), qboolean, qfalse, qtrue, gentity_s::r, rageLoopSound, gentity_s::s, forcedata_s::saberAnimLevel, clientSession_t::saberLevel, seeLoopSound, clientSession_t::selectedFP, gclient_s::sess, clientSession_t::sessionTeam, clientSession_t::setForce, gclient_s::siegeClass, SPECTATOR_FREE, clientSession_t::spectatorClient, clientSession_t::spectatorState, speedLoopSound, playerTeamState_t::state, strcpy(), SVF_BOT, SVF_BROADCAST, entityShared_t::svFlags, TEAM_BEGIN, TEAM_BLUE, TEAM_RED, TEAM_SPECTATOR, clientPersistant_t::teamState, trap_Cvar_Set(), trap_GetUserinfo(), trap_SendServerCommand(), entityState_s::trickedentindex, va(), vec3_origin, and ysalamiriLoopSound.

Referenced by ClientBegin(), ClientSpawn(), Cmd_ForceChanged_f(), and NPC_SetMiscDefaultData().

00148 {
00149         int i;
00150         int i_r;
00151         int maxRank = g_maxForceRank.integer;
00152         qboolean warnClient = qfalse;
00153         qboolean warnClientLimit = qfalse;
00154         char userinfo[MAX_INFO_STRING];
00155         char forcePowers[256];
00156         char readBuf[256];
00157         int lastFPKnown = -1;
00158         qboolean didEvent = qfalse;
00159 
00160         if (!maxRank)
00161         { //if server has no max rank, default to max (50)
00162                 maxRank = FORCE_MASTERY_JEDI_MASTER;
00163         }
00164         else if (maxRank >= NUM_FORCE_MASTERY_LEVELS)
00165         {//ack, prevent user from being dumb
00166                 maxRank = FORCE_MASTERY_JEDI_MASTER;
00167                 trap_Cvar_Set( "g_maxForceRank", va("%i", maxRank) );
00168         }
00169 
00170         /*
00171         if (g_forcePowerDisable.integer)
00172         {
00173                 maxRank = FORCE_MASTERY_UNINITIATED;
00174         }
00175         */
00176         //rww - don't do this
00177 
00178         if ( !ent || !ent->client )
00179         {
00180                 return;
00181         }
00182 
00183         ent->client->ps.fd.saberAnimLevel = ent->client->sess.saberLevel;
00184 
00185         if (ent->client->ps.fd.saberAnimLevel < FORCE_LEVEL_1 ||
00186                 ent->client->ps.fd.saberAnimLevel > FORCE_LEVEL_3)
00187         {
00188                 ent->client->ps.fd.saberAnimLevel = FORCE_LEVEL_1;
00189         }
00190 
00191         if (!speedLoopSound)
00192         { //so that the client configstring is already modified with this when we need it
00193                 speedLoopSound = G_SoundIndex("sound/weapons/force/speedloop.wav");
00194         }
00195 
00196         if (!rageLoopSound)
00197         {
00198                 rageLoopSound = G_SoundIndex("sound/weapons/force/rageloop.wav");
00199         }
00200 
00201         if (!absorbLoopSound)
00202         {
00203                 absorbLoopSound = G_SoundIndex("sound/weapons/force/absorbloop.wav");
00204         }
00205 
00206         if (!protectLoopSound)
00207         {
00208                 protectLoopSound = G_SoundIndex("sound/weapons/force/protectloop.wav");
00209         }
00210 
00211         if (!seeLoopSound)
00212         {
00213                 seeLoopSound = G_SoundIndex("sound/weapons/force/seeloop.wav");
00214         }
00215 
00216         if (!ysalamiriLoopSound)
00217         {
00218                 ysalamiriLoopSound = G_SoundIndex("sound/player/nullifyloop.wav");
00219         }
00220 
00221         if (ent->s.eType == ET_NPC)
00222         { //just stop here then.
00223                 return;
00224         }
00225 
00226         i = 0;
00227         while (i < NUM_FORCE_POWERS)
00228         {
00229                 ent->client->ps.fd.forcePowerLevel[i] = 0;
00230                 ent->client->ps.fd.forcePowersKnown &= ~(1 << i);
00231                 i++;
00232         }
00233 
00234         ent->client->ps.fd.forcePowerSelected = -1;
00235 
00236         ent->client->ps.fd.forceSide = 0;
00237 
00238         if (g_gametype.integer == GT_SIEGE &&
00239                 ent->client->siegeClass != -1)
00240         { //Then use the powers for this class, and skip all this nonsense.
00241                 i = 0;
00242 
00243                 while (i < NUM_FORCE_POWERS)
00244                 {
00245                         ent->client->ps.fd.forcePowerLevel[i] = bgSiegeClasses[ent->client->siegeClass].forcePowerLevels[i];
00246 
00247                         if (!ent->client->ps.fd.forcePowerLevel[i])
00248                         {
00249                                 ent->client->ps.fd.forcePowersKnown &= ~(1 << i);
00250                         }
00251                         else
00252                         {
00253                                 ent->client->ps.fd.forcePowersKnown |= (1 << i);
00254                         }
00255                         i++;
00256                 }
00257 
00258                 if (!ent->client->sess.setForce)
00259                 {
00260                         //bring up the class selection menu
00261                         trap_SendServerCommand(ent-g_entities, "scl");
00262                 }
00263                 ent->client->sess.setForce = qtrue;
00264 
00265                 return;
00266         }
00267 
00268         if (ent->s.eType == ET_NPC && ent->s.number >= MAX_CLIENTS)
00269         { //rwwFIXMEFIXME: Temp
00270                 strcpy(userinfo, "forcepowers\\7-1-333003000313003120");
00271         }
00272         else
00273         {
00274                 trap_GetUserinfo( ent->s.number, userinfo, sizeof( userinfo ) );
00275         }
00276 
00277         Q_strncpyz( forcePowers, Info_ValueForKey (userinfo, "forcepowers"), sizeof( forcePowers ) );
00278 
00279         if ( (ent->r.svFlags & SVF_BOT) && botstates[ent->s.number] )
00280         { //if it's a bot just copy the info directly from its personality
00281                 Com_sprintf(forcePowers, sizeof(forcePowers), "%s\0", botstates[ent->s.number]->forceinfo);
00282         }
00283 
00284         //rww - parse through the string manually and eat out all the appropriate data
00285         i = 0;
00286 
00287         if (g_forceBasedTeams.integer)
00288         {
00289                 if (ent->client->sess.sessionTeam == TEAM_RED)
00290                 {
00291                         warnClient = !(BG_LegalizedForcePowers(forcePowers, maxRank, HasSetSaberOnly(), FORCE_DARKSIDE, g_gametype.integer, g_forcePowerDisable.integer));
00292                 }
00293                 else if (ent->client->sess.sessionTeam == TEAM_BLUE)
00294                 {
00295                         warnClient = !(BG_LegalizedForcePowers(forcePowers, maxRank, HasSetSaberOnly(), FORCE_LIGHTSIDE, g_gametype.integer, g_forcePowerDisable.integer));
00296                 }
00297                 else
00298                 {
00299                         warnClient = !(BG_LegalizedForcePowers(forcePowers, maxRank, HasSetSaberOnly(), 0, g_gametype.integer, g_forcePowerDisable.integer));
00300                 }
00301         }
00302         else
00303         {
00304                 warnClient = !(BG_LegalizedForcePowers(forcePowers, maxRank, HasSetSaberOnly(), 0, g_gametype.integer, g_forcePowerDisable.integer));
00305         }
00306 
00307         i_r = 0;
00308         while (forcePowers[i] && forcePowers[i] != '-')
00309         {
00310                 readBuf[i_r] = forcePowers[i];
00311                 i_r++;
00312                 i++;
00313         }
00314         readBuf[i_r] = 0;
00315         //THE RANK
00316         ent->client->ps.fd.forceRank = atoi(readBuf);
00317         i++;
00318 
00319         i_r = 0;
00320         while (forcePowers[i] && forcePowers[i] != '-')
00321         {
00322                 readBuf[i_r] = forcePowers[i];
00323                 i_r++;
00324                 i++;
00325         }
00326         readBuf[i_r] = 0;
00327         //THE SIDE
00328         ent->client->ps.fd.forceSide = atoi(readBuf);
00329         i++;
00330 
00331 
00332         if ( g_gametype.integer != GT_SIEGE && (ent->r.svFlags & SVF_BOT) && botstates[ent->s.number] )
00333         { //hmm..I'm going to cheat here.
00334                 int oldI = i;
00335                 i_r = 0;
00336                 while (forcePowers[i] && forcePowers[i] != '\n' &&
00337                         i_r < NUM_FORCE_POWERS)
00338                 {
00339                         if (ent->client->ps.fd.forceSide == FORCE_LIGHTSIDE)
00340                         {
00341                                 if (i_r == FP_ABSORB)
00342                                 {
00343                                         forcePowers[i] = '3';
00344                                 }
00345                                 if (botstates[ent->s.number]->settings.skill >= 4)
00346                                 { //cheat and give them more stuff
00347                                         if (i_r == FP_HEAL)
00348                                         {
00349                                                 forcePowers[i] = '3';
00350                                         }
00351                                         else if (i_r == FP_PROTECT)
00352                                         {
00353                                                 forcePowers[i] = '3';
00354                                         }
00355                                 }
00356                         }
00357                         else if (ent->client->ps.fd.forceSide == FORCE_DARKSIDE)
00358                         {
00359                                 if (botstates[ent->s.number]->settings.skill >= 4)
00360                                 {
00361                                         if (i_r == FP_GRIP)
00362                                         {
00363                                                 forcePowers[i] = '3';
00364                                         }
00365                                         else if (i_r == FP_LIGHTNING)
00366                                         {
00367                                                 forcePowers[i] = '3';
00368                                         }
00369                                         else if (i_r == FP_RAGE)
00370                                         {
00371                                                 forcePowers[i] = '3';
00372                                         }
00373                                         else if (i_r == FP_DRAIN)
00374                                         {
00375                                                 forcePowers[i] = '3';
00376                                         }
00377                                 }
00378                         }
00379 
00380                         if (i_r == FP_PUSH)
00381                         {
00382                                 forcePowers[i] = '3';
00383                         }
00384                         else if (i_r == FP_PULL)
00385                         {
00386                                 forcePowers[i] = '3';
00387                         }
00388 
00389                         i++;
00390                         i_r++;
00391                 }
00392                 i = oldI;
00393         }
00394 
00395         i_r = 0;
00396         while (forcePowers[i] && forcePowers[i] != '\n' &&
00397                 i_r < NUM_FORCE_POWERS)
00398         {
00399                 readBuf[0] = forcePowers[i];
00400                 readBuf[1] = 0;
00401 
00402                 ent->client->ps.fd.forcePowerLevel[i_r] = atoi(readBuf);
00403                 if (ent->client->ps.fd.forcePowerLevel[i_r])
00404                 {
00405                         ent->client->ps.fd.forcePowersKnown |= (1 << i_r);
00406                 }
00407                 else
00408                 {
00409                         ent->client->ps.fd.forcePowersKnown &= ~(1 << i_r);
00410                 }
00411                 i++;
00412                 i_r++;
00413         }
00414         //THE POWERS
00415 
00416         if (ent->s.eType != ET_NPC)
00417         {
00418                 if (HasSetSaberOnly())
00419                 {
00420                         gentity_t *te = G_TempEntity( vec3_origin, EV_SET_FREE_SABER );
00421                         te->r.svFlags |= SVF_BROADCAST;
00422                         te->s.eventParm = 1;
00423                 }
00424                 else
00425                 {
00426                         gentity_t *te = G_TempEntity( vec3_origin, EV_SET_FREE_SABER );
00427                         te->r.svFlags |= SVF_BROADCAST;
00428                         te->s.eventParm = 0;
00429                 }
00430 
00431                 if (g_forcePowerDisable.integer)
00432                 {
00433                         gentity_t *te = G_TempEntity( vec3_origin, EV_SET_FORCE_DISABLE );
00434                         te->r.svFlags |= SVF_BROADCAST;
00435                         te->s.eventParm = 1;
00436                 }
00437                 else
00438                 {
00439                         gentity_t *te = G_TempEntity( vec3_origin, EV_SET_FORCE_DISABLE );
00440                         te->r.svFlags |= SVF_BROADCAST;
00441                         te->s.eventParm = 0;
00442                 }
00443         }
00444 
00445         //rww - It seems we currently want to always do this, even if the player isn't exceeding the max
00446         //rank, so..
00447 //      if (g_gametype.integer == GT_DUEL || g_gametype.integer == GT_POWERDUEL)
00448 //      { //totally messes duel up to force someone into spec mode, and besides, each "round" is
00449           //counted as a full restart
00450 //              ent->client->sess.setForce = qtrue;
00451 //      }
00452 
00453         if (ent->s.eType == ET_NPC)
00454         {
00455                 ent->client->sess.setForce = qtrue;
00456         }
00457         else if (g_gametype.integer == GT_SIEGE)
00458         {
00459                 if (!ent->client->sess.setForce)
00460                 {
00461                         ent->client->sess.setForce = qtrue;
00462                         //bring up the class selection menu
00463                         trap_SendServerCommand(ent-g_entities, "scl");
00464                 }
00465         }
00466         else
00467         {
00468                 if (warnClient || !ent->client->sess.setForce)
00469                 { //the client's rank is too high for the server and has been autocapped, so tell them
00470                         if (g_gametype.integer != GT_HOLOCRON && g_gametype.integer != GT_JEDIMASTER )
00471                         {
00472 #ifdef EVENT_FORCE_RANK
00473                                 gentity_t *te = G_TempEntity( vec3_origin, EV_GIVE_NEW_RANK );
00474 
00475                                 te->r.svFlags |= SVF_BROADCAST;
00476                                 te->s.trickedentindex = ent->s.number;
00477                                 te->s.eventParm = maxRank;
00478                                 te->s.bolt1 = 0;
00479 #endif
00480                                 didEvent = qtrue;
00481 
00482 //                              if (!(ent->r.svFlags & SVF_BOT) && g_gametype.integer != GT_DUEL && g_gametype.integer != GT_POWERDUEL && ent->s.eType != ET_NPC)
00483                                 if (!(ent->r.svFlags & SVF_BOT) && ent->s.eType != ET_NPC)
00484                                 {
00485                                         if (!g_teamAutoJoin.integer)
00486                                         {
00487                                                 //Make them a spectator so they can set their powerups up without being bothered.
00488                                                 ent->client->sess.sessionTeam = TEAM_SPECTATOR;
00489                                                 ent->client->sess.spectatorState = SPECTATOR_FREE;
00490                                                 ent->client->sess.spectatorClient = 0;
00491 
00492                                                 ent->client->pers.teamState.state = TEAM_BEGIN;
00493                                                 trap_SendServerCommand(ent-g_entities, "spc");  // Fire up the profile menu
00494                                         }
00495                                 }
00496 
00497 #ifdef EVENT_FORCE_RANK
00498                                 te->s.bolt2 = ent->client->sess.sessionTeam;
00499 #else
00500                                 //Event isn't very reliable, I made it a string. This way I can send it to just one
00501                                 //client also, as opposed to making a broadcast event.
00502                                 trap_SendServerCommand(ent->s.number, va("nfr %i %i %i", maxRank, 1, ent->client->sess.sessionTeam));
00503                                 //Arg1 is new max rank, arg2 is non-0 if force menu should be shown, arg3 is the current team
00504 #endif
00505                         }
00506                         ent->client->sess.setForce = qtrue;
00507                 }
00508 
00509                 if (!didEvent )
00510                 {
00511 #ifdef EVENT_FORCE_RANK
00512                         gentity_t *te = G_TempEntity( vec3_origin, EV_GIVE_NEW_RANK );
00513 
00514                         te->r.svFlags |= SVF_BROADCAST;
00515                         te->s.trickedentindex = ent->s.number;
00516                         te->s.eventParm = maxRank;
00517                         te->s.bolt1 = 1;
00518                         te->s.bolt2 = ent->client->sess.sessionTeam;
00519 #else
00520                         trap_SendServerCommand(ent->s.number, va("nfr %i %i %i", maxRank, 0, ent->client->sess.sessionTeam));
00521 #endif
00522                 }
00523 
00524                 if (warnClientLimit)
00525                 { //the server has one or more force powers disabled and the client is using them in his config
00526                         //trap_SendServerCommand(ent-g_entities, va("print \"The server has one or more force powers that you have chosen disabled.\nYou will not be able to use the disable force power(s) while playing on this server.\n\""));
00527                 }
00528         }
00529 
00530         i = 0;
00531         while (i < NUM_FORCE_POWERS)
00532         {
00533                 if ((ent->client->ps.fd.forcePowersKnown & (1 << i)) &&
00534                         !ent->client->ps.fd.forcePowerLevel[i])
00535                 { //err..
00536                         ent->client->ps.fd.forcePowersKnown &= ~(1 << i);
00537                 }
00538                 else
00539                 {
00540                         if (i != FP_LEVITATION && i != FP_SABER_OFFENSE && i != FP_SABER_DEFENSE && i != FP_SABERTHROW)
00541                         {
00542                                 lastFPKnown = i;
00543                         }
00544                 }
00545 
00546                 i++;
00547         }
00548 
00549         if (ent->client->ps.fd.forcePowersKnown & ent->client->sess.selectedFP)
00550         {
00551                 ent->client->ps.fd.forcePowerSelected = ent->client->sess.selectedFP;
00552         }
00553 
00554         if (!(ent->client->ps.fd.forcePowersKnown & (1 << ent->client->ps.fd.forcePowerSelected)))
00555         {
00556                 if (lastFPKnown != -1)
00557                 {
00558                         ent->client->ps.fd.forcePowerSelected = lastFPKnown;
00559                 }
00560                 else
00561                 {
00562                         ent->client->ps.fd.forcePowerSelected = 0;
00563                 }
00564         }
00565 
00566         while (i < NUM_FORCE_POWERS)
00567         {
00568                 ent->client->ps.fd.forcePowerBaseLevel[i] = ent->client->ps.fd.forcePowerLevel[i];
00569                 i++;
00570         }
00571         ent->client->ps.fd.forceUsingAdded = 0;
00572 }

void WP_SpawnInitForcePowers gentity_t ent  ) 
 

Definition at line 574 of file w_force.c.

References bgSiegeClasses, gentity_s::client, ENTITYNUM_NONE, playerState_s::fd, FORCE_LEVEL_0, FORCE_LEVEL_1, FORCE_POWER_MAX, forcedata_s::forceDeactivateAll, forcedata_s::forceDrainEntNum, forcedata_s::forceDrainTime, forcedata_s::forceGripBeingGripped, forcedata_s::forceGripCripple, forcedata_s::forceGripDamageDebounceTime, forcedata_s::forceGripEntityNum, forcedata_s::forceGripSoundTime, forcedata_s::forceGripStarted, forcedata_s::forceGripUseTime, forcedata_s::forceHealAmount, forcedata_s::forceHealTime, forcedata_s::forceJumpCharge, forcedata_s::forceJumpSound, forcedata_s::forceJumpZStart, forcedata_s::forceMindtrickTargetIndex, forcedata_s::forceMindtrickTargetIndex2, forcedata_s::forceMindtrickTargetIndex3, forcedata_s::forceMindtrickTargetIndex4, forcedata_s::forcePower, forcedata_s::forcePowerDebounce, forcedata_s::forcePowerDuration, forcedata_s::forcePowerLevel, forcedata_s::forcePowerMax, forcedata_s::forcePowerRegenDebounceTime, forcedata_s::forcePowersActive, forcedata_s::forcePowersKnown, forcedata_s::forceRageRecoveryTime, FP_SABER_DEFENSE, FP_SABER_OFFENSE, g_gametype, gentity_t, GT_HOLOCRON, GT_SIEGE, HasSetSaberOnly(), playerState_s::holocronBits, playerState_s::holocronsCarried, vmCvar_t::integer, NUM_FORCE_POWERS, gclient_s::ps, playerState_s::saberAttackChainCount, gclient_s::siegeClass, and WP_ForcePowerStop().

Referenced by ClientSpawn(), and NPC_SetMiscDefaultData().

00575 {
00576         int i = 0;
00577 
00578         ent->client->ps.saberAttackChainCount = 0;
00579 
00580         i = 0;
00581 
00582         while (i < NUM_FORCE_POWERS)
00583         {
00584                 if (ent->client->ps.fd.forcePowersActive & (1 << i))
00585                 {
00586                         WP_ForcePowerStop(ent, i);
00587                 }
00588 
00589                 i++;
00590         }
00591 
00592         ent->client->ps.fd.forceDeactivateAll = 0;
00593 
00594         ent->client->ps.fd.forcePower = ent->client->ps.fd.forcePowerMax = FORCE_POWER_MAX;
00595         ent->client->ps.fd.forcePowerRegenDebounceTime = 0;
00596         ent->client->ps.fd.forceGripEntityNum = ENTITYNUM_NONE;
00597         ent->client->ps.fd.forceMindtrickTargetIndex = 0;
00598         ent->client->ps.fd.forceMindtrickTargetIndex2 = 0;
00599         ent->client->ps.fd.forceMindtrickTargetIndex3 = 0;
00600         ent->client->ps.fd.forceMindtrickTargetIndex4 = 0;
00601 
00602         ent->client->ps.holocronBits = 0;
00603 
00604         i = 0;
00605         while (i < NUM_FORCE_POWERS)
00606         {
00607                 ent->client->ps.holocronsCarried[i] = 0;
00608                 i++;
00609         }
00610 
00611         if (g_gametype.integer == GT_HOLOCRON)
00612         {
00613                 i = 0;
00614                 while (i < NUM_FORCE_POWERS)
00615                 {
00616                         ent->client->ps.fd.forcePowerLevel[i] = FORCE_LEVEL_0;
00617                         i++;
00618                 }
00619 
00620                 if (HasSetSaberOnly())
00621                 {
00622                         if (ent->client->ps.fd.forcePowerLevel[FP_SABER_OFFENSE] < FORCE_LEVEL_1)
00623                         {
00624                                 ent->client->ps.fd.forcePowerLevel[FP_SABER_OFFENSE] = FORCE_LEVEL_1;
00625                         }
00626                         if (ent->client->ps.fd.forcePowerLevel[FP_SABER_DEFENSE] < FORCE_LEVEL_1)
00627                         {
00628                                 ent->client->ps.fd.forcePowerLevel[FP_SABER_DEFENSE] = FORCE_LEVEL_1;
00629                         }
00630                 }
00631         }
00632 
00633         i = 0;
00634 
00635         while (i < NUM_FORCE_POWERS)
00636         {
00637                 ent->client->ps.fd.forcePowerDebounce[i] = 0;
00638                 ent->client->ps.fd.forcePowerDuration[i] = 0;
00639 
00640                 i++;
00641         }
00642 
00643         ent->client->ps.fd.forcePowerRegenDebounceTime = 0;
00644         ent->client->ps.fd.forceJumpZStart = 0;
00645         ent->client->ps.fd.forceJumpCharge = 0;
00646         ent->client->ps.fd.forceJumpSound = 0;
00647         ent->client->ps.fd.forceGripDamageDebounceTime = 0;
00648         ent->client->ps.fd.forceGripBeingGripped = 0;
00649         ent->client->ps.fd.forceGripCripple = 0;
00650         ent->client->ps.fd.forceGripUseTime = 0;
00651         ent->client->ps.fd.forceGripSoundTime = 0;
00652         ent->client->ps.fd.forceGripStarted = 0;
00653         ent->client->ps.fd.forceHealTime = 0;
00654         ent->client->ps.fd.forceHealAmount = 0;
00655         ent->client->ps.fd.forceRageRecoveryTime = 0;
00656         ent->client->ps.fd.forceDrainEntNum = ENTITYNUM_NONE;
00657         ent->client->ps.fd.forceDrainTime = 0;
00658 
00659         i = 0;
00660         while (i < NUM_FORCE_POWERS)
00661         {
00662                 if ((ent->client->ps.fd.forcePowersKnown & (1 << i)) &&
00663                         !ent->client->ps.fd.forcePowerLevel[i])
00664                 { //make sure all known powers are cleared if we have level 0 in them
00665                         ent->client->ps.fd.forcePowersKnown &= ~(1 << i);
00666                 }
00667 
00668                 i++;
00669         }
00670 
00671         if (g_gametype.integer == GT_SIEGE &&
00672                 ent->client->siegeClass != -1)
00673         { //Then use the powers for this class.
00674                 i = 0;
00675 
00676                 while (i < NUM_FORCE_POWERS)
00677                 {
00678                         ent->client->ps.fd.forcePowerLevel[i] = bgSiegeClasses[ent->client->siegeClass].forcePowerLevels[i];
00679 
00680                         if (!ent->client->ps.fd.forcePowerLevel[i])
00681                         {
00682                                 ent->client->ps.fd.forcePowersKnown &= ~(1 << i);
00683                         }
00684                         else
00685                         {
00686                                 ent->client->ps.fd.forcePowersKnown |= (1 << i);
00687                         }
00688                         i++;
00689                 }
00690         }
00691 }


Variable Documentation

int absorbLoopSound = 0
 

Definition at line 30 of file w_force.c.

Referenced by ForceAbsorb(), and WP_InitForcePowers().

bot_state_t* botstates[MAX_CLIENTS]
 

Definition at line 22 of file w_force.c.

const int forcePowerMinRank[NUM_FORCE_POWER_LEVELS][NUM_FORCE_POWERS]
 

Definition at line 51 of file w_force.c.

float forcePushPullRadius[NUM_FORCE_POWER_LEVELS]
 

Initial value:

{
        0,
        384,
        448,
        512
}

Definition at line 3044 of file w_force.c.

int g_LastFrameTime
 

Definition at line 4224 of file w_force.c.

Referenced by G_RunFrame(), and WP_ForcePowersUpdate().

vmCvar_t g_saberRestrictForce
 

Definition at line 16 of file w_force.c.

Referenced by WP_ForcePowerUsable().

int g_TimeSinceLastFrame
 

Definition at line 4225 of file w_force.c.

Referenced by G_RunFrame().

const int mindTrickTime[NUM_FORCE_POWER_LEVELS]
 

Initial value:

{
        0,
        5000,
        10000,
        15000
}

Definition at line 139 of file w_force.c.

Referenced by ForceTelepathyCheckDirectNPCTarget().

int protectLoopSound = 0
 

Definition at line 28 of file w_force.c.

Referenced by ForceProtect(), and WP_InitForcePowers().

int rageLoopSound = 0
 

Definition at line 26 of file w_force.c.

Referenced by ForceRage(), and WP_InitForcePowers().

int seeLoopSound = 0
 

Definition at line 32 of file w_force.c.

Referenced by ForceSeeing(), and WP_InitForcePowers().

int speedLoopSound = 0
 

Definition at line 24 of file w_force.c.

Referenced by ForceSpeed(), and WP_InitForcePowers().

int ysalamiriLoopSound = 0
 

Definition at line 34 of file w_force.c.

Referenced by WP_InitForcePowers().