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