codemp/game/g_weapon.c File Reference

#include "g_local.h"
#include "be_aas.h"
#include "bg_saga.h"
#include "../ghoul2/G2.h"
#include "q_shared.h"
#include "../namespace_begin.h"
#include "../namespace_end.h"

Go to the source code of this file.

Defines

#define BRYAR_PISTOL_VEL   1600
#define BRYAR_PISTOL_DAMAGE   10
#define BRYAR_CHARGE_UNIT   200.0f
#define BRYAR_ALT_SIZE   1.0f
#define BLASTER_SPREAD   1.6f
#define BLASTER_VELOCITY   2300
#define BLASTER_DAMAGE   20
#define DISRUPTOR_MAIN_DAMAGE   30
#define DISRUPTOR_MAIN_DAMAGE_SIEGE   50
#define DISRUPTOR_NPC_MAIN_DAMAGE_CUT   0.25f
#define DISRUPTOR_ALT_DAMAGE   100
#define DISRUPTOR_NPC_ALT_DAMAGE_CUT   0.2f
#define DISRUPTOR_ALT_TRACES   3
#define DISRUPTOR_CHARGE_UNIT   50.0f
#define BOWCASTER_DAMAGE   50
#define BOWCASTER_VELOCITY   1300
#define BOWCASTER_SPLASH_DAMAGE   0
#define BOWCASTER_SPLASH_RADIUS   0
#define BOWCASTER_SIZE   2
#define BOWCASTER_ALT_SPREAD   5.0f
#define BOWCASTER_VEL_RANGE   0.3f
#define BOWCASTER_CHARGE_UNIT   200.0f
#define REPEATER_SPREAD   1.4f
#define REPEATER_DAMAGE   14
#define REPEATER_VELOCITY   1600
#define REPEATER_ALT_SIZE   3
#define REPEATER_ALT_DAMAGE   60
#define REPEATER_ALT_SPLASH_DAMAGE   60
#define REPEATER_ALT_SPLASH_RADIUS   128
#define REPEATER_ALT_SPLASH_RAD_SIEGE   80
#define REPEATER_ALT_VELOCITY   1100
#define DEMP2_DAMAGE   35
#define DEMP2_VELOCITY   1800
#define DEMP2_SIZE   2
#define DEMP2_ALT_DAMAGE   8
#define DEMP2_CHARGE_UNIT   700.0f
#define DEMP2_ALT_RANGE   4096
#define DEMP2_ALT_SPLASHRADIUS   256
#define FLECHETTE_SHOTS   5
#define FLECHETTE_SPREAD   4.0f
#define FLECHETTE_DAMAGE   12
#define FLECHETTE_VEL   3500
#define FLECHETTE_SIZE   1
#define FLECHETTE_MINE_RADIUS_CHECK   256
#define FLECHETTE_ALT_DAMAGE   60
#define FLECHETTE_ALT_SPLASH_DAM   60
#define FLECHETTE_ALT_SPLASH_RAD   128
#define ROCKET_VELOCITY   900
#define ROCKET_DAMAGE   100
#define ROCKET_SPLASH_DAMAGE   100
#define ROCKET_SPLASH_RADIUS   160
#define ROCKET_SIZE   3
#define ROCKET_ALT_THINK_TIME   100
#define CONC_VELOCITY   3000
#define CONC_DAMAGE   75
#define CONC_NPC_DAMAGE_EASY   40
#define CONC_NPC_DAMAGE_NORMAL   80
#define CONC_NPC_DAMAGE_HARD   100
#define CONC_SPLASH_DAMAGE   40
#define CONC_SPLASH_RADIUS   200
#define CONC_ALT_DAMAGE   25
#define CONC_ALT_NPC_DAMAGE_EASY   20
#define CONC_ALT_NPC_DAMAGE_MEDIUM   35
#define CONC_ALT_NPC_DAMAGE_HARD   50
#define STUN_BATON_DAMAGE   20
#define STUN_BATON_ALT_DAMAGE   20
#define STUN_BATON_RANGE   8
#define MELEE_SWING1_DAMAGE   10
#define MELEE_SWING2_DAMAGE   12
#define MELEE_RANGE   8
#define ATST_MAIN_VEL   4000
#define ATST_MAIN_DAMAGE   25
#define ATST_MAIN_SIZE   3
#define ATST_SIDE_MAIN_DAMAGE   75
#define ATST_SIDE_MAIN_VELOCITY   1300
#define ATST_SIDE_MAIN_NPC_DAMAGE_EASY   30
#define ATST_SIDE_MAIN_NPC_DAMAGE_NORMAL   40
#define ATST_SIDE_MAIN_NPC_DAMAGE_HARD   50
#define ATST_SIDE_MAIN_SIZE   4
#define ATST_SIDE_MAIN_SPLASH_DAMAGE   10
#define ATST_SIDE_MAIN_SPLASH_RADIUS   16
#define ATST_SIDE_ALT_VELOCITY   1100
#define ATST_SIDE_ALT_NPC_VELOCITY   600
#define ATST_SIDE_ALT_DAMAGE   130
#define ATST_SIDE_ROCKET_NPC_DAMAGE_EASY   30
#define ATST_SIDE_ROCKET_NPC_DAMAGE_NORMAL   50
#define ATST_SIDE_ROCKET_NPC_DAMAGE_HARD   90
#define ATST_SIDE_ALT_SPLASH_DAMAGE   130
#define ATST_SIDE_ALT_SPLASH_RADIUS   200
#define ATST_SIDE_ALT_ROCKET_SIZE   5
#define ATST_SIDE_ALT_ROCKET_SPLASH_SCALE   0.5f
#define TD_DAMAGE   70
#define TD_SPLASH_RAD   128
#define TD_SPLASH_DAM   90
#define TD_VELOCITY   900
#define TD_MIN_CHARGE   0.15f
#define TD_TIME   3000
#define TD_ALT_TIME   3000
#define TD_ALT_DAMAGE   60
#define TD_ALT_SPLASH_RAD   128
#define TD_ALT_SPLASH_DAM   50
#define TD_ALT_VELOCITY   600
#define TD_ALT_MIN_CHARGE   0.15f
#define TD_ALT_TIME   3000
#define LT_DAMAGE   100
#define LT_SPLASH_RAD   256.0f
#define LT_SPLASH_DAM   105
#define LT_VELOCITY   900.0f
#define LT_SIZE   1.5f
#define LT_ALT_TIME   2000
#define LT_ACTIVATION_DELAY   1000
#define LT_DELAY_TIME   50
#define VEH_HOMING_MISSILE_THINK_TIME   100
#define MAX_XHAIR_DIST_ACCURACY   20000.0f
#define EMPLACED_CANRESPAWN   1
#define EMPLACED_GUN_HEALTH   800

Functions

qboolean G_BoxInBounds (vec3_t point, vec3_t mins, vec3_t maxs, vec3_t boundsMins, vec3_t boundsMaxs)
qboolean G_HeavyMelee (gentity_t *attacker)
void Jedi_Decloak (gentity_t *self)
void laserTrapStick (gentity_t *ent, vec3_t endpos, vec3_t normal)
void touch_NULL (gentity_t *ent, gentity_t *other, trace_t *trace)
void laserTrapExplode (gentity_t *self)
void RocketDie (gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod)
float WP_SpeedOfMissileForWeapon (int wp, qboolean alt_fire)
void W_TraceSetStart (gentity_t *ent, vec3_t start, vec3_t mins, vec3_t maxs)
void WP_FireTurretMissile (gentity_t *ent, vec3_t start, vec3_t dir, qboolean altFire, int damage, int velocity, int mod, gentity_t *ignore)
void WP_FireGenericBlasterMissile (gentity_t *ent, vec3_t start, vec3_t dir, qboolean altFire, int damage, int velocity, int mod)
void WP_FireBlasterMissile (gentity_t *ent, vec3_t start, vec3_t dir, qboolean altFire)
void WP_FireTurboLaserMissile (gentity_t *ent, vec3_t start, vec3_t dir)
void WP_FireEmplacedMissile (gentity_t *ent, vec3_t start, vec3_t dir, qboolean altFire, gentity_t *ignore)
int G_GetHitLocation (gentity_t *target, vec3_t ppoint)
qboolean G_CanDisruptify (gentity_t *ent)
void WP_DisruptorAltFire (gentity_t *ent)
void DEMP2_AltRadiusDamage (gentity_t *ent)
void DEMP2_AltDetonate (gentity_t *ent)
void prox_mine_think (gentity_t *ent)
void WP_ExplosiveDie (gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod)
void WP_flechette_alt_blow (gentity_t *ent)
void rocketThink (gentity_t *ent)
void G_ExplodeMissile (gentity_t *ent)
void thermalThinkStandard (gentity_t *ent)
void thermalDetonatorExplode (gentity_t *ent)
gentity_tWP_FireThermalDetonator (gentity_t *ent, qboolean altFire)
gentity_tWP_DropThermal (gentity_t *ent)
qboolean WP_LobFire (gentity_t *self, vec3_t start, vec3_t target, vec3_t mins, vec3_t maxs, int clipmask, vec3_t velocity, qboolean tracePath, int ignoreEntNum, int enemyNum, float minSpeed, float maxSpeed, float idealSpeed, qboolean mustHit)
void laserTrapDelayedExplode (gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath)
void touchLaserTrap (gentity_t *ent, gentity_t *other, trace_t *trace)
void proxMineThink (gentity_t *ent)
void laserTrapThink (gentity_t *ent)
void TrapThink (gentity_t *ent)
void CreateLaserTrap (gentity_t *laserTrap, vec3_t start, gentity_t *owner)
void WP_PlaceLaserTrap (gentity_t *ent, qboolean alt_fire)
void VectorNPos (vec3_t in, vec3_t out)
void DetPackBlow (gentity_t *self)
void charge_stick (gentity_t *self, gentity_t *other, trace_t *trace)
void DetPackPain (gentity_t *self, gentity_t *attacker, int damage)
void DetPackDie (gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod)
void drop_charge (gentity_t *self, vec3_t start, vec3_t dir)
void BlowDetpacks (gentity_t *ent)
qboolean CheatsOn (void)
void WP_DropDetPack (gentity_t *ent, qboolean alt_fire)
void WP_FireStunBaton (gentity_t *ent, qboolean alt_fire)
void WP_FireMelee (gentity_t *ent, qboolean alt_fire)
void SnapVectorTowards (vec3_t v, vec3_t to)
qboolean LogAccuracyHit (gentity_t *target, gentity_t *attacker)
void CalcMuzzlePoint (gentity_t *ent, vec3_t forward, vec3_t right, vec3_t up, vec3_t muzzlePoint)
void CalcMuzzlePointOrigin (gentity_t *ent, vec3_t origin, vec3_t forward, vec3_t right, vec3_t up, vec3_t muzzlePoint)
void G_MissileImpact (gentity_t *ent, trace_t *trace)
void WP_TouchVehMissile (gentity_t *ent, gentity_t *other, trace_t *trace)
void WP_CalcVehMuzzle (gentity_t *ent, int muzzleNum)
void WP_VehWeapSetSolidToOwner (gentity_t *self)
gentity_tWP_FireVehicleWeapon (gentity_t *ent, vec3_t start, vec3_t dir, vehWeaponInfo_t *vehWeapon, qboolean alt_fire, qboolean isTurretWeap)
void G_VehMuzzleFireFX (gentity_t *ent, gentity_t *broadcaster, int muzzlesFired)
void G_EstimateCamPos (vec3_t viewAngles, vec3_t cameraFocusLoc, float viewheight, float thirdPersonRange, float thirdPersonHorzOffset, float vertOffset, float pitchOffset, int ignoreEntNum, vec3_t camPos)
void WP_GetVehicleCamPos (gentity_t *ent, gentity_t *pilot, vec3_t camPos)
void WP_VehLeadCrosshairVeh (gentity_t *camTraceEnt, vec3_t newEnd, const vec3_t dir, const vec3_t shotStart, vec3_t shotDir)
int BG_VehTraceFromCamPos (trace_t *camTrace, bgEntity_t *bgEnt, const vec3_t entOrg, const vec3_t shotStart, const vec3_t end, vec3_t newEnd, vec3_t shotDir, float bestDist)
qboolean WP_VehCheckTraceFromCamPos (gentity_t *ent, const vec3_t shotStart, vec3_t shotDir)
void FireVehicleWeapon (gentity_t *ent, qboolean alt_fire)
int BG_EmplacedView (vec3_t baseAngles, vec3_t angles, float *newYaw, float constraint)
void FireWeapon (gentity_t *ent, qboolean altFire)
qboolean TryHeal (gentity_t *ent, gentity_t *target)
void emplaced_gun_use (gentity_t *self, gentity_t *other, trace_t *trace)
void emplaced_gun_realuse (gentity_t *self, gentity_t *other, gentity_t *activator)
void emplaced_gun_pain (gentity_t *self, gentity_t *attacker, int damage)
void emplaced_gun_update (gentity_t *self)
void emplaced_gun_die (gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod)
void SP_emplaced_gun (gentity_t *ent)

Variables

float g_cullDistance


Define Documentation

#define ATST_MAIN_DAMAGE   25
 

Definition at line 130 of file g_weapon.c.

#define ATST_MAIN_SIZE   3
 

Definition at line 131 of file g_weapon.c.

#define ATST_MAIN_VEL   4000
 

Definition at line 129 of file g_weapon.c.

#define ATST_SIDE_ALT_DAMAGE   130
 

Definition at line 146 of file g_weapon.c.

#define ATST_SIDE_ALT_NPC_VELOCITY   600
 

Definition at line 145 of file g_weapon.c.

#define ATST_SIDE_ALT_ROCKET_SIZE   5
 

Definition at line 154 of file g_weapon.c.

#define ATST_SIDE_ALT_ROCKET_SPLASH_SCALE   0.5f
 

Definition at line 155 of file g_weapon.c.

#define ATST_SIDE_ALT_SPLASH_DAMAGE   130
 

Definition at line 152 of file g_weapon.c.

#define ATST_SIDE_ALT_SPLASH_RADIUS   200
 

Definition at line 153 of file g_weapon.c.

#define ATST_SIDE_ALT_VELOCITY   1100
 

Definition at line 144 of file g_weapon.c.

#define ATST_SIDE_MAIN_DAMAGE   75
 

Definition at line 135 of file g_weapon.c.

#define ATST_SIDE_MAIN_NPC_DAMAGE_EASY   30
 

Definition at line 137 of file g_weapon.c.

#define ATST_SIDE_MAIN_NPC_DAMAGE_HARD   50
 

Definition at line 139 of file g_weapon.c.

#define ATST_SIDE_MAIN_NPC_DAMAGE_NORMAL   40
 

Definition at line 138 of file g_weapon.c.

#define ATST_SIDE_MAIN_SIZE   4
 

Definition at line 140 of file g_weapon.c.

#define ATST_SIDE_MAIN_SPLASH_DAMAGE   10
 

Definition at line 141 of file g_weapon.c.

#define ATST_SIDE_MAIN_SPLASH_RADIUS   16
 

Definition at line 142 of file g_weapon.c.

#define ATST_SIDE_MAIN_VELOCITY   1300
 

Definition at line 136 of file g_weapon.c.

#define ATST_SIDE_ROCKET_NPC_DAMAGE_EASY   30
 

Definition at line 148 of file g_weapon.c.

#define ATST_SIDE_ROCKET_NPC_DAMAGE_HARD   90
 

Definition at line 150 of file g_weapon.c.

#define ATST_SIDE_ROCKET_NPC_DAMAGE_NORMAL   50
 

Definition at line 149 of file g_weapon.c.

#define BLASTER_DAMAGE   20
 

Definition at line 27 of file g_weapon.c.

Referenced by WP_FireBlasterMissile(), and WP_FireEmplacedMissile().

#define BLASTER_SPREAD   1.6f
 

Definition at line 25 of file g_weapon.c.

#define BLASTER_VELOCITY   2300
 

Definition at line 26 of file g_weapon.c.

Referenced by WP_FireBlasterMissile(), and WP_FireEmplacedMissile().

#define BOWCASTER_ALT_SPREAD   5.0f
 

Definition at line 48 of file g_weapon.c.

#define BOWCASTER_CHARGE_UNIT   200.0f
 

Definition at line 50 of file g_weapon.c.

#define BOWCASTER_DAMAGE   50
 

Definition at line 42 of file g_weapon.c.

#define BOWCASTER_SIZE   2
 

Definition at line 46 of file g_weapon.c.

Referenced by Mark1_FireRocket(), and Mark1Dead_FireRocket().

#define BOWCASTER_SPLASH_DAMAGE   0
 

Definition at line 44 of file g_weapon.c.

Referenced by Mark1_FireRocket(), and Mark1Dead_FireRocket().

#define BOWCASTER_SPLASH_RADIUS   0
 

Definition at line 45 of file g_weapon.c.

Referenced by Mark1_FireRocket(), and Mark1Dead_FireRocket().

#define BOWCASTER_VEL_RANGE   0.3f
 

Definition at line 49 of file g_weapon.c.

#define BOWCASTER_VELOCITY   1300
 

Definition at line 43 of file g_weapon.c.

Referenced by Mark1_FireRocket(), and Mark1Dead_FireRocket().

#define BRYAR_ALT_SIZE   1.0f
 

Definition at line 21 of file g_weapon.c.

#define BRYAR_CHARGE_UNIT   200.0f
 

Definition at line 20 of file g_weapon.c.

#define BRYAR_PISTOL_DAMAGE   10
 

Definition at line 19 of file g_weapon.c.

#define BRYAR_PISTOL_VEL   1600
 

Definition at line 18 of file g_weapon.c.

#define CONC_ALT_DAMAGE   25
 

Definition at line 110 of file g_weapon.c.

#define CONC_ALT_NPC_DAMAGE_EASY   20
 

Definition at line 111 of file g_weapon.c.

#define CONC_ALT_NPC_DAMAGE_HARD   50
 

Definition at line 113 of file g_weapon.c.

#define CONC_ALT_NPC_DAMAGE_MEDIUM   35
 

Definition at line 112 of file g_weapon.c.

#define CONC_DAMAGE   75
 

Definition at line 103 of file g_weapon.c.

#define CONC_NPC_DAMAGE_EASY   40
 

Definition at line 104 of file g_weapon.c.

#define CONC_NPC_DAMAGE_HARD   100
 

Definition at line 106 of file g_weapon.c.

#define CONC_NPC_DAMAGE_NORMAL   80
 

Definition at line 105 of file g_weapon.c.

#define CONC_SPLASH_DAMAGE   40
 

Definition at line 107 of file g_weapon.c.

#define CONC_SPLASH_RADIUS   200
 

Definition at line 108 of file g_weapon.c.

#define CONC_VELOCITY   3000
 

Definition at line 102 of file g_weapon.c.

#define DEMP2_ALT_DAMAGE   8
 

Definition at line 71 of file g_weapon.c.

#define DEMP2_ALT_RANGE   4096
 

Definition at line 73 of file g_weapon.c.

#define DEMP2_ALT_SPLASHRADIUS   256
 

Definition at line 74 of file g_weapon.c.

#define DEMP2_CHARGE_UNIT   700.0f
 

Definition at line 72 of file g_weapon.c.

#define DEMP2_DAMAGE   35
 

Definition at line 67 of file g_weapon.c.

#define DEMP2_SIZE   2
 

Definition at line 69 of file g_weapon.c.

#define DEMP2_VELOCITY   1800
 

Definition at line 68 of file g_weapon.c.

#define DISRUPTOR_ALT_DAMAGE   100
 

Definition at line 35 of file g_weapon.c.

Referenced by WP_DisruptorAltFire().

#define DISRUPTOR_ALT_TRACES   3
 

Definition at line 37 of file g_weapon.c.

Referenced by WP_DisruptorAltFire().

#define DISRUPTOR_CHARGE_UNIT   50.0f
 

Definition at line 38 of file g_weapon.c.

Referenced by WP_DisruptorAltFire().

#define DISRUPTOR_MAIN_DAMAGE   30
 

Definition at line 31 of file g_weapon.c.

#define DISRUPTOR_MAIN_DAMAGE_SIEGE   50
 

Definition at line 32 of file g_weapon.c.

#define DISRUPTOR_NPC_ALT_DAMAGE_CUT   0.2f
 

Definition at line 36 of file g_weapon.c.

#define DISRUPTOR_NPC_MAIN_DAMAGE_CUT   0.25f
 

Definition at line 33 of file g_weapon.c.

#define EMPLACED_CANRESPAWN   1
 

Definition at line 4633 of file g_weapon.c.

Referenced by emplaced_gun_update(), and SP_emplaced_gun().

#define EMPLACED_GUN_HEALTH   800
 

Definition at line 4796 of file g_weapon.c.

Referenced by emplaced_gun_update(), and SP_emplaced_gun().

#define FLECHETTE_ALT_DAMAGE   60
 

Definition at line 84 of file g_weapon.c.

#define FLECHETTE_ALT_SPLASH_DAM   60
 

Definition at line 85 of file g_weapon.c.

#define FLECHETTE_ALT_SPLASH_RAD   128
 

Definition at line 86 of file g_weapon.c.

#define FLECHETTE_DAMAGE   12
 

Definition at line 80 of file g_weapon.c.

#define FLECHETTE_MINE_RADIUS_CHECK   256
 

Definition at line 83 of file g_weapon.c.

Referenced by prox_mine_think().

#define FLECHETTE_SHOTS   5
 

Definition at line 78 of file g_weapon.c.

Referenced by FireWeapon().

#define FLECHETTE_SIZE   1
 

Definition at line 82 of file g_weapon.c.

#define FLECHETTE_SPREAD   4.0f
 

Definition at line 79 of file g_weapon.c.

#define FLECHETTE_VEL   3500
 

Definition at line 81 of file g_weapon.c.

#define LT_ACTIVATION_DELAY   1000
 

Definition at line 2239 of file g_weapon.c.

Referenced by laserTrapStick().

#define LT_ALT_TIME   2000
 

Definition at line 2238 of file g_weapon.c.

Referenced by laserTrapStick().

#define LT_DAMAGE   100
 

Definition at line 2233 of file g_weapon.c.

Referenced by CreateLaserTrap().

#define LT_DELAY_TIME   50
 

Definition at line 2240 of file g_weapon.c.

Referenced by laserTrapThink().

#define LT_SIZE   1.5f
 

Definition at line 2237 of file g_weapon.c.

Referenced by CreateLaserTrap(), and laserTrapStick().

#define LT_SPLASH_DAM   105
 

Definition at line 2235 of file g_weapon.c.

Referenced by CreateLaserTrap().

#define LT_SPLASH_RAD   256.0f
 

Definition at line 2234 of file g_weapon.c.

Referenced by CreateLaserTrap().

#define LT_VELOCITY   900.0f
 

Definition at line 2236 of file g_weapon.c.

#define MAX_XHAIR_DIST_ACCURACY   20000.0f
 

Definition at line 4020 of file g_weapon.c.

#define MELEE_RANGE   8
 

Definition at line 125 of file g_weapon.c.

Referenced by WP_FireMelee().

#define MELEE_SWING1_DAMAGE   10
 

Definition at line 123 of file g_weapon.c.

Referenced by WP_FireMelee().

#define MELEE_SWING2_DAMAGE   12
 

Definition at line 124 of file g_weapon.c.

Referenced by WP_FireMelee().

#define REPEATER_ALT_DAMAGE   60
 

Definition at line 59 of file g_weapon.c.

#define REPEATER_ALT_SIZE   3
 

Definition at line 58 of file g_weapon.c.

Referenced by NPC_BSGM_Attack().

#define REPEATER_ALT_SPLASH_DAMAGE   60
 

Definition at line 60 of file g_weapon.c.

#define REPEATER_ALT_SPLASH_RAD_SIEGE   80
 

Definition at line 62 of file g_weapon.c.

#define REPEATER_ALT_SPLASH_RADIUS   128
 

Definition at line 61 of file g_weapon.c.

#define REPEATER_ALT_VELOCITY   1100
 

Definition at line 63 of file g_weapon.c.

#define REPEATER_DAMAGE   14
 

Definition at line 55 of file g_weapon.c.

#define REPEATER_SPREAD   1.4f
 

Definition at line 54 of file g_weapon.c.

#define REPEATER_VELOCITY   1600
 

Definition at line 56 of file g_weapon.c.

#define ROCKET_ALT_THINK_TIME   100
 

Definition at line 95 of file g_weapon.c.

Referenced by rocketThink().

#define ROCKET_DAMAGE   100
 

Definition at line 91 of file g_weapon.c.

#define ROCKET_SIZE   3
 

Definition at line 94 of file g_weapon.c.

#define ROCKET_SPLASH_DAMAGE   100
 

Definition at line 92 of file g_weapon.c.

#define ROCKET_SPLASH_RADIUS   160
 

Definition at line 93 of file g_weapon.c.

#define ROCKET_VELOCITY   900
 

Definition at line 90 of file g_weapon.c.

Referenced by rocketThink().

#define STUN_BATON_ALT_DAMAGE   20
 

Definition at line 118 of file g_weapon.c.

#define STUN_BATON_DAMAGE   20
 

Definition at line 117 of file g_weapon.c.

Referenced by WP_FireStunBaton().

#define STUN_BATON_RANGE   8
 

Definition at line 119 of file g_weapon.c.

Referenced by WP_FireStunBaton().

#define TD_ALT_DAMAGE   60
 

Definition at line 1924 of file g_weapon.c.

#define TD_ALT_MIN_CHARGE   0.15f
 

Definition at line 1928 of file g_weapon.c.

#define TD_ALT_SPLASH_DAM   50
 

Definition at line 1926 of file g_weapon.c.

#define TD_ALT_SPLASH_RAD   128
 

Definition at line 1925 of file g_weapon.c.

#define TD_ALT_TIME   3000
 

Definition at line 1929 of file g_weapon.c.

#define TD_ALT_TIME   3000
 

Definition at line 1929 of file g_weapon.c.

#define TD_ALT_VELOCITY   600
 

Definition at line 1927 of file g_weapon.c.

#define TD_DAMAGE   70
 

Definition at line 1916 of file g_weapon.c.

Referenced by WP_FireThermalDetonator().

#define TD_MIN_CHARGE   0.15f
 

Definition at line 1920 of file g_weapon.c.

Referenced by WP_FireThermalDetonator().

#define TD_SPLASH_DAM   90
 

Definition at line 1918 of file g_weapon.c.

Referenced by WP_FireThermalDetonator().

#define TD_SPLASH_RAD   128
 

Definition at line 1917 of file g_weapon.c.

Referenced by WP_FireThermalDetonator().

#define TD_TIME   3000
 

Definition at line 1921 of file g_weapon.c.

Referenced by WP_FireThermalDetonator().

#define TD_VELOCITY   900
 

Definition at line 1919 of file g_weapon.c.

Referenced by WP_FireThermalDetonator().

#define VEH_HOMING_MISSILE_THINK_TIME   100
 

Definition at line 3622 of file g_weapon.c.

Referenced by WP_FireVehicleWeapon().


Function Documentation

int BG_EmplacedView vec3_t  baseAngles,
vec3_t  angles,
float *  newYaw,
float  constraint
 

Definition at line 2703 of file bg_misc.c.

References AngleSubtract(), vec3_t, and YAW.

Referenced by CG_EmplacedView(), CG_Player(), EWebThink(), and FireWeapon().

02704 {
02705         float dif = AngleSubtract(baseAngles[YAW], angles[YAW]);
02706 
02707         if (dif > constraint ||
02708                 dif < -constraint)
02709         {
02710                 float amt;
02711 
02712                 if (dif > constraint)
02713                 {
02714                         amt = (dif-constraint);
02715                         dif = constraint;
02716                 }
02717                 else if (dif < -constraint)
02718                 {
02719                         amt = (dif+constraint);
02720                         dif = -constraint;
02721                 }
02722                 else
02723                 {
02724                         amt = 0.0f;
02725                 }
02726 
02727                 *newYaw = AngleSubtract(angles[YAW], -dif);
02728 
02729                 if (amt > 1.0f || amt < -1.0f)
02730                 { //significant, force the view
02731                         return 2;
02732                 }
02733                 else
02734                 { //just a little out of range
02735                         return 1;
02736                 }
02737         }
02738 
02739         return 0;
02740 }

int BG_VehTraceFromCamPos trace_t camTrace,
bgEntity_t bgEnt,
const vec3_t  entOrg,
const vec3_t  shotStart,
const vec3_t  end,
vec3_t  newEnd,
vec3_t  shotDir,
float  bestDist
 

Definition at line 5834 of file bg_pmove.c.

References trace_t::allsolid, bgEntity_t, CG_GetVehicleCamPos(), CONTENTS_BODY, CONTENTS_SOLID, trace_t::endpos, trace_t::entityNum, trace_t::fraction, gentity_t, vehicleInfo_t::length, Vehicle_s::m_pPilot, gentity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, MAX_XHAIR_DIST_ACCURACY, entityState_s::number, pm, gentity_s::s, trace_t::startsolid, pmove_t::trace, trap_Trace(), vec3_origin, vec3_t, VectorCopy, VectorMA, VectorNormalize(), VectorSubtract, and WP_GetVehicleCamPos().

Referenced by PM_RocketLock(), and WP_VehCheckTraceFromCamPos().

05835 {
05836         //NOTE: this MUST stay up to date with the method used in CG_ScanForCrosshairEntity (where it checks the doExtraVehTraceFromViewPos bool)
05837         vec3_t  viewDir2End, extraEnd, camPos;
05838         float   minAutoAimDist;
05839 
05840 #ifdef QAGAME
05841         WP_GetVehicleCamPos( (gentity_t *)bgEnt, (gentity_t *)bgEnt->m_pVehicle->m_pPilot, camPos );
05842 #else
05843         CG_GetVehicleCamPos( camPos );
05844 #endif
05845         
05846         minAutoAimDist = Distance( entOrg, camPos ) + (bgEnt->m_pVehicle->m_pVehicleInfo->length/2.0f) + 200.0f;
05847 
05848         VectorCopy( end, newEnd );
05849         VectorSubtract( end, camPos, viewDir2End );
05850         VectorNormalize( viewDir2End );
05851         VectorMA( camPos, MAX_XHAIR_DIST_ACCURACY, viewDir2End, extraEnd );
05852 
05853 #ifdef QAGAME
05854         trap_Trace( camTrace, camPos, vec3_origin, vec3_origin, extraEnd, 
05855                 bgEnt->s.number, CONTENTS_SOLID|CONTENTS_BODY );
05856 #else
05857         pm->trace( camTrace, camPos, vec3_origin, vec3_origin, extraEnd, 
05858                 bgEnt->s.number, CONTENTS_SOLID|CONTENTS_BODY );
05859 #endif
05860 
05861         if ( !camTrace->allsolid
05862                 && !camTrace->startsolid
05863                 && camTrace->fraction < 1.0f
05864                 && (camTrace->fraction*MAX_XHAIR_DIST_ACCURACY) > minAutoAimDist 
05865                 && ((camTrace->fraction*MAX_XHAIR_DIST_ACCURACY)-Distance( entOrg, camPos )) < bestDist )
05866         {//this trace hit *something* that's closer than the thing the main trace hit, so use this result instead
05867                 VectorCopy( camTrace->endpos, newEnd );
05868                 VectorSubtract( newEnd, shotStart, shotDir );
05869                 VectorNormalize( shotDir );
05870                 return (camTrace->entityNum+1);
05871         }
05872         return 0;
05873 }

void BlowDetpacks gentity_t ent  ) 
 

Definition at line 2849 of file g_weapon.c.

References CHAN_BODY, gentity_s::client, entityShared_t::currentOrigin, DetPackBlow(), FOFS, G_Find(), G_Sound(), G_SoundIndex(), gentity_t, playerState_s::hasDetPackPlanted, level, gentity_s::nextthink, NULL, entityState_s::origin, gentity_s::parent, gclient_s::ps, qfalse, gentity_s::r, random, gentity_s::s, gentity_s::think, level_locals_t::time, and VectorCopy.

Referenced by player_die(), and WP_DropDetPack().

02850 {
02851         gentity_t *found = NULL;
02852 
02853         if ( ent->client->ps.hasDetPackPlanted )
02854         {
02855                 while ( (found = G_Find( found, FOFS(classname), "detpack") ) != NULL )
02856                 {//loop through all ents and blow the crap out of them!
02857                         if ( found->parent == ent )
02858                         {
02859                                 VectorCopy( found->r.currentOrigin, found->s.origin );
02860                                 found->think = DetPackBlow;
02861                                 found->nextthink = level.time + 100 + random() * 200;
02862                                 G_Sound( found, CHAN_BODY, G_SoundIndex("sound/weapons/detpack/warning.wav") );
02863                         }
02864                 }
02865                 ent->client->ps.hasDetPackPlanted = qfalse;
02866         }
02867 }

void CalcMuzzlePoint gentity_t ent,
vec3_t  forward,
vec3_t  right,
vec3_t  up,
vec3_t  muzzlePoint
 

Definition at line 3525 of file g_weapon.c.

References gentity_s::client, gentity_t, entityState_s::pos, gclient_s::ps, gentity_s::s, trajectory_t::trBase, vec3_t, VectorCopy, VectorMA, playerState_s::viewheight, entityState_s::weapon, WP_MuzzlePoint, WP_NONE, and WP_NUM_WEAPONS.

Referenced by CalcEntitySpot(), FireWeapon(), NPC_BSSniper_Attack(), Sniper_FaceEnemy(), and WP_DropDetPack().

03526 {
03527         int weapontype;
03528         vec3_t muzzleOffPoint;
03529 
03530         weapontype = ent->s.weapon;
03531         VectorCopy( ent->s.pos.trBase, muzzlePoint );
03532 
03533         VectorCopy(WP_MuzzlePoint[weapontype], muzzleOffPoint);
03534 
03535         if (weapontype > WP_NONE && weapontype < WP_NUM_WEAPONS)
03536         {       // Use the table to generate the muzzlepoint;
03537                 {       // Crouching.  Use the add-to-Z method to adjust vertically.
03538                         VectorMA(muzzlePoint, muzzleOffPoint[0], forward, muzzlePoint);
03539                         VectorMA(muzzlePoint, muzzleOffPoint[1], right, muzzlePoint);
03540                         muzzlePoint[2] += ent->client->ps.viewheight + muzzleOffPoint[2];
03541                 }
03542         }
03543 
03544         // snap to integer coordinates for more efficient network bandwidth usage
03545         SnapVector( muzzlePoint );
03546 }

void CalcMuzzlePointOrigin gentity_t ent,
vec3_t  origin,
vec3_t  forward,
vec3_t  right,
vec3_t  up,
vec3_t  muzzlePoint
 

Definition at line 3555 of file g_weapon.c.

References gentity_s::client, gentity_t, entityState_s::pos, gclient_s::ps, gentity_s::s, trajectory_t::trBase, vec3_t, VectorCopy, VectorMA, and playerState_s::viewheight.

03555                                                                                                                           {
03556         VectorCopy( ent->s.pos.trBase, muzzlePoint );
03557         muzzlePoint[2] += ent->client->ps.viewheight;
03558         VectorMA( muzzlePoint, 14, forward, muzzlePoint );
03559         // snap to integer coordinates for more efficient network bandwidth usage
03560         SnapVector( muzzlePoint );
03561 }

void charge_stick gentity_t self,
gentity_t other,
trace_t trace
 

Definition at line 2643 of file g_weapon.c.

References entityState_s::angles, entityState_s::apos, CHAN_WEAPON, charge_stick(), gentity_s::client, gentity_s::count, entityShared_t::currentAngles, entityShared_t::currentOrigin, DetPackBlow(), EFFECT_EXPLOSION_DETPACK, ENTITYNUM_WORLD, ET_MOVER, entityState_s::eType, EV_MISSILE_MISS, FL_BBRUSH, gentity_s::flags, G_FreeEntity(), G_PlayEffect(), G_RadiusDamage(), G_Sound(), G_SoundIndex(), G_TempEntity(), gentity_t, entityState_s::groundEntityNum, level, MOD_DET_PACK_SPLASH, gentity_s::nextthink, cplane_s::normal, entityState_s::number, entityState_s::origin, entityShared_t::ownerNum, gentity_s::parent, trace_t::plane, entityState_s::pos, gentity_s::pos2, Q_irand(), qfalse, gentity_s::r, gentity_s::s, gentity_s::splashDamage, gentity_s::splashRadius, SVF_OWNERNOTSHARED, entityShared_t::svFlags, gentity_s::takedamage, gentity_s::target_ent, gentity_s::think, level_locals_t::time, gentity_s::touch, TR_STATIONARY, trajectory_t::trBase, trajectory_t::trDelta, trajectory_t::trType, vec3_t, vectoangles(), VectorClear, VectorCopy, VectorNormalize(), VectorNPos(), and entityState_s::weapon.

Referenced by charge_stick(), and drop_charge().

02644 {
02645         gentity_t       *tent;
02646 
02647         if ( other 
02648                 && (other->flags&FL_BBRUSH)
02649                 && other->s.pos.trType == TR_STATIONARY
02650                 && other->s.apos.trType == TR_STATIONARY )
02651         {//a perfectly still breakable brush, let us attach directly to it!
02652                 self->target_ent = other;//remember them when we blow up
02653         }
02654         else if ( other 
02655                 && other->s.number < ENTITYNUM_WORLD
02656                 && other->s.eType == ET_MOVER
02657                 && trace->plane.normal[2] > 0 )
02658         {//stick to it?
02659                 self->s.groundEntityNum = other->s.number;
02660         }
02661         else if (other && other->s.number < ENTITYNUM_WORLD &&
02662                 (other->client || !other->s.weapon))
02663         { //hit another entity that is not stickable, "bounce" off
02664                 vec3_t vNor, tN;
02665 
02666                 VectorCopy(trace->plane.normal, vNor);
02667                 VectorNormalize(vNor);
02668                 VectorNPos(self->s.pos.trDelta, tN);
02669                 self->s.pos.trDelta[0] += vNor[0]*(tN[0]*(((float)Q_irand(1, 10))*0.1));
02670                 self->s.pos.trDelta[1] += vNor[1]*(tN[1]*(((float)Q_irand(1, 10))*0.1));
02671                 self->s.pos.trDelta[2] += vNor[1]*(tN[2]*(((float)Q_irand(1, 10))*0.1));
02672 
02673                 vectoangles(vNor, self->s.angles);
02674                 vectoangles(vNor, self->s.apos.trBase);
02675                 self->touch = charge_stick;
02676                 return;
02677         }
02678         else if (other && other->s.number < ENTITYNUM_WORLD)
02679         { //hit an entity that we just want to explode on (probably another projectile or something)
02680                 vec3_t v;
02681 
02682                 self->touch = 0;
02683                 self->think = 0;
02684                 self->nextthink = 0;
02685 
02686                 self->takedamage = qfalse;
02687 
02688                 VectorClear(self->s.apos.trDelta);
02689                 self->s.apos.trType = TR_STATIONARY;
02690 
02691                 G_RadiusDamage( self->r.currentOrigin, self->parent, self->splashDamage, self->splashRadius, self, self, MOD_DET_PACK_SPLASH );
02692                 VectorCopy(trace->plane.normal, v);
02693                 VectorCopy(v, self->pos2);
02694                 self->count = -1;
02695                 G_PlayEffect(EFFECT_EXPLOSION_DETPACK, self->r.currentOrigin, v);
02696 
02697                 self->think = G_FreeEntity;
02698                 self->nextthink = level.time;
02699                 return;
02700         }
02701 
02702         //if we get here I guess we hit hte world so we can stick to it
02703 
02704         self->touch = 0;
02705         self->think = DetPackBlow;
02706         self->nextthink = level.time + 30000;
02707 
02708         VectorClear(self->s.apos.trDelta);
02709         self->s.apos.trType = TR_STATIONARY;
02710 
02711         self->s.pos.trType = TR_STATIONARY;
02712         VectorCopy( self->r.currentOrigin, self->s.origin );
02713         VectorCopy( self->r.currentOrigin, self->s.pos.trBase );
02714         VectorClear( self->s.pos.trDelta );
02715 
02716         VectorClear( self->s.apos.trDelta );
02717 
02718         VectorNormalize(trace->plane.normal);
02719 
02720         vectoangles(trace->plane.normal, self->s.angles);
02721         VectorCopy(self->s.angles, self->r.currentAngles );
02722         VectorCopy(self->s.angles, self->s.apos.trBase);
02723 
02724         VectorCopy(trace->plane.normal, self->pos2);
02725         self->count = -1;
02726 
02727         G_Sound(self, CHAN_WEAPON, G_SoundIndex("sound/weapons/detpack/stick.wav"));
02728                 
02729         tent = G_TempEntity( self->r.currentOrigin, EV_MISSILE_MISS );
02730         tent->s.weapon = 0;
02731         tent->parent = self;
02732         tent->r.ownerNum = self->s.number;
02733 
02734         //so that the owner can blow it up with projectiles
02735         self->r.svFlags |= SVF_OWNERNOTSHARED;
02736 }

qboolean CheatsOn void   ) 
 

Definition at line 2869 of file g_weapon.c.

References g_cheats, vmCvar_t::integer, qboolean, qfalse, and qtrue.

Referenced by WP_DropDetPack().

02870 {
02871         if ( !g_cheats.integer )
02872         {
02873                 return qfalse;
02874         }
02875         return qtrue;
02876 }

void CreateLaserTrap gentity_t laserTrap,
vec3_t  start,
gentity_t owner
 

Definition at line 2475 of file g_weapon.c.

References gentity_s::activator, entityState_s::apos, gentity_s::classname, gentity_s::clipmask, entityShared_t::contents, entityShared_t::currentOrigin, gentity_s::damage, EF_MISSILE_STICK, entityState_s::eFlags, ET_GENERAL, entityState_s::eType, FL_BOUNCE_HALF, gentity_s::flags, entityState_s::g2radius, G_ModelIndex(), entityState_s::genericenemyindex, gentity_t, gentity_s::health, level, LT_DAMAGE, LT_SIZE, LT_SPLASH_DAM, LT_SPLASH_RAD, MASK_SHOT, MAX_GENTITIES, entityShared_t::maxs, gentity_s::methodOfDeath, entityShared_t::mins, MOD_TRIP_MINE_SPLASH, entityState_s::modelGhoul2, entityState_s::modelindex, gentity_s::nextthink, entityState_s::number, entityShared_t::ownerNum, gentity_s::parent, PITCH, entityState_s::pos, gentity_s::pos2, gentity_s::r, rand(), ROLL, gentity_s::s, entityState_s::solid, gentity_s::splashDamage, gentity_s::splashMethodOfDeath, gentity_s::splashRadius, SVF_USE_CURRENT_ORIGIN, entityShared_t::svFlags, gentity_s::think, level_locals_t::time, entityState_s::time, gentity_s::touch, touchLaserTrap(), TR_GRAVITY, TrapThink(), trajectory_t::trBase, trajectory_t::trDelta, trajectory_t::trTime, trajectory_t::trType, vec3_t, VectorCopy, VectorSet, entityState_s::weapon, WP_TRIP_MINE, and YAW.

Referenced by WP_PlaceLaserTrap().

02476 { //create a laser trap entity
02477         laserTrap->classname = "laserTrap";
02478         laserTrap->flags |= FL_BOUNCE_HALF;
02479         laserTrap->s.eFlags |= EF_MISSILE_STICK;
02480         laserTrap->splashDamage = LT_SPLASH_DAM;
02481         laserTrap->splashRadius = LT_SPLASH_RAD;
02482         laserTrap->damage = LT_DAMAGE;
02483         laserTrap->methodOfDeath = MOD_TRIP_MINE_SPLASH;
02484         laserTrap->splashMethodOfDeath = MOD_TRIP_MINE_SPLASH;
02485         laserTrap->s.eType = ET_GENERAL;
02486         laserTrap->r.svFlags = SVF_USE_CURRENT_ORIGIN;
02487         laserTrap->s.weapon = WP_TRIP_MINE;
02488         laserTrap->s.pos.trType = TR_GRAVITY;
02489         laserTrap->r.contents = MASK_SHOT;
02490         laserTrap->parent = owner;
02491         laserTrap->activator = owner;
02492         laserTrap->r.ownerNum = owner->s.number;
02493         VectorSet( laserTrap->r.mins, -LT_SIZE, -LT_SIZE, -LT_SIZE );
02494         VectorSet( laserTrap->r.maxs, LT_SIZE, LT_SIZE, LT_SIZE );
02495         laserTrap->clipmask = MASK_SHOT;
02496         laserTrap->s.solid = 2;
02497         laserTrap->s.modelindex = G_ModelIndex( "models/weapons2/laser_trap/laser_trap_w.glm" );
02498         laserTrap->s.modelGhoul2 = 1;
02499         laserTrap->s.g2radius = 40;
02500 
02501         laserTrap->s.genericenemyindex = owner->s.number+MAX_GENTITIES;
02502 
02503         laserTrap->health = 1;
02504 
02505         laserTrap->s.time = 0;
02506 
02507         laserTrap->s.pos.trTime = level.time;           // move a bit on the very first frame
02508         VectorCopy( start, laserTrap->s.pos.trBase );
02509         SnapVector( laserTrap->s.pos.trBase );                  // save net bandwidth
02510         
02511         SnapVector( laserTrap->s.pos.trDelta );                 // save net bandwidth
02512         VectorCopy (start, laserTrap->r.currentOrigin);
02513 
02514         laserTrap->s.apos.trType = TR_GRAVITY;
02515         laserTrap->s.apos.trTime = level.time;
02516         laserTrap->s.apos.trBase[YAW] = rand()%360;
02517         laserTrap->s.apos.trBase[PITCH] = rand()%360;
02518         laserTrap->s.apos.trBase[ROLL] = rand()%360;
02519 
02520         if (rand()%10 < 5)
02521         {
02522                 laserTrap->s.apos.trBase[YAW] = -laserTrap->s.apos.trBase[YAW];
02523         }
02524 
02525         VectorCopy( start, laserTrap->pos2 );
02526         laserTrap->touch = touchLaserTrap;
02527         laserTrap->think = TrapThink;
02528         laserTrap->nextthink = level.time + 50;
02529 }

void DEMP2_AltDetonate gentity_t ent  ) 
 

Definition at line 1308 of file g_weapon.c.

References gentity_s::count, entityShared_t::currentOrigin, DEMP2_AltRadiusDamage(), EFFECT_EXPLOSION_DEMP2ALT, ET_GENERAL, entityState_s::eType, G_PlayEffect(), G_SetOrigin(), gentity_s::genericValue5, gentity_s::genericValue6, gentity_t, level, gentity_s::nextthink, gentity_s::pos1, gentity_s::r, gentity_s::s, gentity_s::think, level_locals_t::time, and entityState_s::weapon.

01310 {
01311         gentity_t *efEnt;
01312 
01313         G_SetOrigin( ent, ent->r.currentOrigin );
01314         if (!ent->pos1[0] && !ent->pos1[1] && !ent->pos1[2])
01315         { //don't play effect with a 0'd out directional vector
01316                 ent->pos1[1] = 1;
01317         }
01318         //Let's just save ourself some bandwidth and play both the effect and sphere spawn in 1 event
01319         efEnt = G_PlayEffect( EFFECT_EXPLOSION_DEMP2ALT, ent->r.currentOrigin, ent->pos1 );
01320 
01321         if (efEnt)
01322         {
01323                 efEnt->s.weapon = ent->count*2;
01324         }
01325 
01326         ent->genericValue5 = level.time;
01327         ent->genericValue6 = 0;
01328         ent->nextthink = level.time + 50;
01329         ent->think = DEMP2_AltRadiusDamage;
01330         ent->s.eType = ET_GENERAL; // make us a missile no longer
01331 }

void DEMP2_AltRadiusDamage gentity_t ent  ) 
 

Definition at line 1162 of file g_weapon.c.

References entityShared_t::absmax, entityShared_t::absmin, CLASS_VEHICLE, gentity_s::client, gclient_s::cloakToggleTime, entityShared_t::contents, gentity_s::count, entityShared_t::currentOrigin, gentity_s::damage, DAMAGE_DEATH_KNOCKBACK, playerState_s::electrifyTime, ET_NPC, entityState_s::eType, G_Damage(), g_entities, G_FreeEntity(), gentity_s::genericValue5, gentity_s::genericValue6, gentity_t, gentity_s::inuse, Jedi_Decloak(), level, gentity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, MAX_GENTITIES, gentity_s::nextthink, entityState_s::NPC_class, NULL, entityShared_t::ownerNum, playerState_s::powerups, gclient_s::ps, PW_CLOAKED, Q_irand(), gentity_s::r, gentity_s::s, gentity_s::splashMethodOfDeath, gentity_s::takedamage, gentity_s::think, level_locals_t::time, trap_EntitiesInBox(), vehicleInfo_t::type, vec3_t, VectorCopy, VectorSubtract, VH_FIGHTER, VH_SPEEDER, and VH_WALKER.

Referenced by DEMP2_AltDetonate().

01163 {
01164         float           frac = ( level.time - ent->genericValue5 ) / 800.0f; // / 1600.0f; // synchronize with demp2 effect
01165         float           dist, radius, fact;
01166         gentity_t       *gent;
01167         int                     iEntityList[MAX_GENTITIES];
01168         gentity_t       *entityList[MAX_GENTITIES];
01169         gentity_t       *myOwner = NULL;
01170         int                     numListedEntities, i, e;
01171         vec3_t          mins, maxs;
01172         vec3_t          v, dir;
01173 
01174         if (ent->r.ownerNum >= 0 &&
01175                 ent->r.ownerNum < /*MAX_CLIENTS ... let npc's/shooters use it*/MAX_GENTITIES)
01176         {
01177                 myOwner = &g_entities[ent->r.ownerNum];
01178         }
01179 
01180         if (!myOwner || !myOwner->inuse || !myOwner->client)
01181         {
01182                 ent->think = G_FreeEntity;
01183                 ent->nextthink = level.time;
01184                 return;
01185         }
01186 
01187         frac *= frac * frac; // yes, this is completely ridiculous...but it causes the shell to grow slowly then "explode" at the end
01188         
01189         radius = frac * 200.0f; // 200 is max radius...the model is aprox. 100 units tall...the fx draw code mults. this by 2.
01190 
01191         fact = ent->count*0.6;
01192 
01193         if (fact < 1)
01194         {
01195                 fact = 1;
01196         }
01197 
01198         radius *= fact;
01199 
01200         for ( i = 0 ; i < 3 ; i++ ) 
01201         {
01202                 mins[i] = ent->r.currentOrigin[i] - radius;
01203                 maxs[i] = ent->r.currentOrigin[i] + radius;
01204         }
01205 
01206         numListedEntities = trap_EntitiesInBox( mins, maxs, iEntityList, MAX_GENTITIES );
01207 
01208         i = 0;
01209         while (i < numListedEntities)
01210         {
01211                 entityList[i] = &g_entities[iEntityList[i]];
01212                 i++;
01213         }
01214 
01215         for ( e = 0 ; e < numListedEntities ; e++ ) 
01216         {
01217                 gent = entityList[ e ];
01218 
01219                 if ( !gent || !gent->takedamage || !gent->r.contents )
01220                 {
01221                         continue;
01222                 }
01223 
01224                 // find the distance from the edge of the bounding box
01225                 for ( i = 0 ; i < 3 ; i++ ) 
01226                 {
01227                         if ( ent->r.currentOrigin[i] < gent->r.absmin[i] ) 
01228                         {
01229                                 v[i] = gent->r.absmin[i] - ent->r.currentOrigin[i];
01230                         } 
01231                         else if ( ent->r.currentOrigin[i] > gent->r.absmax[i] ) 
01232                         {
01233                                 v[i] = ent->r.currentOrigin[i] - gent->r.absmax[i];
01234                         } 
01235                         else 
01236                         {
01237                                 v[i] = 0;
01238                         }
01239                 }
01240 
01241                 // shape is an ellipsoid, so cut vertical distance in half`
01242                 v[2] *= 0.5f;
01243 
01244                 dist = VectorLength( v );
01245 
01246                 if ( dist >= radius ) 
01247                 {
01248                         // shockwave hasn't hit them yet
01249                         continue;
01250                 }
01251 
01252                 if (dist+(16*ent->count) < ent->genericValue6)
01253                 {
01254                         // shockwave has already hit this thing...
01255                         continue;
01256                 }
01257 
01258                 VectorCopy( gent->r.currentOrigin, v );
01259                 VectorSubtract( v, ent->r.currentOrigin, dir);
01260 
01261                 // push the center of mass higher than the origin so players get knocked into the air more
01262                 dir[2] += 12;
01263 
01264                 if (gent != myOwner)
01265                 {
01266                         G_Damage( gent, myOwner, myOwner, dir, ent->r.currentOrigin, ent->damage, DAMAGE_DEATH_KNOCKBACK, ent->splashMethodOfDeath );
01267                         if ( gent->takedamage 
01268                                 && gent->client ) 
01269                         {
01270                                 if ( gent->client->ps.electrifyTime < level.time )
01271                                 {//electrocution effect
01272                                         if (gent->s.eType == ET_NPC && gent->s.NPC_class == CLASS_VEHICLE &&
01273                                                 gent->m_pVehicle && (gent->m_pVehicle->m_pVehicleInfo->type == VH_SPEEDER || gent->m_pVehicle->m_pVehicleInfo->type == VH_WALKER))
01274                                         { //do some extra stuff to speeders/walkers
01275                                                 gent->client->ps.electrifyTime = level.time + Q_irand( 3000, 4000 );
01276                                         }
01277                                         else if ( gent->s.NPC_class != CLASS_VEHICLE 
01278                                                 || (gent->m_pVehicle && gent->m_pVehicle->m_pVehicleInfo->type != VH_FIGHTER) )
01279                                         {//don't do this to fighters
01280                                                 gent->client->ps.electrifyTime = level.time + Q_irand( 300, 800 );
01281                                         }
01282                                 }
01283                                 if ( gent->client->ps.powerups[PW_CLOAKED] )
01284                                 {//disable cloak temporarily
01285                                         Jedi_Decloak( gent );
01286                                         gent->client->cloakToggleTime = level.time + Q_irand( 3000, 10000 );
01287                                 }
01288                         }
01289                 }
01290         }
01291 
01292         // store the last fraction so that next time around we can test against those things that fall between that last point and where the current shockwave edge is
01293         ent->genericValue6 = radius;
01294 
01295         if ( frac < 1.0f )
01296         {
01297                 // shock is still happening so continue letting it expand
01298                 ent->nextthink = level.time + 50;
01299         }
01300         else
01301         { //don't just leave the entity around
01302                 ent->think = G_FreeEntity;
01303                 ent->nextthink = level.time;
01304         }
01305 }

void DetPackBlow gentity_t self  ) 
 

Definition at line 2738 of file g_weapon.c.

References gentity_s::count, entityShared_t::currentOrigin, gentity_s::damage, gentity_s::die, EFFECT_EXPLOSION_DETPACK, G_Damage(), g_entities, G_FreeEntity(), G_PlayEffect(), G_RadiusDamage(), gentity_t, level, MOD_DET_PACK_SPLASH, gentity_s::nextthink, entityShared_t::ownerNum, gentity_s::pain, gentity_s::parent, gentity_s::pos2, qfalse, gentity_s::r, gentity_s::splashDamage, gentity_s::splashRadius, gentity_s::takedamage, gentity_s::target_ent, gentity_s::think, level_locals_t::time, vec3_t, and VectorCopy.

Referenced by BlowDetpacks(), charge_stick(), DetPackDie(), and DetPackPain().

02739 {
02740         vec3_t v;
02741 
02742         self->pain = 0;
02743         self->die = 0;
02744         self->takedamage = qfalse;
02745 
02746         if ( self->target_ent )
02747         {//we were attached to something, do *direct* damage to it!
02748                 G_Damage( self->target_ent, self, &g_entities[self->r.ownerNum], v, self->r.currentOrigin, self->damage, 0, MOD_DET_PACK_SPLASH );
02749         }
02750         G_RadiusDamage( self->r.currentOrigin, self->parent, self->splashDamage, self->splashRadius, self, self, MOD_DET_PACK_SPLASH );
02751         v[0] = 0;
02752         v[1] = 0;
02753         v[2] = 1;
02754 
02755         if (self->count == -1)
02756         {
02757                 VectorCopy(self->pos2, v);
02758         }
02759 
02760         G_PlayEffect(EFFECT_EXPLOSION_DETPACK, self->r.currentOrigin, v);
02761 
02762         self->think = G_FreeEntity;
02763         self->nextthink = level.time;
02764 }

void DetPackDie gentity_t self,
gentity_t inflictor,
gentity_t attacker,
int  damage,
int  mod
 

Definition at line 2773 of file g_weapon.c.

References DetPackBlow(), gentity_t, level, gentity_s::nextthink, Q_irand(), qfalse, gentity_s::takedamage, gentity_s::think, and level_locals_t::time.

Referenced by drop_charge().

02774 {
02775         self->think = DetPackBlow;
02776         self->nextthink = level.time + Q_irand(50, 100);
02777         self->takedamage = qfalse;
02778 }

void DetPackPain gentity_t self,
gentity_t attacker,
int  damage
 

Definition at line 2766 of file g_weapon.c.

References DetPackBlow(), gentity_t, level, gentity_s::nextthink, Q_irand(), qfalse, gentity_s::takedamage, gentity_s::think, and level_locals_t::time.

Referenced by drop_charge().

02767 {
02768         self->think = DetPackBlow;
02769         self->nextthink = level.time + Q_irand(50, 100);
02770         self->takedamage = qfalse;
02771 }

void drop_charge gentity_t self,
vec3_t  start,
vec3_t  dir
 

Definition at line 2780 of file g_weapon.c.

References entityState_s::angles, entityState_s::apos, charge_stick(), gentity_s::classname, gentity_s::clipmask, entityShared_t::contents, gentity_s::damage, DetPackDie(), DetPackPain(), gentity_s::die, ET_GENERAL, entityState_s::eType, FRAMETIME, entityState_s::g2radius, G_ModelIndex(), G_RunObject(), G_SetOrigin(), G_Spawn(), entityState_s::genericenemyindex, gentity_t, gentity_s::health, level, MASK_SHOT, MAX_GENTITIES, entityShared_t::maxs, gentity_s::methodOfDeath, entityShared_t::mins, MOD_DET_PACK_SPLASH, entityState_s::modelGhoul2, entityState_s::modelindex, gentity_s::nextthink, entityState_s::number, entityShared_t::ownerNum, gentity_s::pain, gentity_s::parent, gentity_s::physicsObject, PITCH, entityState_s::pos, qtrue, gentity_s::r, rand(), ROLL, gentity_s::s, gentity_s::setTime, entityState_s::solid, gentity_s::splashDamage, gentity_s::splashMethodOfDeath, gentity_s::splashRadius, gentity_s::takedamage, gentity_s::think, level_locals_t::time, gentity_s::touch, TR_GRAVITY, trap_LinkEntity(), trajectory_t::trBase, trajectory_t::trDelta, trajectory_t::trTime, trajectory_t::trType, vec3_t, vectoangles(), VectorCopy, VectorNormalize(), VectorScale, VectorSet, entityState_s::weapon, WP_DET_PACK, and YAW.

Referenced by WP_DropDetPack().

02781 {
02782         gentity_t       *bolt;
02783 
02784         VectorNormalize (dir);
02785 
02786         bolt = G_Spawn();
02787         bolt->classname = "detpack";
02788         bolt->nextthink = level.time + FRAMETIME;
02789         bolt->think = G_RunObject;
02790         bolt->s.eType = ET_GENERAL;
02791         bolt->s.g2radius = 100;
02792         bolt->s.modelGhoul2 = 1;
02793         bolt->s.modelindex = G_ModelIndex("models/weapons2/detpack/det_pack_proj.glm");
02794 
02795         bolt->parent = self;
02796         bolt->r.ownerNum = self->s.number;
02797         bolt->damage = 100;
02798         bolt->splashDamage = 200;
02799         bolt->splashRadius = 200;
02800         bolt->methodOfDeath = MOD_DET_PACK_SPLASH;
02801         bolt->splashMethodOfDeath = MOD_DET_PACK_SPLASH;
02802         bolt->clipmask = MASK_SHOT;
02803         bolt->s.solid = 2;
02804         bolt->r.contents = MASK_SHOT;
02805         bolt->touch = charge_stick;
02806 
02807         bolt->physicsObject = qtrue;
02808 
02809         bolt->s.genericenemyindex = self->s.number+MAX_GENTITIES;
02810         //rww - so client prediction knows we own this and won't hit it
02811 
02812         VectorSet( bolt->r.mins, -2, -2, -2 );
02813         VectorSet( bolt->r.maxs, 2, 2, 2 );
02814 
02815         bolt->health = 1;
02816         bolt->takedamage = qtrue;
02817         bolt->pain = DetPackPain;
02818         bolt->die = DetPackDie;
02819 
02820         bolt->s.weapon = WP_DET_PACK;
02821 
02822         bolt->setTime = level.time;
02823 
02824         G_SetOrigin(bolt, start);
02825         bolt->s.pos.trType = TR_GRAVITY;
02826         VectorCopy( start, bolt->s.pos.trBase );
02827         VectorScale(dir, 300, bolt->s.pos.trDelta );
02828         bolt->s.pos.trTime = level.time;
02829 
02830         bolt->s.apos.trType = TR_GRAVITY;
02831         bolt->s.apos.trTime = level.time;
02832         bolt->s.apos.trBase[YAW] = rand()%360;
02833         bolt->s.apos.trBase[PITCH] = rand()%360;
02834         bolt->s.apos.trBase[ROLL] = rand()%360;
02835 
02836         if (rand()%10 < 5)
02837         {
02838                 bolt->s.apos.trBase[YAW] = -bolt->s.apos.trBase[YAW];
02839         }
02840 
02841         vectoangles(dir, bolt->s.angles);
02842         VectorCopy(bolt->s.angles, bolt->s.apos.trBase);
02843         VectorSet(bolt->s.apos.trDelta, 300, 0, 0 );
02844         bolt->s.apos.trTime = level.time;
02845 
02846         trap_LinkEntity(bolt);
02847 }

void emplaced_gun_die gentity_t self,
gentity_t inflictor,
gentity_t attacker,
int  damage,
int  mod
 

Definition at line 4901 of file g_weapon.c.

References gentity_s::genericValue4, gentity_s::genericValue5, gentity_t, level, gentity_s::s, level_locals_t::time, and entityState_s::time.

Referenced by SP_emplaced_gun().

04902 { //set us up to flash and then explode
04903         if (self->genericValue4)
04904         {
04905                 return;
04906         }
04907 
04908         self->genericValue4 = 1;
04909 
04910         self->s.time = level.time + 3000;
04911 
04912         self->genericValue5 = 0;
04913 }

void emplaced_gun_pain gentity_t self,
gentity_t attacker,
int  damage
 

Definition at line 4781 of file g_weapon.c.

References BSET_PAIN, G_ActivateBehavior(), gentity_t, entityState_s::health, gentity_s::health, and gentity_s::s.

Referenced by SP_emplaced_gun().

04782 {
04783         self->s.health = self->health;
04784 
04785         if ( self->health <= 0 )
04786         {
04787                 //death effect.. for now taken care of on cgame
04788         }
04789         else
04790         {
04791                 //if we have a pain behavior set then use it I guess
04792                 G_ActivateBehavior( self, BSET_PAIN );
04793         }
04794 }

void emplaced_gun_realuse gentity_t self,
gentity_t other,
gentity_t activator
 

Definition at line 4775 of file g_weapon.c.

References emplaced_gun_use(), gentity_t, and NULL.

Referenced by SP_emplaced_gun().

04776 {
04777         emplaced_gun_use(self, other, NULL);
04778 }

void emplaced_gun_update gentity_t self  ) 
 

Definition at line 4799 of file g_weapon.c.

References gentity_s::activator, entityState_s::activeForcePass, BUTTON_USE, usercmd_s::buttons, gentity_s::client, clientPersistant_t::cmd, gentity_s::count, entityShared_t::currentOrigin, EFFECT_EXPLOSION_DETPACK, EFFECT_SMOKE, EMPLACED_CANRESPAWN, EMPLACED_GUN_HEALTH, playerState_s::emplacedIndex, playerState_s::emplacedTime, ENTITYNUM_NONE, G_PlayEffect(), G_RadiusDamage(), gentity_s::genericValue1, gentity_s::genericValue2, gentity_s::genericValue3, gentity_s::genericValue4, gentity_s::genericValue5, gentity_t, entityState_s::health, gentity_s::health, gentity_s::inuse, level, MOD_UNKNOWN, gentity_s::nextthink, NULL, entityState_s::number, playerState_s::origin, entityState_s::origin, entityShared_t::ownerNum, gclient_s::pers, gclient_s::ps, Q_irand(), gentity_s::r, gentity_s::s, playerState_s::saberHolstered, gentity_s::spawnflags, gentity_s::splashDamage, gentity_s::splashRadius, STAT_WEAPONS, playerState_s::stats, entityState_s::time, level_locals_t::time, vec3_t, VectorCopy, VectorSet, VectorSubtract, entityState_s::weapon, playerState_s::weapon, WEAPON_READY, playerState_s::weaponstate, and WP_EMPLACED_GUN.

Referenced by SP_emplaced_gun().

04800 {
04801         vec3_t  smokeOrg, puffAngle;
04802         int oldWeap;
04803         float ownLen = 0;
04804 
04805         if (self->health < 1 && !self->genericValue5)
04806         { //we are dead, set our respawn delay if we have one
04807                 if (self->spawnflags & EMPLACED_CANRESPAWN)
04808                 {
04809                         self->genericValue5 = level.time + 4000 + self->count;
04810                 }
04811         }
04812         else if (self->health < 1 && self->genericValue5 < level.time)
04813         { //we are dead, see if it's time to respawn
04814                 self->s.time = 0;
04815                 self->genericValue4 = 0;
04816                 self->genericValue3 = 0;
04817                 self->health = EMPLACED_GUN_HEALTH*0.4;
04818                 self->s.health = self->health;
04819         }
04820 
04821         if (self->genericValue4 && self->genericValue4 < 2 && self->s.time < level.time)
04822         { //we have finished our warning (red flashing) effect, it's time to finish dying
04823                 vec3_t explOrg;
04824 
04825                 VectorSet( puffAngle, 0, 0, 1 );
04826 
04827                 VectorCopy(self->r.currentOrigin, explOrg);
04828                 explOrg[2] += 16;
04829 
04830                 //just use the detpack explosion effect
04831                 G_PlayEffect(EFFECT_EXPLOSION_DETPACK, explOrg, puffAngle);
04832 
04833                 self->genericValue3 = level.time + Q_irand(2500, 3500);
04834 
04835                 G_RadiusDamage(self->r.currentOrigin, self, self->splashDamage, self->splashRadius, self, NULL, MOD_UNKNOWN);
04836 
04837                 self->s.time = -1;
04838 
04839                 self->genericValue4 = 2;
04840         }
04841 
04842         if (self->genericValue3 > level.time)
04843         { //see if we are freshly dead and should be smoking
04844                 if (self->genericValue2 < level.time)
04845                 { //is it time yet to spawn another smoke puff?
04846                         VectorSet( puffAngle, 0, 0, 1 );
04847                         VectorCopy(self->r.currentOrigin, smokeOrg);
04848 
04849                         smokeOrg[2] += 60;
04850 
04851                         G_PlayEffect(EFFECT_SMOKE, smokeOrg, puffAngle);
04852                         self->genericValue2 = level.time + Q_irand(250, 400);
04853                 }
04854         }
04855 
04856         if (self->activator && self->activator->client && self->activator->inuse)
04857         { //handle updating current user
04858                 vec3_t vLen;
04859                 VectorSubtract(self->s.origin, self->activator->client->ps.origin, vLen);
04860                 ownLen = VectorLength(vLen);
04861 
04862                 if (!(self->activator->client->pers.cmd.buttons & BUTTON_USE) && self->genericValue1)
04863                 {
04864                         self->genericValue1 = 0;
04865                 }
04866 
04867                 if ((self->activator->client->pers.cmd.buttons & BUTTON_USE) && !self->genericValue1)
04868                 {
04869                         self->activator->client->ps.emplacedIndex = 0;
04870                         self->activator->client->ps.saberHolstered = 0;
04871                         self->nextthink = level.time + 50;
04872                         return;
04873                 }
04874         }
04875 
04876         if ((self->activator && self->activator->client) &&
04877                 (!self->activator->inuse || self->activator->client->ps.emplacedIndex != self->s.number || self->genericValue4 || ownLen > 64))
04878         { //get the user off of me then
04879                 self->activator->client->ps.stats[STAT_WEAPONS] &= ~(1<<WP_EMPLACED_GUN);
04880 
04881                 oldWeap = self->activator->client->ps.weapon;
04882                 self->activator->client->ps.weapon = self->s.weapon;
04883                 self->s.weapon = oldWeap;
04884                 self->activator->r.ownerNum = ENTITYNUM_NONE;
04885                 self->activator->client->ps.emplacedTime = level.time + 1000;
04886                 self->activator->client->ps.emplacedIndex = 0;
04887                 self->activator->client->ps.saberHolstered = 0;
04888                 self->activator = NULL;
04889 
04890                 self->s.activeForcePass = 0;
04891         }
04892         else if (self->activator && self->activator->client)
04893         { //make sure the user is using the emplaced gun weapon
04894                 self->activator->client->ps.weapon = WP_EMPLACED_GUN;
04895                 self->activator->client->ps.weaponstate = WEAPON_READY;
04896         }
04897         self->nextthink = level.time + 50;
04898 }

void emplaced_gun_use gentity_t self,
gentity_t other,
trace_t trace
 

Definition at line 4662 of file g_weapon.c.

References gentity_s::activator, entityState_s::activeForcePass, AngleVectors(), gentity_s::client, entityShared_t::currentOrigin, DotProduct, playerState_s::emplacedIndex, entityState_s::emplacedOwner, playerState_s::emplacedTime, playerState_s::forceHandExtend, gentity_s::genericValue1, gentity_t, HANDEXTEND_NONE, gentity_s::health, playerState_s::isJediMaster, level, NULL, NUM_FORCE_POWERS, entityState_s::number, entityState_s::origin, playerState_s::origin, entityShared_t::ownerNum, playerState_s::pm_flags, PMF_DUCKED, gentity_s::pos1, gclient_s::ps, gentity_s::r, gentity_s::s, STAT_WEAPONS, playerState_s::stats, level_locals_t::time, TryHeal(), vec3_t, vectoangles(), VectorNormalize(), VectorSubtract, playerState_s::viewangles, playerState_s::weapon, entityState_s::weapon, WEAPON_READY, playerState_s::weaponstate, and WP_EMPLACED_GUN.

Referenced by emplaced_gun_realuse().

04663 {
04664         vec3_t fwd1, fwd2;
04665         float dot;
04666         int oldWeapon;
04667         gentity_t *activator = other;
04668         float zoffset = 50;
04669         vec3_t anglesToOwner;
04670         vec3_t vLen;
04671         float ownLen;
04672 
04673         if ( self->health <= 0 )
04674         { //gun is destroyed
04675                 return;
04676         }
04677 
04678         if (self->activator)
04679         { //someone is already using me
04680                 return;
04681         }
04682 
04683         if (!activator->client)
04684         {
04685                 return;
04686         }
04687 
04688         if (activator->client->ps.emplacedTime > level.time)
04689         { //last use attempt still too recent
04690                 return;
04691         }
04692 
04693         if (activator->client->ps.forceHandExtend != HANDEXTEND_NONE)
04694         { //don't use if busy doing something else
04695                 return;
04696         }
04697 
04698         if (activator->client->ps.origin[2] > self->s.origin[2]+zoffset-8)
04699         { //can't use it from the top
04700                 return;
04701         }
04702 
04703         if (activator->client->ps.pm_flags & PMF_DUCKED)
04704         { //must be standing
04705                 return;
04706         }
04707 
04708         if (activator->client->ps.isJediMaster)
04709         { //jm can't use weapons
04710                 return;
04711         }
04712 
04713         VectorSubtract(self->s.origin, activator->client->ps.origin, vLen);
04714         ownLen = VectorLength(vLen);
04715 
04716         if (ownLen > 64.0f)
04717         { //must be within 64 units of the gun to use at all
04718                 return;
04719         }
04720 
04721         // Let's get some direction vectors for the user
04722         AngleVectors( activator->client->ps.viewangles, fwd1, NULL, NULL );
04723 
04724         // Get the guns direction vector
04725         AngleVectors( self->pos1, fwd2, NULL, NULL );
04726 
04727         dot = DotProduct( fwd1, fwd2 );
04728 
04729         // Must be reasonably facing the way the gun points ( 110 degrees or so ), otherwise we don't allow to use it.
04730         if ( dot < -0.2f )
04731         {
04732                 goto tryHeal;
04733         }
04734 
04735         VectorSubtract(self->s.origin, activator->client->ps.origin, fwd1);
04736         VectorNormalize(fwd1);
04737 
04738         dot = DotProduct( fwd1, fwd2 );
04739 
04740         //check the positioning in relation to the gun as well
04741         if ( dot < 0.6f )
04742         {
04743                 goto tryHeal;
04744         }
04745 
04746         self->genericValue1 = 1;
04747 
04748         oldWeapon = activator->s.weapon;
04749 
04750         // swap the users weapon with the emplaced gun
04751         activator->client->ps.weapon = self->s.weapon;
04752         activator->client->ps.weaponstate = WEAPON_READY;
04753         activator->client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_EMPLACED_GUN );
04754 
04755         activator->client->ps.emplacedIndex = self->s.number;
04756 
04757         self->s.emplacedOwner = activator->s.number;
04758         self->s.activeForcePass = NUM_FORCE_POWERS+1;
04759 
04760         // the gun will track which weapon we used to have
04761         self->s.weapon = oldWeapon;
04762 
04763         //user's new owner becomes the gun ent
04764         activator->r.ownerNum = self->s.number;
04765         self->activator = activator;
04766 
04767         VectorSubtract(self->r.currentOrigin, activator->client->ps.origin, anglesToOwner);
04768         vectoangles(anglesToOwner, anglesToOwner);
04769         return;
04770 
04771 tryHeal: //well, not in the right dir, try healing it instead...
04772         TryHeal(activator, self);
04773 }

void FireVehicleWeapon gentity_t ent,
qboolean  alt_fire
 

Definition at line 4087 of file g_weapon.c.

References vehWeaponStats_t::aimCorrect, trace_t::allsolid, vehWeaponStatus_t::ammo, AngleVectors(), gentity_s::client, entityShared_t::currentOrigin, vehWeaponStats_t::delay, playerState_s::electrifyTime, trace_t::endpos, trace_t::entityNum, ENTITYNUM_NONE, EV_NOAMMO, vehWeaponInfo_t::fHoming, trace_t::fraction, G_AddEvent(), g_entities, G_VehMuzzleFireFX(), g_vehWeaponInfo, gentity_t, vehWeaponInfo_t::iAmmoPerShot, vehWeaponStats_t::ID, level, vehWeaponStats_t::linkable, vehWeaponStatus_t::linked, Vehicle_s::m_iMuzzleTag, Vehicle_s::m_iMuzzleWait, Vehicle_s::m_iRemovedSurfaces, Vehicle_s::m_pParentEntity, Vehicle_s::m_pPilot, gentity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, Vehicle_s::m_ulFlags, Vehicle_s::m_vMuzzleDir, Vehicle_s::m_vMuzzlePos, Vehicle_s::m_vOrientation, MASK_SHOT, MAX_CLIENTS, MAX_VEH_WEAPONS, MAX_VEHICLE_MUZZLES, vehWeaponStatus_t::nextMuzzle, NULL, entityState_s::number, gclient_s::ps, qboolean, qfalse, qtrue, gentity_s::r, playerState_s::rocketLockIndex, playerState_s::rocketLockTime, playerState_s::rocketTargetTime, gentity_s::s, bgEntity_s::s, trace_t::startsolid, level_locals_t::time, trap_Trace(), vehicleInfo_t::type, vec3_origin, vec3_t, VectorCopy, VectorMA, VectorSet, VEH_WEAPON_NONE, VEH_WINGSOPEN, Vehicle_t, VH_FIGHTER, VH_SPEEDER, VH_WALKER, vehicleInfo_t::weapMuzzle, vehicleInfo_t::weapon, Vehicle_s::weaponStatus, WP_CalcVehMuzzle(), WP_FireVehicleWeapon(), WP_VehCheckTraceFromCamPos(), and WP_VehLeadCrosshairVeh().

Referenced by FireWeapon().

04089 {
04090         Vehicle_t *pVeh = ent->m_pVehicle;
04091         int muzzlesFired = 0;
04092         gentity_t *missile = NULL;
04093         vehWeaponInfo_t *vehWeapon = NULL;
04094         qboolean        clearRocketLockEntity = qfalse;
04095         
04096         if ( !pVeh )
04097         {
04098                 return;
04099         }
04100 
04101         if (pVeh->m_iRemovedSurfaces)
04102         { //can't fire when the thing is breaking apart
04103                 return;
04104         }
04105 
04106         if (pVeh->m_pVehicleInfo->type == VH_WALKER &&
04107                 ent->client->ps.electrifyTime > level.time)
04108         { //don't fire while being electrocuted
04109                 return;
04110         }
04111 
04112         // TODO?: If possible (probably not enough time), it would be nice if secondary fire was actually a mode switch/toggle
04113         // so that, for instance, an x-wing can have 4-gun fire, or individual muzzle fire. If you wanted a different weapon, you
04114         // would actually have to press the 2 key or something like that (I doubt I'd get a graphic for it anyways though). -AReis
04115 
04116         // If this is not the alternate fire, fire a normal blaster shot...
04117         if ( pVeh->m_pVehicleInfo &&
04118                 (pVeh->m_pVehicleInfo->type != VH_FIGHTER || (pVeh->m_ulFlags&VEH_WINGSOPEN)) ) // NOTE: Wings open also denotes that it has already launched.
04119         {//fighters can only fire when wings are open
04120                 int     weaponNum = 0, vehWeaponIndex = VEH_WEAPON_NONE;
04121                 int     delay = 1000;
04122                 qboolean aimCorrect = qfalse;
04123                 qboolean linkedFiring = qfalse;
04124 
04125                 if ( !alt_fire )
04126                 {
04127                         weaponNum = 0;
04128                 }
04129                 else
04130                 {
04131                         weaponNum = 1;
04132                 }
04133 
04134                 vehWeaponIndex = pVeh->m_pVehicleInfo->weapon[weaponNum].ID;
04135 
04136                 if ( pVeh->weaponStatus[weaponNum].ammo <= 0 )
04137                 {//no ammo for this weapon
04138                         if ( pVeh->m_pPilot && pVeh->m_pPilot->s.number < MAX_CLIENTS )
04139                         {// let the client know he's out of ammo
04140                                 int i;
04141                                 //but only if one of the vehicle muzzles is actually ready to fire this weapon
04142                                 for ( i = 0; i < MAX_VEHICLE_MUZZLES; i++ )
04143                                 {
04144                                         if ( pVeh->m_pVehicleInfo->weapMuzzle[i] != vehWeaponIndex )
04145                                         {//this muzzle doesn't match the weapon we're trying to use
04146                                                 continue;
04147                                         }
04148                                         if ( pVeh->m_iMuzzleTag[i] != -1 
04149                                                 && pVeh->m_iMuzzleWait[i] < level.time )
04150                                         {//this one would have fired, send the no ammo message
04151                                                 G_AddEvent( (gentity_t*)pVeh->m_pPilot, EV_NOAMMO, weaponNum );
04152                                                 break;
04153                                         }
04154                                 }
04155                         }
04156                         return;
04157                 }
04158 
04159                 delay = pVeh->m_pVehicleInfo->weapon[weaponNum].delay;
04160                 aimCorrect = pVeh->m_pVehicleInfo->weapon[weaponNum].aimCorrect;
04161                 if ( pVeh->m_pVehicleInfo->weapon[weaponNum].linkable == 2//always linked
04162                         || ( pVeh->m_pVehicleInfo->weapon[weaponNum].linkable == 1//optionally linkable
04163                                  && pVeh->weaponStatus[weaponNum].linked ) )//linked
04164                 {//we're linking the primary or alternate weapons, so we'll do *all* the muzzles
04165                         linkedFiring = qtrue;
04166                 }
04167 
04168                 if ( vehWeaponIndex <= VEH_WEAPON_BASE || vehWeaponIndex >= MAX_VEH_WEAPONS )
04169                 {//invalid vehicle weapon
04170                         return;
04171                 }
04172                 else
04173                 {
04174                         int i, numMuzzles = 0, numMuzzlesReady = 0, cumulativeDelay = 0, cumulativeAmmo = 0;
04175                         qboolean sentAmmoWarning = qfalse;
04176 
04177                         vehWeapon = &g_vehWeaponInfo[vehWeaponIndex];
04178 
04179                         if ( pVeh->m_pVehicleInfo->weapon[weaponNum].linkable == 2 )
04180                         {//always linked weapons don't accumulate delay, just use specified delay
04181                                 cumulativeDelay = delay;
04182                         }
04183                         //find out how many we've got for this weapon
04184                         for ( i = 0; i < MAX_VEHICLE_MUZZLES; i++ )
04185                         {
04186                                 if ( pVeh->m_pVehicleInfo->weapMuzzle[i] != vehWeaponIndex )
04187                                 {//this muzzle doesn't match the weapon we're trying to use
04188                                         continue;
04189                                 }
04190                                 if ( pVeh->m_iMuzzleTag[i] != -1 && pVeh->m_iMuzzleWait[i] < level.time )
04191                                 {
04192                                         numMuzzlesReady++;
04193                                 }
04194                                 if ( pVeh->m_pVehicleInfo->weapMuzzle[pVeh->weaponStatus[weaponNum].nextMuzzle] != vehWeaponIndex )
04195                                 {//Our designated next muzzle for this weapon isn't valid for this weapon (happens when ships fire for the first time)
04196                                         //set the next to this one
04197                                         pVeh->weaponStatus[weaponNum].nextMuzzle = i;
04198                                 }
04199                                 if ( linkedFiring )
04200                                 {
04201                                         cumulativeAmmo += vehWeapon->iAmmoPerShot;
04202                                         if ( pVeh->m_pVehicleInfo->weapon[weaponNum].linkable != 2 )
04203                                         {//always linked weapons don't accumulate delay, just use specified delay
04204                                                 cumulativeDelay += delay;
04205                                         }
04206                                 }
04207                                 numMuzzles++;
04208                         }
04209 
04210                         if ( linkedFiring )
04211                         {//firing all muzzles at once
04212                                 if ( numMuzzlesReady != numMuzzles )
04213                                 {//can't fire all linked muzzles yet
04214                                         return;
04215                                 }
04216                                 else 
04217                                 {//can fire all linked muzzles, check ammo
04218                                         if ( pVeh->weaponStatus[weaponNum].ammo < cumulativeAmmo )
04219                                         {//can't fire, not enough ammo
04220                                                 if ( pVeh->m_pPilot && pVeh->m_pPilot->s.number < MAX_CLIENTS )
04221                                                 {// let the client know he's out of ammo
04222                                                         G_AddEvent( (gentity_t*)pVeh->m_pPilot, EV_NOAMMO, weaponNum );
04223                                                 }
04224                                                 return;
04225                                         }
04226                                 }
04227                         }
04228 
04229                         for ( i = 0; i < MAX_VEHICLE_MUZZLES; i++ )
04230                         {
04231                                 if ( pVeh->m_pVehicleInfo->weapMuzzle[i] != vehWeaponIndex )
04232                                 {//this muzzle doesn't match the weapon we're trying to use
04233                                         continue;
04234                                 }
04235                                 if ( !linkedFiring
04236                                         && i != pVeh->weaponStatus[weaponNum].nextMuzzle )
04237                                 {//we're only firing one muzzle and this isn't it
04238                                         continue;
04239                                 }
04240 
04241                                 // Fire this muzzle.
04242                                 if ( pVeh->m_iMuzzleTag[i] != -1 && pVeh->m_iMuzzleWait[i] < level.time )
04243                                 {
04244                                         vec3_t  start, dir;
04245                                         
04246                                         if ( pVeh->weaponStatus[weaponNum].ammo < vehWeapon->iAmmoPerShot )
04247                                         {//out of ammo!
04248                                                 if ( !sentAmmoWarning )
04249                                                 {
04250                                                         sentAmmoWarning = qtrue;
04251                                                         if ( pVeh->m_pPilot && pVeh->m_pPilot->s.number < MAX_CLIENTS )
04252                                                         {// let the client know he's out of ammo
04253                                                                 G_AddEvent( (gentity_t*)pVeh->m_pPilot, EV_NOAMMO, weaponNum );
04254                                                         }
04255                                                 }
04256                                         }
04257                                         else
04258                                         {//have enough ammo to shoot
04259                                                 //do the firing
04260                                                 WP_CalcVehMuzzle(ent, i);
04261                                                 VectorCopy( pVeh->m_vMuzzlePos[i], start );
04262                                                 VectorCopy( pVeh->m_vMuzzleDir[i], dir );
04263                                                 if ( WP_VehCheckTraceFromCamPos( ent, start, dir ) )
04264                                                 {//auto-aim at whatever crosshair would be over from camera's point of view (if closer)
04265                                                 }
04266                                                 else if ( aimCorrect )
04267                                                 {//auto-aim the missile at the crosshair if there's anything there
04268                                                         trace_t trace;
04269                                                         vec3_t  end;
04270                                                         vec3_t  ang;
04271                                                         vec3_t  fixedDir;
04272 
04273                                                         if (pVeh->m_pVehicleInfo->type == VH_SPEEDER)
04274                                                         {
04275                                                                 VectorSet(ang, 0.0f, pVeh->m_vOrientation[1], 0.0f);
04276                                                         }
04277                                                         else
04278                                                         {
04279                                                                 VectorCopy(pVeh->m_vOrientation, ang);
04280                                                         }
04281                                                         AngleVectors( ang, fixedDir, NULL, NULL );
04282                                                         VectorMA( ent->r.currentOrigin, 32768, fixedDir, end );
04283                                                         //VectorMA( ent->r.currentOrigin, 8192, dir, end );
04284                                                         trap_Trace( &trace, ent->r.currentOrigin, vec3_origin, vec3_origin, end, ent->s.number, MASK_SHOT );
04285                                                         if ( trace.fraction < 1.0f && !trace.allsolid && !trace.startsolid )
04286                                                         {
04287                                                                 vec3_t newEnd;
04288                                                                 VectorCopy( trace.endpos, newEnd );
04289                                                                 WP_VehLeadCrosshairVeh( &g_entities[trace.entityNum], newEnd, fixedDir, start, dir );
04290                                                         }
04291                                                 }
04292 
04293                                                 //play the weapon's muzzle effect if we have one
04294                                                 //NOTE: just need MAX_VEHICLE_MUZZLES bits for this... should be cool since it's currently 12 and we're sending it in 16 bits
04295                                                 muzzlesFired |= (1<<i);
04296                                                                                                 
04297                                                 missile = WP_FireVehicleWeapon( ent, start, dir, vehWeapon, alt_fire, qfalse );
04298                                                 if ( vehWeapon->fHoming )
04299                                                 {//clear the rocket lock entity *after* all muzzles have fired
04300                                                         clearRocketLockEntity = qtrue;
04301                                                 }
04302                                         }
04303 
04304                                         if ( linkedFiring )
04305                                         {//we're linking the weapon, so continue on and fire all appropriate muzzles
04306                                                 continue;
04307                                         }
04308                                         //else just firing one
04309                                         //take the ammo, set the next muzzle and set the delay on it
04310                                         if ( numMuzzles > 1 )
04311                                         {//more than one, look for it
04312                                                 int nextMuzzle = pVeh->weaponStatus[weaponNum].nextMuzzle;
04313                                                 while ( 1 )
04314                                                 {
04315                                                         nextMuzzle++;
04316                                                         if ( nextMuzzle >= MAX_VEHICLE_MUZZLES )
04317                                                         {
04318                                                                 nextMuzzle = 0;
04319                                                         }
04320                                                         if ( nextMuzzle == pVeh->weaponStatus[weaponNum].nextMuzzle )
04321                                                         {//WTF?  Wrapped without finding another valid one!
04322                                                                 break;
04323                                                         }
04324                                                         if ( pVeh->m_pVehicleInfo->weapMuzzle[nextMuzzle] == vehWeaponIndex )
04325                                                         {//this is the next muzzle for this weapon
04326                                                                 pVeh->weaponStatus[weaponNum].nextMuzzle = nextMuzzle;
04327                                                                 break;
04328                                                         }
04329                                                 }
04330                                         }//else, just stay on the one we just fired
04331                                         //set the delay on the next muzzle
04332                                         pVeh->m_iMuzzleWait[pVeh->weaponStatus[weaponNum].nextMuzzle] = level.time + delay;
04333                                         //take away the ammo
04334                                         pVeh->weaponStatus[weaponNum].ammo -= vehWeapon->iAmmoPerShot;
04335                                         //NOTE: in order to send the vehicle's ammo info to the client, we copy the ammo into the first 2 ammo slots on the vehicle NPC's client->ps.ammo array
04336                                         if ( pVeh->m_pParentEntity && ((gentity_t*)(pVeh->m_pParentEntity))->client )
04337                                         {
04338                                                 ((gentity_t*)(pVeh->m_pParentEntity))->client->ps.ammo[weaponNum] = pVeh->weaponStatus[weaponNum].ammo;
04339                                         }
04340                                         //done!
04341                                         //we'll get in here again next frame and try the next muzzle...
04342                                         //return;
04343                                         goto tryFire;
04344                                 }
04345                         }
04346                         //we went through all the muzzles, so apply the cumulative delay and ammo cost
04347                         if ( cumulativeAmmo )
04348                         {//taking ammo one shot at a time
04349                                 //take the ammo
04350                                 pVeh->weaponStatus[weaponNum].ammo -= cumulativeAmmo;
04351                                 //NOTE: in order to send the vehicle's ammo info to the client, we copy the ammo into the first 2 ammo slots on the vehicle NPC's client->ps.ammo array
04352                                 if ( pVeh->m_pParentEntity && ((gentity_t*)(pVeh->m_pParentEntity))->client )
04353                                 {
04354                                         ((gentity_t*)(pVeh->m_pParentEntity))->client->ps.ammo[weaponNum] = pVeh->weaponStatus[weaponNum].ammo;
04355                                 }
04356                         }
04357                         if ( cumulativeDelay )
04358                         {//we linked muzzles so we need to apply the cumulative delay now, to each of the linked muzzles
04359                                 for ( i = 0; i < MAX_VEHICLE_MUZZLES; i++ )
04360                                 {
04361                                         if ( pVeh->m_pVehicleInfo->weapMuzzle[i] != vehWeaponIndex )
04362                                         {//this muzzle doesn't match the weapon we're trying to use
04363                                                 continue;
04364                                         }
04365                                         //apply the cumulative delay
04366                                         pVeh->m_iMuzzleWait[i] = level.time + cumulativeDelay;
04367                                 }
04368                         }
04369                 }
04370         }
04371 
04372 tryFire:
04373         if ( clearRocketLockEntity )
04374         {//hmm, should probably clear that anytime any weapon fires?
04375                 ent->client->ps.rocketLockIndex = ENTITYNUM_NONE;
04376                 ent->client->ps.rocketLockTime = 0;
04377                 ent->client->ps.rocketTargetTime = 0;
04378         }
04379 
04380         if ( vehWeapon && muzzlesFired > 0 )
04381         {
04382                 G_VehMuzzleFireFX(ent, missile, muzzlesFired );
04383         }
04384 }

void FireWeapon gentity_t ent,
qboolean  altFire
 

Definition at line 4395 of file g_weapon.c.

References gclient_s::accuracy_shots, entityState_s::angles, AngleVectors(), BG_EmplacedView(), CalcMuzzlePoint(), CLASS_VEHICLE, gentity_s::client, clientPersistant_t::cmd, playerState_s::emplacedIndex, gclient_s::ewebIndex, FireVehicleWeapon(), FLECHETTE_SHOTS, g_entities, G_LogWeaponFire(), g_quadfactor, gentity_t, gentity_s::inuse, playerState_s::m_iVehicleNum, gentity_s::m_pVehicle, Vehicle_s::m_vOrientation, MAX_CLIENTS, gclient_s::NPC_class, entityState_s::number, entityState_s::origin2, gclient_s::pers, PITCH, playerState_s::powerups, gclient_s::ps, PW_QUAD, qfalse, usercmd_s::rightmove, gentity_s::s, vmCvar_t::value, vec3_t, VectorCopy, playerState_s::viewangles, entityState_s::weapon, WP_BLASTER, WP_BOWCASTER, WP_BRYAR_OLD, WP_BRYAR_PISTOL, WP_CONCUSSION, WP_DEMP2, WP_DET_PACK, WP_DISRUPTOR, WP_DropDetPack(), WP_EMPLACED_GUN, WP_FireMelee(), WP_FireStunBaton(), WP_FireThermalDetonator(), WP_FLECHETTE, WP_MELEE, WP_PlaceLaserTrap(), WP_REPEATER, WP_ROCKET_LAUNCHER, WP_SABER, WP_STUN_BATON, WP_THERMAL, WP_TRIP_MINE, and YAW.

Referenced by ClientEvents(), G_CheapWeaponFire(), and misc_weapon_shooter_fire().

04395                                                     {
04396         if (ent->client->ps.powerups[PW_QUAD] ) {
04397                 s_quadFactor = g_quadfactor.value;
04398         } else {
04399                 s_quadFactor = 1;
04400         }
04401 
04402         // track shots taken for accuracy tracking.  Grapple is not a weapon and gauntet is just not tracked
04403         if( ent->s.weapon != WP_SABER && ent->s.weapon != WP_STUN_BATON && ent->s.weapon != WP_MELEE ) 
04404         {
04405                 if( ent->s.weapon == WP_FLECHETTE ) {
04406                         ent->client->accuracy_shots += FLECHETTE_SHOTS;
04407                 } else {
04408                         ent->client->accuracy_shots++;
04409                 }
04410         }
04411 
04412         if ( ent && ent->client && ent->client->NPC_class == CLASS_VEHICLE )
04413         {
04414                 FireVehicleWeapon( ent, altFire );
04415                 return;
04416         }
04417         else
04418         {
04419                 // set aiming directions
04420                 if (ent->s.weapon == WP_EMPLACED_GUN &&
04421                         ent->client->ps.emplacedIndex)
04422                 { //if using emplaced then base muzzle point off of gun position/angles
04423                         gentity_t *emp = &g_entities[ent->client->ps.emplacedIndex];
04424 
04425                         if (emp->inuse)
04426                         {
04427                                 float yaw;
04428                                 vec3_t viewAngCap;
04429                                 int override;
04430 
04431                                 VectorCopy(ent->client->ps.viewangles, viewAngCap);
04432                                 if (viewAngCap[PITCH] > 40)
04433                                 {
04434                                         viewAngCap[PITCH] = 40;
04435                                 }
04436 
04437                                 override = BG_EmplacedView(ent->client->ps.viewangles, emp->s.angles, &yaw,
04438                                         emp->s.origin2[0]);
04439                                 
04440                                 if (override)
04441                                 {
04442                                         viewAngCap[YAW] = yaw;
04443                                 }
04444 
04445                                 AngleVectors( viewAngCap, forward, vright, up );
04446                         }
04447                         else
04448                         {
04449                                 AngleVectors( ent->client->ps.viewangles, forward, vright, up );
04450                         }
04451                 }
04452                 else if (ent->s.number < MAX_CLIENTS &&
04453                         ent->client->ps.m_iVehicleNum && ent->s.weapon == WP_BLASTER)
04454                 { //riding a vehicle...with blaster selected
04455                         vec3_t vehTurnAngles;
04456                         gentity_t *vehEnt = &g_entities[ent->client->ps.m_iVehicleNum];
04457 
04458                         if (vehEnt->inuse && vehEnt->client && vehEnt->m_pVehicle)
04459                         {
04460                                 VectorCopy(vehEnt->m_pVehicle->m_vOrientation, vehTurnAngles);
04461                                 vehTurnAngles[PITCH] = ent->client->ps.viewangles[PITCH];
04462                         }
04463                         else
04464                         {
04465                                 VectorCopy(ent->client->ps.viewangles, vehTurnAngles);
04466                         }
04467                         if (ent->client->pers.cmd.rightmove > 0)
04468                         { //shooting to right
04469                                 vehTurnAngles[YAW] -= 90.0f;
04470                         }
04471                         else if (ent->client->pers.cmd.rightmove < 0)
04472                         { //shooting to left
04473                                 vehTurnAngles[YAW] += 90.0f;
04474                         }
04475 
04476                         AngleVectors( vehTurnAngles, forward, vright, up );
04477                 }
04478                 else
04479                 {
04480                         AngleVectors( ent->client->ps.viewangles, forward, vright, up );
04481                 }
04482 
04483                 CalcMuzzlePoint ( ent, forward, vright, up, muzzle );
04484 
04485                 // fire the specific weapon
04486                 switch( ent->s.weapon ) {
04487                 case WP_STUN_BATON:
04488                         WP_FireStunBaton( ent, altFire );
04489                         break;
04490 
04491                 case WP_MELEE:
04492                         WP_FireMelee(ent, altFire);
04493                         break;
04494 
04495                 case WP_SABER:
04496                         break;
04497 
04498                 case WP_BRYAR_PISTOL:
04499                         //if ( g_gametype.integer == GT_SIEGE )
04500                         if (1)
04501                         {//allow alt-fire
04502                                 WP_FireBryarPistol( ent, altFire );
04503                         }
04504                         else
04505                         {
04506                                 WP_FireBryarPistol( ent, qfalse );
04507                         }
04508                         break;
04509 
04510                 case WP_CONCUSSION:
04511                         if ( altFire )
04512                         {
04513                                 WP_FireConcussionAlt( ent );
04514                         }
04515                         else
04516                         {
04517                                 WP_FireConcussion( ent );
04518                         }
04519                         break;
04520 
04521                 case WP_BRYAR_OLD:
04522                         WP_FireBryarPistol( ent, altFire );
04523                         break;
04524 
04525                 case WP_BLASTER:
04526                         WP_FireBlaster( ent, altFire );
04527                         break;
04528 
04529                 case WP_DISRUPTOR:
04530                         WP_FireDisruptor( ent, altFire );
04531                         break;
04532 
04533                 case WP_BOWCASTER:
04534                         WP_FireBowcaster( ent, altFire );
04535                         break;
04536 
04537                 case WP_REPEATER:
04538                         WP_FireRepeater( ent, altFire );
04539                         break;
04540 
04541                 case WP_DEMP2:
04542                         WP_FireDEMP2( ent, altFire );
04543                         break;
04544 
04545                 case WP_FLECHETTE:
04546                         WP_FireFlechette( ent, altFire );
04547                         break;
04548 
04549                 case WP_ROCKET_LAUNCHER:
04550                         WP_FireRocket( ent, altFire );
04551                         break;
04552 
04553                 case WP_THERMAL:
04554                         WP_FireThermalDetonator( ent, altFire );
04555                         break;
04556 
04557                 case WP_TRIP_MINE:
04558                         WP_PlaceLaserTrap( ent, altFire );
04559                         break;
04560 
04561                 case WP_DET_PACK:
04562                         WP_DropDetPack( ent, altFire );
04563                         break;
04564 
04565                 case WP_EMPLACED_GUN:
04566                         if (ent->client && ent->client->ewebIndex)
04567                         { //specially handled by the e-web itself
04568                                 break;
04569                         }
04570                         WP_FireEmplaced( ent, altFire );
04571                         break;
04572                 default:
04573 //                      assert(!"unknown weapon fire");
04574                         break;
04575                 }
04576         }
04577 
04578         G_LogWeaponFire(ent->s.number, ent->s.weapon);
04579 }

qboolean G_BoxInBounds vec3_t  point,
vec3_t  mins,
vec3_t  maxs,
vec3_t  boundsMins,
vec3_t  boundsMaxs
 

Definition at line 1896 of file g_utils.c.

References qboolean, qfalse, qtrue, vec3_t, and VectorAdd.

Referenced by W_TraceSetStart().

01897 {
01898         vec3_t boxMins;
01899         vec3_t boxMaxs;
01900 
01901         VectorAdd( point, mins, boxMins );
01902         VectorAdd( point, maxs, boxMaxs );
01903 
01904         if(boxMaxs[0]>boundsMaxs[0])
01905                 return qfalse;
01906 
01907         if(boxMaxs[1]>boundsMaxs[1])
01908                 return qfalse;
01909 
01910         if(boxMaxs[2]>boundsMaxs[2])
01911                 return qfalse;
01912 
01913         if(boxMins[0]<boundsMins[0])
01914                 return qfalse;
01915 
01916         if(boxMins[1]<boundsMins[1])
01917                 return qfalse;
01918 
01919         if(boxMins[2]<boundsMins[2])
01920                 return qfalse;
01921 
01922         //box is completely contained within bounds
01923         return qtrue;
01924 }

qboolean G_CanDisruptify gentity_t ent  ) 
 

Definition at line 622 of file g_weapon.c.

References CLASS_VEHICLE, gentity_s::client, ET_NPC, entityState_s::eType, gentity_t, gentity_s::inuse, gentity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, entityState_s::NPC_class, qboolean, qfalse, qtrue, gentity_s::s, vehicleInfo_t::type, and VH_ANIMAL.

Referenced by WP_DisruptorAltFire().

00623 {
00624         if (!ent || !ent->inuse || !ent->client || ent->s.eType != ET_NPC ||
00625                 ent->s.NPC_class != CLASS_VEHICLE || !ent->m_pVehicle)
00626         { //not vehicle
00627                 return qtrue;
00628         }
00629 
00630         if (ent->m_pVehicle->m_pVehicleInfo->type == VH_ANIMAL)
00631         { //animal is only type that can be disintigeiteigerated
00632                 return qtrue;
00633         }
00634 
00635         //don't do it to any other veh
00636         return qfalse;
00637 }

void G_EstimateCamPos vec3_t  viewAngles,
vec3_t  cameraFocusLoc,
float  viewheight,
float  thirdPersonRange,
float  thirdPersonHorzOffset,
float  vertOffset,
float  pitchOffset,
int  ignoreEntNum,
vec3_t  camPos
 

Definition at line 3868 of file g_weapon.c.

References AngleNormalize180(), AnglesToAxis(), AngleVectors(), bg_fighterAltControl, CAMERA_SIZE, cameraCurLoc, cameraCurTarget, cameraFocusAngles, cameraFocusLoc, camerafwd, cameraIdealLoc, cameraIdealTarget, cameraup, CONTENTS_PLAYERCLIP, trace_t::endpos, trace_t::fraction, vmCvar_t::integer, MASK_CAMERACLIP, MASK_SOLID, NULL, PITCH, trap_Trace(), vec3_t, vectoangles(), VectorCopy, VectorMA, VectorNormalize(), VectorSet, and VectorSubtract.

Referenced by WP_GetVehicleCamPos().

03871 {
03872         int             MASK_CAMERACLIP = (MASK_SOLID|CONTENTS_PLAYERCLIP);
03873         float   CAMERA_SIZE = 4;
03874         vec3_t  cameramins;
03875         vec3_t  cameramaxs;
03876         vec3_t  cameraFocusAngles, camerafwd, cameraup;
03877         vec3_t  cameraIdealTarget, cameraCurTarget;
03878         vec3_t  cameraIdealLoc, cameraCurLoc;
03879         vec3_t  diff;
03880         vec3_t  camAngles;
03881         vec3_t  viewaxis[3];
03882         trace_t trace;
03883 
03884         VectorSet( cameramins, -CAMERA_SIZE, -CAMERA_SIZE, -CAMERA_SIZE );
03885         VectorSet( cameramaxs, CAMERA_SIZE, CAMERA_SIZE, CAMERA_SIZE );
03886 
03887         VectorCopy( viewAngles, cameraFocusAngles );
03888         cameraFocusAngles[PITCH] += pitchOffset;
03889         if ( !bg_fighterAltControl.integer )
03890         {//clamp view pitch
03891                 cameraFocusAngles[PITCH] = AngleNormalize180( cameraFocusAngles[PITCH] );
03892                 if (cameraFocusAngles[PITCH] > 80.0)
03893                 {
03894                         cameraFocusAngles[PITCH] = 80.0;
03895                 }
03896                 else if (cameraFocusAngles[PITCH] < -80.0)
03897                 {
03898                         cameraFocusAngles[PITCH] = -80.0;
03899                 }
03900         }
03901         AngleVectors(cameraFocusAngles, camerafwd, NULL, cameraup);
03902 
03903         cameraFocusLoc[2] += viewheight;
03904 
03905         VectorCopy( cameraFocusLoc, cameraIdealTarget );
03906         cameraIdealTarget[2] += vertOffset;
03907 
03908         //NOTE: on cgame, this uses the thirdpersontargetdamp value, we ignore that here
03909         VectorCopy( cameraIdealTarget, cameraCurTarget );
03910         trap_Trace( &trace, cameraFocusLoc, cameramins, cameramaxs, cameraCurTarget, ignoreEntNum, MASK_CAMERACLIP );
03911         if (trace.fraction < 1.0)
03912         {
03913                 VectorCopy(trace.endpos, cameraCurTarget);
03914         }
03915 
03916         VectorMA(cameraIdealTarget, -(thirdPersonRange), camerafwd, cameraIdealLoc);
03917         //NOTE: on cgame, this uses the thirdpersoncameradamp value, we ignore that here
03918         VectorCopy( cameraIdealLoc, cameraCurLoc );
03919         trap_Trace(&trace, cameraCurTarget, cameramins, cameramaxs, cameraCurLoc, ignoreEntNum, MASK_CAMERACLIP);
03920         if (trace.fraction < 1.0)
03921         {
03922                 VectorCopy( trace.endpos, cameraCurLoc );
03923         }
03924 
03925         VectorSubtract(cameraCurTarget, cameraCurLoc, diff);
03926         {
03927                 float dist = VectorNormalize(diff);
03928                 //under normal circumstances, should never be 0.00000 and so on.
03929                 if ( !dist || (diff[0] == 0 || diff[1] == 0) )
03930                 {//must be hitting something, need some value to calc angles, so use cam forward
03931                         VectorCopy( camerafwd, diff );
03932                 }
03933         }
03934 
03935         vectoangles(diff, camAngles);
03936 
03937         if ( thirdPersonHorzOffset != 0.0f )
03938         {
03939                 AnglesToAxis( camAngles, viewaxis );
03940                 VectorMA( cameraCurLoc, thirdPersonHorzOffset, viewaxis[1], cameraCurLoc );
03941         }
03942 
03943         VectorCopy(cameraCurLoc, camPos);
03944 }

void G_ExplodeMissile gentity_t ent  ) 
 

Definition at line 215 of file g_missile.c.

References gentity_s::activator, BG_EvaluateTrajectory(), entityShared_t::currentOrigin, DirToByte(), ET_GENERAL, entityState_s::eType, EV_MISSILE_MISS, gentity_s::freeAfterEvent, G_AddEvent(), g_entities, G_RadiusDamage(), G_SetOrigin(), gentity_t, level, entityState_s::number, gentity_s::parent, entityState_s::pos, qfalse, qtrue, gentity_s::r, gentity_s::s, gentity_s::splashDamage, gentity_s::splashMethodOfDeath, gentity_s::splashRadius, gentity_s::takedamage, level_locals_t::time, trap_LinkEntity(), and vec3_t.

Referenced by RocketDie().

00215                                         {
00216         vec3_t          dir;
00217         vec3_t          origin;
00218 
00219         BG_EvaluateTrajectory( &ent->s.pos, level.time, origin );
00220         SnapVector( origin );
00221         G_SetOrigin( ent, origin );
00222 
00223         // we don't have a valid direction, so just point straight up
00224         dir[0] = dir[1] = 0;
00225         dir[2] = 1;
00226 
00227         ent->s.eType = ET_GENERAL;
00228         G_AddEvent( ent, EV_MISSILE_MISS, DirToByte( dir ) );
00229 
00230         ent->freeAfterEvent = qtrue;
00231 
00232         ent->takedamage = qfalse;
00233         // splash damage
00234         if ( ent->splashDamage ) {
00235                 if( G_RadiusDamage( ent->r.currentOrigin, ent->parent, ent->splashDamage, ent->splashRadius, ent, 
00236                                 ent, ent->splashMethodOfDeath ) ) 
00237                 {
00238                         if (ent->parent)
00239                         {
00240                                 g_entities[ent->parent->s.number].client->accuracy_hits++;
00241                         }
00242                         else if (ent->activator)
00243                         {
00244                                 g_entities[ent->activator->s.number].client->accuracy_hits++;
00245                         }
00246                 }
00247         }
00248 
00249         trap_LinkEntity( ent );
00250 }

int G_GetHitLocation gentity_t target,
vec3_t  ppoint
 

Definition at line 45 of file g_combat.c.

References entityShared_t::absmax, entityShared_t::absmin, AngleVectors(), gentity_s::client, entityShared_t::currentAngles, DotProduct, fabs(), gentity_t, 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, entityShared_t::maxs, entityShared_t::mins, gentity_s::r, vec3_origin, vec3_t, VectorAdd, VectorCopy, VectorNormalize(), VectorScale, VectorSet, VectorSubtract, and YAW.

Referenced by G_CheckForDismemberment(), G_LocationBasedDamageModifier(), G_PickDeathAnim(), and WP_DisruptorAltFire().

00046 {
00047         vec3_t                  point, point_dir;
00048         vec3_t                  forward, right, up;
00049         vec3_t                  tangles, tcenter;
00050         float                   tradius;
00051         float                   udot, fdot, rdot;
00052         int                             Vertical, Forward, Lateral;
00053         int                             HitLoc;
00054 
00055         // Get target forward, right and up.
00056         if(target->client)
00057         {
00058                 // Ignore player's pitch and roll.
00059                 VectorSet(tangles, 0, target->r.currentAngles[YAW], 0);
00060         }
00061 
00062         AngleVectors(tangles, forward, right, up);
00063 
00064         // Get center of target.
00065         VectorAdd(target->r.absmin, target->r.absmax, tcenter);
00066         VectorScale(tcenter, 0.5, tcenter);
00067 
00068         // Get radius width of target.
00069         tradius = (fabs(target->r.maxs[0]) + fabs(target->r.maxs[1]) + fabs(target->r.mins[0]) + fabs(target->r.mins[1]))/4;
00070 
00071         // Get impact point.
00072         if(ppoint && !VectorCompare(ppoint, vec3_origin))
00073         {
00074                 VectorCopy(ppoint, point);
00075         }
00076         else
00077         {
00078                 return HL_NONE;
00079         }
00080 
00081 /*
00082 //get impact dir
00083         if(pdir && !VectorCompare(pdir, vec3_origin))
00084         {
00085                 VectorCopy(pdir, dir);
00086         }
00087         else
00088         {
00089                 return;
00090         }
00091 
00092 //put point at controlled distance from center
00093         VectorSubtract(point, tcenter, tempvec);
00094         tempvec[2] = 0;
00095         hdist = VectorLength(tempvec);
00096 
00097         VectorMA(point, hdist - tradius, dir, point);
00098         //now a point on the surface of a cylinder with a radius of tradius
00099 */      
00100         VectorSubtract(point, tcenter, point_dir);
00101         VectorNormalize(point_dir);
00102 
00103         // Get bottom to top (vertical) position index
00104         udot = DotProduct(up, point_dir);
00105         if(udot>.800)
00106         {
00107                 Vertical = 4;
00108         }
00109         else if(udot>.400)
00110         {
00111                 Vertical = 3;
00112         }
00113         else if(udot>-.333)
00114         {
00115                 Vertical = 2;
00116         }
00117         else if(udot>-.666)
00118         {
00119                 Vertical = 1;
00120         }
00121         else
00122         {
00123                 Vertical = 0;
00124         }
00125 
00126         // Get back to front (forward) position index.
00127         fdot = DotProduct(forward, point_dir);
00128         if(fdot>.666)
00129         {
00130                 Forward = 4;
00131         }
00132         else if(fdot>.333)
00133         {
00134                 Forward = 3;
00135         }
00136         else if(fdot>-.333)
00137         {
00138                 Forward = 2;
00139         }
00140         else if(fdot>-.666)
00141         {
00142                 Forward = 1;
00143         }
00144         else
00145         {
00146                 Forward = 0;
00147         }
00148 
00149         // Get left to right (lateral) position index.
00150         rdot = DotProduct(right, point_dir);
00151         if(rdot>.666)
00152         {
00153                 Lateral = 4;
00154         }
00155         else if(rdot>.333)
00156         {
00157                 Lateral = 3;
00158         }
00159         else if(rdot>-.333)
00160         {
00161                 Lateral = 2;
00162         }
00163         else if(rdot>-.666)
00164         {
00165                 Lateral = 1;
00166         }
00167         else
00168         {
00169                 Lateral = 0;
00170         }
00171 
00172         HitLoc = Vertical * 25 + Forward * 5 + Lateral;
00173 
00174         if(HitLoc <= 10)
00175         {
00176                 // Feet.
00177                 if ( rdot > 0 )
00178                 {
00179                         return HL_FOOT_RT;
00180                 }
00181                 else
00182                 {
00183                         return HL_FOOT_LT;
00184                 }
00185         }
00186         else if(HitLoc <= 50)
00187         {
00188                 // Legs.
00189                 if ( rdot > 0 )
00190                 {
00191                         return HL_LEG_RT;
00192                 }
00193                 else
00194                 {
00195                         return HL_LEG_LT;
00196                 }
00197         }
00198         else if(HitLoc == 56||HitLoc == 60||HitLoc == 61||HitLoc == 65||HitLoc == 66||HitLoc == 70)
00199         {
00200                 // Hands.
00201                 if ( rdot > 0 )
00202                 {
00203                         return HL_HAND_RT;
00204                 }
00205                 else
00206                 {
00207                         return HL_HAND_LT;
00208                 }
00209         }
00210         else if(HitLoc == 83||HitLoc == 87||HitLoc == 88||HitLoc == 92||HitLoc == 93||HitLoc == 97)
00211         {
00212                 // Arms.
00213                 if ( rdot > 0 )
00214                 {
00215                         return HL_ARM_RT;
00216                 }
00217                 else
00218                 {
00219                         return HL_ARM_LT;
00220                 }
00221         }
00222         else if((HitLoc >= 107 && HitLoc <= 109)||(HitLoc >= 112 && HitLoc <= 114)||(HitLoc >= 117 && HitLoc <= 119))
00223         {
00224                 // Head.
00225                 return HL_HEAD;
00226         }
00227         else
00228         {
00229                 if(udot < 0.3)
00230                 {
00231                         return HL_WAIST;
00232                 }
00233                 else if(fdot < 0)
00234                 {
00235                         if(rdot > 0.4)
00236                         {
00237                                 return HL_BACK_RT;
00238                         }
00239                         else if(rdot < -0.4)
00240                         {
00241                                 return HL_BACK_LT;
00242                         }
00243                         else if(fdot < 0)
00244                         {
00245                                 return HL_BACK;
00246                         }
00247                 }
00248                 else
00249                 {
00250                         if(rdot > 0.3)
00251                         {
00252                                 return HL_CHEST_RT;
00253                         }
00254                         else if(rdot < -0.3)
00255                         {
00256                                 return HL_CHEST_LT;
00257                         }
00258                         else if(fdot < 0)
00259                         {
00260                                 return HL_CHEST;
00261                         }
00262                 }
00263         }
00264         return HL_NONE;
00265 }

qboolean G_HeavyMelee gentity_t attacker  ) 
 

Definition at line 32 of file g_combat.c.

References bgSiegeClasses, CFL_HEAVYMELEE, gentity_s::client, g_gametype, gentity_t, GT_SIEGE, vmCvar_t::integer, qboolean, qfalse, qtrue, and gclient_s::siegeClass.

Referenced by G_Damage(), player_die(), and WP_FireMelee().

00033 {
00034         if (g_gametype.integer == GT_SIEGE 
00035                 && attacker 
00036                 && attacker->client
00037                 && attacker->client->siegeClass != -1 
00038                 && (bgSiegeClasses[attacker->client->siegeClass].classflags & (1<<CFL_HEAVYMELEE)) )
00039         {
00040                 return qtrue;
00041         }
00042         return qfalse;
00043 }

void G_MissileImpact gentity_t ent,
trace_t trace
 

Definition at line 355 of file g_missile.c.

References entityState_s::angles, AngleVectors(), BG_EvaluateTrajectoryDelta(), gentity_s::bounceCount, CLASS_ATST, CLASS_GONK, CLASS_INTERROGATOR, CLASS_MARK1, CLASS_MARK2, CLASS_MOUSE, CLASS_PROBE, CLASS_R2D2, CLASS_R5D2, CLASS_REMOTE, CLASS_SEEKER, CLASS_SENTRY, class_t, CLASS_VEHICLE, gentity_s::classname, gentity_s::client, gclient_s::cloakToggleTime, clientPersistant_t::cmd, entityShared_t::contents, CONTENTS_LIGHTSABER, entityShared_t::currentAngles, entityShared_t::currentOrigin, gentity_s::damage, DAMAGE_HALF_ABSORB, DAMAGE_HEAVY_WEAP_CLASS, gentity_s::dflags, DirToByte(), playerState_s::duelIndex, playerState_s::duelInProgress, EF_ALT_FIRING, EF_MISSILE_STICK, entityState_s::eFlags, playerState_s::electrifyTime, trace_t::endpos, trace_t::entityNum, ET_GENERAL, entityState_s::eType, EV_GRENADE_BOUNCE, EV_MISSILE_HIT, EV_MISSILE_MISS, EV_MISSILE_MISS_METAL, EV_MISSILE_STICK, EV_SABER_BLOCK, entityState_s::eventParm, playerState_s::fd, FighterIsLanded(), FL_BOUNCE, FL_BOUNCE_HALF, FL_BOUNCE_SHRAPNEL, FL_DMG_BY_HEAVY_WEAP_ONLY, FL_SHIELDED, gentity_s::flags, FORCE_LEVEL_1, FORCE_LEVEL_2, FORCE_LEVEL_3, forcedata_s::forcePowerLevel, usercmd_s::forwardmove, FP_SABER_DEFENSE, gentity_s::freeAfterEvent, G2_MODEL_PART, G_AddEvent(), G_BounceMissile(), G_Damage(), G_DeflectMissile(), g_entities, G_MissileBounceEffect(), G_RadiusDamage(), G_ReflectMissile(), G_SetOrigin(), G_TempEntity(), gentity_t, Jedi_Decloak(), laserTrapStick(), entityState_s::legsAnim, level, LogAccuracyHit(), gentity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, gentity_s::methodOfDeath, MOD_CONC, MOD_CONC_ALT, MOD_DEMP2_ALT, MOD_DET_PACK_SPLASH, MOD_FLECHETTE_ALT_SPLASH, MOD_REPEATER_ALT, MOD_ROCKET, MOD_ROCKET_HOMING, MOD_SABER, MOD_THERMAL, MOD_THERMAL_SPLASH, MOD_TIMED_MINE_SPLASH, MOD_TRIP_MINE_SPLASH, MOD_TURBLAST, MOD_VEHICLE, gentity_s::neverFree, cplane_s::normal, gclient_s::NPC_class, NULL, entityState_s::number, entityState_s::origin, entityState_s::otherEntityNum, entityShared_t::ownerNum, gentity_s::parent, gclient_s::pers, trace_t::plane, entityState_s::pos, playerState_s::powerups, gclient_s::ps, PW_CLOAKED, Q3_INFINITE, Q_irand(), Q_stricmp(), qboolean, qfalse, qtrue, gentity_s::r, gentity_s::s, playerState_s::saberBlockTime, playerState_s::saberEventFlags, SEF_DEFLECTED, SnapVectorTowards(), gentity_s::spawnflags, gentity_s::splashDamage, gentity_s::splashMethodOfDeath, gentity_s::splashRadius, SURF_FORCEFIELD, SURF_METALSTEPS, trace_t::surfaceFlags, gentity_s::takedamage, gentity_s::think, level_locals_t::time, trap_LinkEntity(), trajectory_t::trBase, vehicleInfo_t::type, vec3_t, VectorCopy, playerState_s::velocity, VH_FIGHTER, VH_SPEEDER, playerState_s::viewangles, entityState_s::weapon, playerState_s::weaponTime, WP_BOWCASTER, WP_DEMP2, WP_DET_PACK, WP_EMPLACED_GUN, WP_FLECHETTE, WP_ROCKET_LAUNCHER, WP_SABER, WP_SaberBlockNonRandom(), WP_SaberCanBlock(), WP_THERMAL, and WP_TRIP_MINE.

Referenced by G_RunMissile(), and WP_TouchVehMissile().

00355                                                        {
00356         gentity_t               *other;
00357         qboolean                hitClient = qfalse;
00358         qboolean                isKnockedSaber = qfalse;
00359 
00360         other = &g_entities[trace->entityNum];
00361 
00362         // check for bounce
00363         if ( !other->takedamage &&
00364                 (ent->bounceCount > 0 || ent->bounceCount == -5) &&
00365                 ( ent->flags & ( FL_BOUNCE | FL_BOUNCE_HALF ) ) ) {
00366                 G_BounceMissile( ent, trace );
00367                 G_AddEvent( ent, EV_GRENADE_BOUNCE, 0 );
00368                 return;
00369         }
00370         else if (ent->neverFree && ent->s.weapon == WP_SABER && (ent->flags & FL_BOUNCE_HALF))
00371         { //this is a knocked-away saber
00372                 if (ent->bounceCount > 0 || ent->bounceCount == -5)
00373                 {
00374                         G_BounceMissile( ent, trace );
00375                         G_AddEvent( ent, EV_GRENADE_BOUNCE, 0 );
00376                         return;
00377                 }
00378 
00379                 isKnockedSaber = qtrue;
00380         }
00381         
00382         // I would glom onto the FL_BOUNCE code section above, but don't feel like risking breaking something else
00383         if ( (!other->takedamage && (ent->bounceCount > 0 || ent->bounceCount == -5) && ( ent->flags&(FL_BOUNCE_SHRAPNEL) ) ) || ((trace->surfaceFlags&SURF_FORCEFIELD)&&!ent->splashDamage&&!ent->splashRadius&&(ent->bounceCount > 0 || ent->bounceCount == -5)) ) 
00384         {
00385                 G_BounceMissile( ent, trace );
00386 
00387                 if ( ent->bounceCount < 1 )
00388                 {
00389                         ent->flags &= ~FL_BOUNCE_SHRAPNEL;
00390                 }
00391                 return;
00392         }
00393 
00394         /*
00395         if ( !other->takedamage && ent->s.weapon == WP_THERMAL && !ent->alt_fire )
00396         {//rolling thermal det - FIXME: make this an eFlag like bounce & stick!!!
00397                 //G_BounceRollMissile( ent, trace );
00398                 if ( ent->owner && ent->owner->s.number == 0 ) 
00399                 {
00400                         G_MissileAddAlerts( ent );
00401                 }
00402                 //gi.linkentity( ent );
00403                 return;
00404         }
00405         */
00406 
00407         if ((other->r.contents & CONTENTS_LIGHTSABER) && !isKnockedSaber)
00408         { //hit this person's saber, so..
00409                 gentity_t *otherOwner = &g_entities[other->r.ownerNum];
00410 
00411                 if (otherOwner->takedamage && otherOwner->client && otherOwner->client->ps.duelInProgress &&
00412                         otherOwner->client->ps.duelIndex != ent->r.ownerNum)
00413                 {
00414                         goto killProj;
00415                 }
00416         }
00417         else if (!isKnockedSaber)
00418         {
00419                 if (other->takedamage && other->client && other->client->ps.duelInProgress &&
00420                         other->client->ps.duelIndex != ent->r.ownerNum)
00421                 {
00422                         goto killProj;
00423                 }
00424         }
00425 
00426         if (other->flags & FL_DMG_BY_HEAVY_WEAP_ONLY)
00427         {
00428                 if (ent->methodOfDeath != MOD_REPEATER_ALT &&
00429                         ent->methodOfDeath != MOD_ROCKET &&
00430                         ent->methodOfDeath != MOD_FLECHETTE_ALT_SPLASH &&
00431                         ent->methodOfDeath != MOD_ROCKET_HOMING &&
00432                         ent->methodOfDeath != MOD_THERMAL &&
00433                         ent->methodOfDeath != MOD_THERMAL_SPLASH &&
00434                         ent->methodOfDeath != MOD_TRIP_MINE_SPLASH &&
00435                         ent->methodOfDeath != MOD_TIMED_MINE_SPLASH &&
00436                         ent->methodOfDeath != MOD_DET_PACK_SPLASH &&
00437                         ent->methodOfDeath != MOD_VEHICLE &&
00438                         ent->methodOfDeath != MOD_CONC &&
00439                         ent->methodOfDeath != MOD_CONC_ALT &&
00440                         ent->methodOfDeath != MOD_SABER &&
00441                         ent->methodOfDeath != MOD_TURBLAST)
00442                 {
00443                         vec3_t fwd;
00444 
00445                         if (trace)
00446                         {
00447                                 VectorCopy(trace->plane.normal, fwd);
00448                         }
00449                         else
00450                         { //oh well
00451                                 AngleVectors(other->r.currentAngles, fwd, NULL, NULL);
00452                         }
00453 
00454                         G_DeflectMissile(other, ent, fwd);
00455                         G_MissileBounceEffect(ent, ent->r.currentOrigin, fwd);
00456                         return;
00457                 }
00458         }
00459 
00460         if ((other->flags & FL_SHIELDED) &&
00461                 ent->s.weapon != WP_ROCKET_LAUNCHER &&
00462                 ent->s.weapon != WP_THERMAL &&
00463                 ent->s.weapon != WP_TRIP_MINE &&
00464                 ent->s.weapon != WP_DET_PACK &&
00465                 ent->s.weapon != WP_DEMP2 &&
00466                 ent->s.weapon != WP_EMPLACED_GUN &&
00467                 ent->methodOfDeath != MOD_REPEATER_ALT &&
00468                 ent->methodOfDeath != MOD_FLECHETTE_ALT_SPLASH && 
00469                 ent->methodOfDeath != MOD_TURBLAST &&
00470                 ent->methodOfDeath != MOD_VEHICLE &&
00471                 ent->methodOfDeath != MOD_CONC &&
00472                 ent->methodOfDeath != MOD_CONC_ALT &&
00473                 !(ent->dflags&DAMAGE_HEAVY_WEAP_CLASS) )
00474         {
00475                 vec3_t fwd;
00476 
00477                 if (other->client)
00478                 {
00479                         AngleVectors(other->client->ps.viewangles, fwd, NULL, NULL);
00480                 }
00481                 else
00482                 {
00483                         AngleVectors(other->r.currentAngles, fwd, NULL, NULL);
00484                 }
00485 
00486                 G_DeflectMissile(other, ent, fwd);
00487                 G_MissileBounceEffect(ent, ent->r.currentOrigin, fwd);
00488                 return;
00489         }
00490                 
00491         if (other->takedamage && other->client &&
00492                 ent->s.weapon != WP_ROCKET_LAUNCHER &&
00493                 ent->s.weapon != WP_THERMAL &&
00494                 ent->s.weapon != WP_TRIP_MINE &&
00495                 ent->s.weapon != WP_DET_PACK &&
00496                 ent->s.weapon != WP_DEMP2 &&
00497                 ent->methodOfDeath != MOD_REPEATER_ALT &&
00498                 ent->methodOfDeath != MOD_FLECHETTE_ALT_SPLASH &&
00499                 ent->methodOfDeath != MOD_CONC &&
00500                 ent->methodOfDeath != MOD_CONC_ALT &&
00501                 other->client->ps.saberBlockTime < level.time &&
00502                 !isKnockedSaber &&
00503                 WP_SaberCanBlock(other, ent->r.currentOrigin, 0, 0, qtrue, 0))
00504         { //only block one projectile per 200ms (to prevent giant swarms of projectiles being blocked)
00505                 vec3_t fwd;
00506                 gentity_t *te;
00507                 int otherDefLevel = other->client->ps.fd.forcePowerLevel[FP_SABER_DEFENSE];
00508 
00509                 te = G_TempEntity( ent->r.currentOrigin, EV_SABER_BLOCK );
00510                 VectorCopy(ent->r.currentOrigin, te->s.origin);
00511                 VectorCopy(trace->plane.normal, te->s.angles);
00512                 te->s.eventParm = 0;
00513                 te->s.weapon = 0;//saberNum
00514                 te->s.legsAnim = 0;//bladeNum
00515 
00516                 /*if (other->client->ps.velocity[2] > 0 ||
00517                         other->client->pers.cmd.forwardmove ||
00518                         other->client->pers.cmd.rightmove)
00519                         */
00520                 if (other->client->ps.velocity[2] > 0 ||
00521                         other->client->pers.cmd.forwardmove < 0) //now we only do it if jumping or running backward. Should be able to full-on charge.
00522                 {
00523                         otherDefLevel -= 1;
00524                         if (otherDefLevel < 0)
00525                         {
00526                                 otherDefLevel = 0;
00527                         }
00528                 }
00529 
00530                 AngleVectors(other->client->ps.viewangles, fwd, NULL, NULL);
00531                 if (otherDefLevel == FORCE_LEVEL_1)
00532                 {
00533                         //if def is only level 1, instead of deflecting the shot it should just die here
00534                 }
00535                 else if (otherDefLevel == FORCE_LEVEL_2)
00536                 {
00537                         G_DeflectMissile(other, ent, fwd);
00538                 }
00539                 else
00540                 {
00541                         G_ReflectMissile(other, ent, fwd);
00542                 }
00543                 other->client->ps.saberBlockTime = level.time + (350 - (otherDefLevel*100)); //200;
00544 
00545                 //For jedi AI
00546                 other->client->ps.saberEventFlags |= SEF_DEFLECTED;
00547 
00548                 if (otherDefLevel == FORCE_LEVEL_3)
00549                 {
00550                         other->client->ps.saberBlockTime = 0; //^_^
00551                 }
00552 
00553                 if (otherDefLevel == FORCE_LEVEL_1)
00554                 {
00555                         goto killProj;
00556                 }
00557                 return;
00558         }
00559         else if ((other->r.contents & CONTENTS_LIGHTSABER) && !isKnockedSaber)
00560         { //hit this person's saber, so..
00561                 gentity_t *otherOwner = &g_entities[other->r.ownerNum];
00562 
00563                 if (otherOwner->takedamage && otherOwner->client &&
00564                         ent->s.weapon != WP_ROCKET_LAUNCHER &&
00565                         ent->s.weapon != WP_THERMAL &&
00566                         ent->s.weapon != WP_TRIP_MINE &&
00567                         ent->s.weapon != WP_DET_PACK &&
00568                         ent->s.weapon != WP_DEMP2 &&
00569                         ent->methodOfDeath != MOD_REPEATER_ALT &&
00570                         ent->methodOfDeath != MOD_FLECHETTE_ALT_SPLASH &&
00571                         ent->methodOfDeath != MOD_CONC &&
00572                         ent->methodOfDeath != MOD_CONC_ALT /*&&
00573                         otherOwner->client->ps.saberBlockTime < level.time*/)
00574                 { //for now still deflect even if saberBlockTime >= level.time because it hit the actual saber
00575                         vec3_t fwd;
00576                         gentity_t *te;
00577                         int otherDefLevel = otherOwner->client->ps.fd.forcePowerLevel[FP_SABER_DEFENSE];
00578 
00579                         //in this case, deflect it even if we can't actually block it because it hit our saber
00580                         //WP_SaberCanBlock(otherOwner, ent->r.currentOrigin, 0, 0, qtrue, 0);
00581                         if (otherOwner->client && otherOwner->client->ps.weaponTime <= 0)
00582                         {
00583                                 WP_SaberBlockNonRandom(otherOwner, ent->r.currentOrigin, qtrue);
00584                         }
00585 
00586                         te = G_TempEntity( ent->r.currentOrigin, EV_SABER_BLOCK );
00587                         VectorCopy(ent->r.currentOrigin, te->s.origin);
00588                         VectorCopy(trace->plane.normal, te->s.angles);
00589                         te->s.eventParm = 0;
00590                         te->s.weapon = 0;//saberNum
00591                         te->s.legsAnim = 0;//bladeNum
00592 
00593                         /*if (otherOwner->client->ps.velocity[2] > 0 ||
00594                                 otherOwner->client->pers.cmd.forwardmove ||
00595                                 otherOwner->client->pers.cmd.rightmove)*/
00596                         if (otherOwner->client->ps.velocity[2] > 0 ||
00597                                 otherOwner->client->pers.cmd.forwardmove < 0) //now we only do it if jumping or running backward. Should be able to full-on charge.
00598                         {
00599                                 otherDefLevel -= 1;
00600                                 if (otherDefLevel < 0)
00601                                 {
00602                                         otherDefLevel = 0;
00603                                 }
00604                         }
00605 
00606                         AngleVectors(otherOwner->client->ps.viewangles, fwd, NULL, NULL);
00607 
00608                         if (otherDefLevel == FORCE_LEVEL_1)
00609                         {
00610                                 //if def is only level 1, instead of deflecting the shot it should just die here
00611                         }
00612                         else if (otherDefLevel == FORCE_LEVEL_2)
00613                         {
00614                                 G_DeflectMissile(otherOwner, ent, fwd);
00615                         }
00616                         else
00617                         {
00618                                 G_ReflectMissile(otherOwner, ent, fwd);
00619                         }
00620                         otherOwner->client->ps.saberBlockTime = level.time + (350 - (otherDefLevel*100));//200;
00621 
00622                         //For jedi AI
00623                         otherOwner->client->ps.saberEventFlags |= SEF_DEFLECTED;
00624 
00625                         if (otherDefLevel == FORCE_LEVEL_3)
00626                         {
00627                                 otherOwner->client->ps.saberBlockTime = 0; //^_^
00628                         }
00629 
00630                         if (otherDefLevel == FORCE_LEVEL_1)
00631                         {
00632                                 goto killProj;
00633                         }
00634                         return;
00635                 }
00636         }
00637 
00638         // check for sticking
00639         if ( !other->takedamage && ( ent->s.eFlags & EF_MISSILE_STICK ) ) 
00640         {
00641                 laserTrapStick( ent, trace->endpos, trace->plane.normal );
00642                 G_AddEvent( ent, EV_MISSILE_STICK, 0 );
00643                 return;
00644         }
00645 
00646         // impact damage
00647         if (other->takedamage && !isKnockedSaber) {
00648                 // FIXME: wrong damage direction?
00649                 if ( ent->damage ) {
00650                         vec3_t  velocity;
00651                         qboolean didDmg = qfalse;
00652 
00653                         if( LogAccuracyHit( other, &g_entities[ent->r.ownerNum] ) ) {
00654                                 g_entities[ent->r.ownerNum].client->accuracy_hits++;
00655                                 hitClient = qtrue;
00656                         }
00657                         BG_EvaluateTrajectoryDelta( &ent->s.pos, level.time, velocity );
00658                         if ( VectorLength( velocity ) == 0 ) {
00659                                 velocity[2] = 1;        // stepped on a grenade
00660                         }
00661 
00662                         if (ent->s.weapon == WP_BOWCASTER || ent->s.weapon == WP_FLECHETTE ||
00663                                 ent->s.weapon == WP_ROCKET_LAUNCHER)
00664                         {
00665                                 if (ent->s.weapon == WP_FLECHETTE && (ent->s.eFlags & EF_ALT_FIRING))
00666                                 {
00667                                         ent->think(ent);
00668                                 }
00669                                 else
00670                                 {
00671                                         G_Damage (other, ent, &g_entities[ent->r.ownerNum], velocity,
00672                                                 /*ent->s.origin*/ent->r.currentOrigin, ent->damage, 
00673                                                 DAMAGE_HALF_ABSORB, ent->methodOfDeath);
00674                                         didDmg = qtrue;
00675                                 }
00676                         }
00677                         else
00678                         {
00679                                 G_Damage (other, ent, &g_entities[ent->r.ownerNum], velocity,
00680                                         /*ent->s.origin*/ent->r.currentOrigin, ent->damage, 
00681                                         0, ent->methodOfDeath);
00682                                 didDmg = qtrue;
00683                         }
00684 
00685                         if (didDmg && other && other->client)
00686                         { //What I'm wondering is why this isn't in the NPC pain funcs. But this is what SP does, so whatever.
00687                                 class_t npc_class = other->client->NPC_class;
00688 
00689                                 // If we are a robot and we aren't currently doing the full body electricity...
00690                                 if ( npc_class == CLASS_SEEKER || npc_class == CLASS_PROBE || npc_class == CLASS_MOUSE ||
00691                                            npc_class == CLASS_GONK || npc_class == CLASS_R2D2 || npc_class == CLASS_R5D2 || npc_class == CLASS_REMOTE ||
00692                                            npc_class == CLASS_MARK1 || npc_class == CLASS_MARK2 || //npc_class == CLASS_PROTOCOL ||//no protocol, looks odd
00693                                            npc_class == CLASS_INTERROGATOR || npc_class == CLASS_ATST || npc_class == CLASS_SENTRY )
00694                                 {
00695                                         // special droid only behaviors
00696                                         if ( other->client->ps.electrifyTime < level.time + 100 )
00697                                         {
00698                                                 // ... do the effect for a split second for some more feedback
00699                                                 other->client->ps.electrifyTime = level.time + 450;
00700                                         }
00701                                         //FIXME: throw some sparks off droids,too
00702                                 }
00703                         }
00704                 }
00705 
00706                 if ( ent->s.weapon == WP_DEMP2 )
00707                 {//a hit with demp2 decloaks people, disables ships
00708                         if ( other && other->client && other->client->NPC_class == CLASS_VEHICLE )
00709                         {//hit a vehicle
00710                                 if ( other->m_pVehicle //valid vehicle ent
00711                                         && other->m_pVehicle->m_pVehicleInfo//valid stats
00712                                         && (other->m_pVehicle->m_pVehicleInfo->type == VH_SPEEDER//always affect speeders
00713                                                 ||(other->m_pVehicle->m_pVehicleInfo->type == VH_FIGHTER && ent->classname && Q_stricmp("vehicle_proj", ent->classname ) == 0) )//only vehicle ion weapons affect a fighter in this manner
00714                                         && !FighterIsLanded( other->m_pVehicle , &other->client->ps )//not landed
00715                                         && !(other->spawnflags&2) )//and not suspended
00716                                 {//vehicles hit by "ion cannons" lose control
00717                                         if ( other->client->ps.electrifyTime > level.time )
00718                                         {//add onto it
00719                                                 //FIXME: extern the length of the "out of control" time?
00720                                                 other->client->ps.electrifyTime += Q_irand(200,500);
00721                                                 if ( other->client->ps.electrifyTime > level.time + 4000 )
00722                                                 {//cap it
00723                                                         other->client->ps.electrifyTime = level.time + 4000;
00724                                                 }
00725                                         }
00726                                         else
00727                                         {//start it
00728                                                 //FIXME: extern the length of the "out of control" time?
00729                                                 other->client->ps.electrifyTime = level.time + Q_irand(200,500);
00730                                         }
00731                                 }
00732                         }
00733                         else if ( other && other->client && other->client->ps.powerups[PW_CLOAKED] )
00734                         {
00735                                 Jedi_Decloak( other );
00736                                 if ( ent->methodOfDeath == MOD_DEMP2_ALT )
00737                                 {//direct hit with alt disables cloak forever
00738                                         //permanently disable the saboteur's cloak
00739                                         other->client->cloakToggleTime = Q3_INFINITE;
00740                                 }
00741                                 else
00742                                 {//temp disable
00743                                         other->client->cloakToggleTime = level.time + Q_irand( 3000, 10000 );
00744                                 }
00745                         }
00746                 }
00747         }
00748 killProj:
00749         // is it cheaper in bandwidth to just remove this ent and create a new
00750         // one, rather than changing the missile into the explosion?
00751 
00752         if ( other->takedamage && other->client && !isKnockedSaber ) {
00753                 G_AddEvent( ent, EV_MISSILE_HIT, DirToByte( trace->plane.normal ) );
00754                 ent->s.otherEntityNum = other->s.number;
00755         } else if( trace->surfaceFlags & SURF_METALSTEPS ) {
00756                 G_AddEvent( ent, EV_MISSILE_MISS_METAL, DirToByte( trace->plane.normal ) );
00757         } else if (ent->s.weapon != G2_MODEL_PART && !isKnockedSaber) {
00758                 G_AddEvent( ent, EV_MISSILE_MISS, DirToByte( trace->plane.normal ) );
00759         }
00760 
00761         if (!isKnockedSaber)
00762         {
00763                 ent->freeAfterEvent = qtrue;
00764 
00765                 // change over to a normal entity right at the point of impact
00766                 ent->s.eType = ET_GENERAL;
00767         }
00768 
00769         SnapVectorTowards( trace->endpos, ent->s.pos.trBase );  // save net bandwidth
00770 
00771         G_SetOrigin( ent, trace->endpos );
00772 
00773         ent->takedamage = qfalse;
00774         // splash damage (doesn't apply to person directly hit)
00775         if ( ent->splashDamage ) {
00776                 if( G_RadiusDamage( trace->endpos, ent->parent, ent->splashDamage, ent->splashRadius, 
00777                         other, ent, ent->splashMethodOfDeath ) ) {
00778                         if( !hitClient 
00779                                 && g_entities[ent->r.ownerNum].client ) {
00780                                 g_entities[ent->r.ownerNum].client->accuracy_hits++;
00781                         }
00782                 }
00783         }
00784 
00785         if (ent->s.weapon == G2_MODEL_PART)
00786         {
00787                 ent->freeAfterEvent = qfalse; //it will free itself
00788         }
00789 
00790         trap_LinkEntity( ent );
00791 }

void G_VehMuzzleFireFX gentity_t ent,
gentity_t broadcaster,
int  muzzlesFired
 

Definition at line 3836 of file g_weapon.c.

References gentity_s::client, EV_VEH_FIRE, G_AddEvent(), G_TempEntity(), gentity_t, gentity_s::m_pVehicle, entityState_s::number, playerState_s::origin, entityState_s::owner, gclient_s::ps, gentity_s::s, entityState_s::trickedentindex, and Vehicle_t.

Referenced by FireVehicleWeapon(), and VEH_TurretCheckFire().

03837 {
03838         Vehicle_t *pVeh = ent->m_pVehicle;
03839         gentity_t *b;
03840 
03841         if (!pVeh)
03842         {
03843                 return;
03844         }
03845 
03846         if (!broadcaster)
03847         { //oh well. We will WASTE A TEMPENT.
03848                 b = G_TempEntity( ent->client->ps.origin, EV_VEH_FIRE );
03849         }
03850         else
03851         { //joy
03852                 b = broadcaster;
03853         }
03854 
03855         //this guy owns it
03856         b->s.owner = ent->s.number;
03857 
03858         //this is the bitfield of all muzzles fired this time
03859         //NOTE: just need MAX_VEHICLE_MUZZLES bits for this... should be cool since it's currently 12 and we're sending it in 16 bits
03860         b->s.trickedentindex = muzzlesFired;
03861 
03862         if ( broadcaster )
03863         { //add the event
03864                 G_AddEvent( b, EV_VEH_FIRE, 0 );
03865         }
03866 }

void Jedi_Decloak gentity_t self  ) 
 

Definition at line 818 of file NPC_AI_Jedi.c.

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 }

void laserTrapDelayedExplode gentity_t self,
gentity_t inflictor,
gentity_t attacker,
int  damage,
int  meansOfDeath
 

Definition at line 2280 of file g_weapon.c.

References gentity_s::enemy, FRAMETIME, gentity_t, laserTrapExplode(), level, gentity_s::nextthink, entityState_s::number, qfalse, gentity_s::s, gentity_s::splashDamage, gentity_s::splashRadius, gentity_s::takedamage, gentity_s::think, and level_locals_t::time.

Referenced by laserTrapStick().

02281 {
02282         self->enemy = attacker;
02283         self->think = laserTrapExplode;
02284         self->nextthink = level.time + FRAMETIME;
02285         self->takedamage = qfalse;
02286         if ( attacker && !attacker->s.number )
02287         {
02288                 //less damage when shot by player
02289                 self->splashDamage /= 3;
02290                 self->splashRadius /= 3;
02291         }
02292 }

void laserTrapExplode gentity_t self  ) 
 

Definition at line 2242 of file g_weapon.c.

References gentity_s::activator, entityShared_t::currentOrigin, EFFECT_EXPLOSION_FLECHETTE, EFFECT_EXPLOSION_TRIPMINE, EV_MISSILE_MISS, G_AddEvent(), G_FreeEntity(), G_PlayEffect(), G_RadiusDamage(), gentity_t, level, MOD_TRIP_MINE_SPLASH, gentity_s::nextthink, entityState_s::pos, qfalse, gentity_s::r, gentity_s::s, gentity_s::splashDamage, gentity_s::splashRadius, gentity_s::takedamage, gentity_s::think, level_locals_t::time, entityState_s::time, trajectory_t::trDelta, vec3_t, VectorCopy, entityState_s::weapon, and WP_FLECHETTE.

Referenced by laserTrapDelayedExplode(), laserTrapThink(), prox_mine_think(), proxMineThink(), touchLaserTrap(), WP_ExplosiveDie(), and WP_flechette_alt_blow().

02243 {
02244         vec3_t v;
02245         self->takedamage = qfalse;
02246 
02247         if (self->activator)
02248         {
02249                 G_RadiusDamage( self->r.currentOrigin, self->activator, self->splashDamage, self->splashRadius, self, self, MOD_TRIP_MINE_SPLASH/*MOD_LT_SPLASH*/ );
02250         }
02251 
02252         if (self->s.weapon != WP_FLECHETTE)
02253         {
02254                 G_AddEvent( self, EV_MISSILE_MISS, 0);
02255         }
02256 
02257         VectorCopy(self->s.pos.trDelta, v);
02258         //Explode outward from the surface
02259 
02260         if (self->s.time == -2)
02261         {
02262                 v[0] = 0;
02263                 v[1] = 0;
02264                 v[2] = 0;
02265         }
02266 
02267         if (self->s.weapon == WP_FLECHETTE)
02268         {
02269                 G_PlayEffect(EFFECT_EXPLOSION_FLECHETTE, self->r.currentOrigin, v);
02270         }
02271         else
02272         {
02273                 G_PlayEffect(EFFECT_EXPLOSION_TRIPMINE, self->r.currentOrigin, v);
02274         }
02275 
02276         self->think = G_FreeEntity;
02277         self->nextthink = level.time;
02278 }

void laserTrapStick gentity_t ent,
vec3_t  endpos,
vec3_t  normal
 

Referenced by G_MissileImpact(), and touchLaserTrap().

void laserTrapThink gentity_t ent  ) 
 

Definition at line 2365 of file g_weapon.c.

References CHAN_WEAPON, gentity_s::client, entityShared_t::currentOrigin, EF_FIRING, entityState_s::eFlags, trace_t::entityNum, FRAMETIME, g_entities, G_Sound(), G_SoundIndex(), gentity_t, laserTrapExplode(), laserTrapThink(), level, LT_DELAY_TIME, MASK_SHOT, gentity_s::movedir, gentity_s::nextthink, NULL, entityState_s::number, entityState_s::pos, gentity_s::r, gentity_s::s, trace_t::startsolid, gentity_s::think, entityState_s::time, level_locals_t::time, gentity_s::touch, trap_LinkEntity(), trap_Trace(), trajectory_t::trBase, vec3_t, and VectorMA.

Referenced by laserTrapStick(), and laserTrapThink().

02366 {
02367         gentity_t       *traceEnt;
02368         vec3_t          end;
02369         trace_t         tr;
02370 
02371         //just relink it every think
02372         trap_LinkEntity(ent);
02373 
02374         //turn on the beam effect
02375         if ( !(ent->s.eFlags&EF_FIRING) )
02376         {//arm me
02377                 G_Sound( ent, CHAN_WEAPON, G_SoundIndex( "sound/weapons/laser_trap/warning.wav" ) );
02378                 ent->s.eFlags |= EF_FIRING;
02379         }
02380         ent->think = laserTrapThink;
02381         ent->nextthink = level.time + FRAMETIME;
02382 
02383         // Find the main impact point
02384         VectorMA ( ent->s.pos.trBase, 1024, ent->movedir, end );
02385         trap_Trace ( &tr, ent->r.currentOrigin, NULL, NULL, end, ent->s.number, MASK_SHOT);
02386         
02387         traceEnt = &g_entities[ tr.entityNum ];
02388 
02389         ent->s.time = -1; //let all clients know to draw a beam from this guy
02390 
02391         if ( traceEnt->client || tr.startsolid )
02392         {
02393                 //go boom
02394                 ent->touch = 0;
02395                 ent->nextthink = level.time + LT_DELAY_TIME;
02396                 ent->think = laserTrapExplode;
02397         }
02398 }

qboolean LogAccuracyHit gentity_t target,
gentity_t attacker
 

Definition at line 3480 of file g_weapon.c.

References gentity_s::client, gentity_t, OnSameTeam(), gclient_s::ps, qboolean, qfalse, qtrue, STAT_HEALTH, playerState_s::stats, and gentity_s::takedamage.

Referenced by G_MissileImpact(), G_RadiusDamage(), and WP_DisruptorAltFire().

03480                                                                   {
03481         if( !target->takedamage ) {
03482                 return qfalse;
03483         }
03484 
03485         if ( target == attacker ) {
03486                 return qfalse;
03487         }
03488 
03489         if( !target->client ) {
03490                 return qfalse;
03491         }
03492 
03493         if (!attacker)
03494         {
03495                 return qfalse;
03496         }
03497 
03498         if( !attacker->client ) {
03499                 return qfalse;
03500         }
03501 
03502         if( target->client->ps.stats[STAT_HEALTH] <= 0 ) {
03503                 return qfalse;
03504         }
03505 
03506         if ( OnSameTeam( target, attacker ) ) {
03507                 return qfalse;
03508         }
03509 
03510         return qtrue;
03511 }

void prox_mine_think gentity_t ent  ) 
 

Definition at line 1468 of file g_weapon.c.

References gentity_s::activator, gentity_s::client, entityShared_t::currentOrigin, gentity_s::delay, FLECHETTE_MINE_RADIUS_CHECK, G_RadiusList(), gentity_t, gentity_s::health, laserTrapExplode(), level, gentity_s::nextthink, entityState_s::number, qboolean, qfalse, qtrue, gentity_s::r, gentity_s::s, gentity_s::think, and level_locals_t::time.

01470 {
01471         int                     count, i;
01472         qboolean        blow = qfalse;
01473 
01474         // if it isn't time to auto-explode, do a small proximity check
01475         if ( ent->delay > level.time )
01476         {
01477                 count = G_RadiusList( ent->r.currentOrigin, FLECHETTE_MINE_RADIUS_CHECK, ent, qtrue, ent_list );
01478 
01479                 for ( i = 0; i < count; i++ )
01480                 {
01481                         if ( ent_list[i]->client && ent_list[i]->health > 0 && ent->activator && ent_list[i]->s.number != ent->activator->s.number )
01482                         {
01483                                 blow = qtrue;
01484                                 break;
01485                         }
01486                 }
01487         }
01488         else
01489         {
01490                 // well, we must die now
01491                 blow = qtrue;
01492         }
01493 
01494         if ( blow )
01495         {
01496                 ent->think = laserTrapExplode;
01497                 ent->nextthink = level.time + 200;
01498         }
01499         else
01500         {
01501                 // we probably don't need to do this thinking logic very often...maybe this is fast enough?
01502                 ent->nextthink = level.time + 500;
01503         }
01504 }

void proxMineThink gentity_t ent  ) 
 

Definition at line 2318 of file g_weapon.c.

References gentity_s::client, CON_CONNECTED, clientPersistant_t::connected, entityShared_t::currentOrigin, ENTITYNUM_WORLD, g_entities, g_friendlyFire, gentity_s::genericValue15, gentity_t, gentity_s::health, vmCvar_t::integer, gentity_s::inuse, laserTrapExplode(), level, MAX_CLIENTS, gentity_s::nextthink, NULL, OnSameTeam(), playerState_s::origin, entityShared_t::ownerNum, gclient_s::pers, gclient_s::ps, gentity_s::r, gclient_s::sess, clientSession_t::sessionTeam, gentity_s::splashRadius, TEAM_SPECTATOR, gclient_s::tempSpectate, gentity_s::think, level_locals_t::time, vec3_t, and VectorSubtract.

Referenced by laserTrapStick().

02319 {
02320         int i = 0;
02321         gentity_t *cl;
02322         gentity_t *owner = NULL;
02323 
02324         if (ent->r.ownerNum < ENTITYNUM_WORLD)
02325         {
02326                 owner = &g_entities[ent->r.ownerNum];
02327         }
02328 
02329         ent->nextthink = level.time;
02330 
02331         if (ent->genericValue15 < level.time ||
02332                 !owner ||
02333                 !owner->inuse ||
02334                 !owner->client ||
02335                 owner->client->pers.connected != CON_CONNECTED)
02336         { //time to die!
02337                 ent->think = laserTrapExplode;
02338                 return;
02339         }
02340 
02341         while (i < MAX_CLIENTS)
02342         { //eh, just check for clients, don't care about anyone else...
02343                 cl = &g_entities[i];
02344 
02345                 if (cl->inuse && cl->client && cl->client->pers.connected == CON_CONNECTED &&
02346                         owner != cl && cl->client->sess.sessionTeam != TEAM_SPECTATOR &&
02347                         cl->client->tempSpectate < level.time && cl->health > 0)
02348                 {
02349                         if (!OnSameTeam(owner, cl) || g_friendlyFire.integer)
02350                         { //not on the same team, or friendly fire is enabled
02351                                 vec3_t v;
02352 
02353                                 VectorSubtract(ent->r.currentOrigin, cl->client->ps.origin, v);
02354                                 if (VectorLength(v) < (ent->splashRadius/2.0f))
02355                                 {
02356                                         ent->think = laserTrapExplode;
02357                                         return;
02358                                 }
02359                         }
02360                 }
02361                 i++;
02362         }
02363 }

void RocketDie gentity_t self,
gentity_t inflictor,
gentity_t attacker,
int  damage,
int  mod
 

Definition at line 1812 of file g_weapon.c.

References entityShared_t::contents, gentity_s::die, G_ExplodeMissile(), G_FreeEntity(), gentity_t, level, gentity_s::nextthink, gentity_s::r, gentity_s::think, and level_locals_t::time.

Referenced by rocketThink(), and WP_FireVehicleWeapon().

01813 {
01814         self->die = 0;
01815         self->r.contents = 0;
01816 
01817         G_ExplodeMissile( self );
01818 
01819         self->think = G_FreeEntity;
01820         self->nextthink = level.time;
01821 }

void rocketThink gentity_t ent  ) 
 

Definition at line 1649 of file g_weapon.c.

References gentity_s::angle, CLASS_VEHICLE, gentity_s::client, crandom, entityShared_t::currentOrigin, DotProduct, gentity_s::enemy, ENTITYNUM_NONE, g_entities, G_FreeEntity(), gentity_s::genericValue1, gentity_s::genericValue2, gentity_t, playerState_s::groundEntityNum, gentity_s::health, gentity_s::inuse, level, entityShared_t::maxs, entityShared_t::mins, MOD_UNKNOWN, gentity_s::movedir, gentity_s::nextthink, gclient_s::NPC_class, entityShared_t::ownerNum, entityState_s::pos, playerState_s::powerups, gclient_s::ps, PW_CLOAKED, gentity_s::r, gentity_s::radius, gentity_s::random, ROCKET_ALT_THINK_TIME, ROCKET_VELOCITY, RocketDie(), gentity_s::s, gentity_s::spawnflags, playerState_s::speed, gentity_s::speed, gentity_s::think, level_locals_t::time, trajectory_t::trBase, trajectory_t::trDelta, trajectory_t::trTime, vec3_t, VectorCopy, VectorMA, VectorNormalize(), VectorScale, and VectorSubtract.

Referenced by WP_FireVehicleWeapon().

01651 {
01652         vec3_t newdir, targetdir, 
01653                         up={0,0,1}, right; 
01654         vec3_t  org;
01655         float dot, dot2, dis;
01656         int i;
01657         float vel = (ent->spawnflags&1)?ent->speed:ROCKET_VELOCITY;
01658 
01659         if ( ent->genericValue1 && ent->genericValue1 < level.time )
01660         {//time's up, we're done, remove us
01661                 if ( ent->genericValue2 )
01662                 {//explode when die
01663                         RocketDie( ent, &g_entities[ent->r.ownerNum], &g_entities[ent->r.ownerNum], 0, MOD_UNKNOWN );
01664                 }
01665                 else
01666                 {//just remove when die
01667                         G_FreeEntity( ent );
01668                 }
01669                 return;
01670         }
01671         if ( !ent->enemy 
01672                 || !ent->enemy->client 
01673                 || ent->enemy->health <= 0 
01674                 || ent->enemy->client->ps.powerups[PW_CLOAKED] )
01675         {//no enemy or enemy not a client or enemy dead or enemy cloaked
01676                 if ( !ent->genericValue1  )
01677                 {//doesn't have its own self-kill time
01678                         ent->nextthink = level.time + 10000;
01679                         ent->think = G_FreeEntity;
01680                 }
01681                 return;
01682         }
01683 
01684         if ( (ent->spawnflags&1) )
01685         {//vehicle rocket
01686                 if ( ent->enemy->client && ent->enemy->client->NPC_class == CLASS_VEHICLE )
01687                 {//tracking another vehicle
01688                         if ( ent->enemy->client->ps.speed+4000 > vel )
01689                         {
01690                                 vel = ent->enemy->client->ps.speed+4000;
01691                         }
01692                 }
01693         }
01694 
01695         if ( ent->enemy && ent->enemy->inuse )
01696         {       
01697                 float newDirMult = ent->angle?ent->angle*2.0f:1.0f;
01698                 float oldDirMult = ent->angle?(1.0f-ent->angle)*2.0f:1.0f;
01699 
01700                 VectorCopy( ent->enemy->r.currentOrigin, org );
01701                 org[2] += (ent->enemy->r.mins[2] + ent->enemy->r.maxs[2]) * 0.5f;
01702 
01703                 VectorSubtract( org, ent->r.currentOrigin, targetdir );
01704                 VectorNormalize( targetdir );
01705 
01706                 // Now the rocket can't do a 180 in space, so we'll limit the turn to about 45 degrees.
01707                 dot = DotProduct( targetdir, ent->movedir );
01708                 if ( (ent->spawnflags&1) )
01709                 {//vehicle rocket
01710                         if ( ent->radius > -1.0f )
01711                         {//can lose the lock if DotProduct drops below this number
01712                                 if ( dot < ent->radius )
01713                                 {//lost the lock!!!
01714                                         //HMM... maybe can re-lock on if they come in front again?
01715                                         /*
01716                                         //OR: should it stop trying to lock altogether?
01717                                         if ( ent->genericValue1 )
01718                                         {//have a timelimit, set next think to that
01719                                                 ent->nextthink = ent->genericValue1;
01720                                                 if ( ent->genericValue2 )
01721                                                 {//explode when die
01722                                                         ent->think = G_ExplodeMissile;
01723                                                 }
01724                                                 else
01725                                                 {
01726                                                         ent->think = G_FreeEntity;
01727                                                 }
01728                                         }
01729                                         else
01730                                         {
01731                                                 ent->think = NULL;
01732                                                 ent->nextthink = -1;
01733                                         }
01734                                         */
01735                                         return;
01736                                 }
01737                         }
01738                 }
01739 
01740 
01741                 // a dot of 1.0 means right-on-target.
01742                 if ( dot < 0.0f )
01743                 {       
01744                         // Go in the direction opposite, start a 180.
01745                         CrossProduct( ent->movedir, up, right );
01746                         dot2 = DotProduct( targetdir, right );
01747 
01748                         if ( dot2 > 0 )
01749                         {       
01750                                 // Turn 45 degrees right.
01751                                 VectorMA( ent->movedir, 0.4f*newDirMult, right, newdir );
01752                         }
01753                         else
01754                         {       
01755                                 // Turn 45 degrees left.
01756                                 VectorMA( ent->movedir, -0.4f*newDirMult, right, newdir );
01757                         }
01758 
01759                         // Yeah we've adjusted horizontally, but let's split the difference vertically, so we kinda try to move towards it.
01760                         newdir[2] = ( (targetdir[2]*newDirMult) + (ent->movedir[2]*oldDirMult) ) * 0.5;
01761 
01762                         // let's also slow down a lot
01763                         vel *= 0.5f;
01764                 }
01765                 else if ( dot < 0.70f )
01766                 {       
01767                         // Still a bit off, so we turn a bit softer
01768                         VectorMA( ent->movedir, 0.5f*newDirMult, targetdir, newdir );
01769                 }
01770                 else
01771                 {       
01772                         // getting close, so turn a bit harder
01773                         VectorMA( ent->movedir, 0.9f*newDirMult, targetdir, newdir );
01774                 }
01775 
01776                 // add crazy drunkenness
01777                 for (i = 0; i < 3; i++ )
01778                 {
01779                         newdir[i] += crandom() * ent->random * 0.25f;
01780                 }
01781 
01782                 // decay the randomness
01783                 ent->random *= 0.9f;
01784 
01785                 if ( ent->enemy->client
01786                         && ent->enemy->client->ps.groundEntityNum != ENTITYNUM_NONE )
01787                 {//tracking a client who's on the ground, aim at the floor...?
01788                         // Try to crash into the ground if we get close enough to do splash damage
01789                         dis = Distance( ent->r.currentOrigin, org );
01790 
01791                         if ( dis < 128 )
01792                         {
01793                                 // the closer we get, the more we push the rocket down, heh heh.
01794                                 newdir[2] -= (1.0f - (dis / 128.0f)) * 0.6f;
01795                         }
01796                 }
01797 
01798                 VectorNormalize( newdir );
01799 
01800                 VectorScale( newdir, vel * 0.5f, ent->s.pos.trDelta );
01801                 VectorCopy( newdir, ent->movedir );
01802                 SnapVector( ent->s.pos.trDelta );                       // save net bandwidth
01803                 VectorCopy( ent->r.currentOrigin, ent->s.pos.trBase );
01804                 ent->s.pos.trTime = level.time;
01805         }
01806 
01807         ent->nextthink = level.time + ROCKET_ALT_THINK_TIME;    // Nothing at all spectacular happened, continue.
01808         return;
01809 }

void SnapVectorTowards vec3_t  v,
vec3_t  to
 

Definition at line 3459 of file g_weapon.c.

References vec3_t.

Referenced by G_MissileImpact().

03459                                               {
03460         int             i;
03461 
03462         for ( i = 0 ; i < 3 ; i++ ) {
03463                 if ( to[i] <= v[i] ) {
03464                         v[i] = (int)v[i];
03465                 } else {
03466                         v[i] = (int)v[i] + 1;
03467                 }
03468         }
03469 }

void SP_emplaced_gun gentity_t ent  ) 
 

Definition at line 4915 of file g_weapon.c.

References trace_t::allsolid, entityState_s::angles, entityState_s::apos, BG_FindItemForWeapon(), entityShared_t::contents, CONTENTS_SOLID, gentity_s::count, entityShared_t::currentAngles, gentity_s::die, EMPLACED_CANRESPAWN, emplaced_gun_die(), EMPLACED_GUN_HEALTH, emplaced_gun_pain(), emplaced_gun_realuse(), emplaced_gun_update(), trace_t::endpos, trace_t::fraction, entityState_s::g2radius, G_ModelIndex(), G_ScaleNetHealth(), G_SetOrigin(), G_SpawnFloat(), G_SpawnInt(), gentity_s::genericValue4, gentity_s::genericValue5, gentity_t, gentity_s::health, level, MASK_SOLID, MAX_CLIENTS, gentity_s::maxHealth, entityShared_t::maxs, entityShared_t::mins, entityState_s::modelGhoul2, entityState_s::modelindex, name, gentity_s::nextthink, entityState_s::number, entityState_s::origin, entityState_s::origin2, entityState_s::owner, gentity_s::pain, entityState_s::pos, gentity_s::pos1, qtrue, gentity_s::r, RegisterItem(), gentity_s::s, entityState_s::shouldtarget, entityState_s::solid, SOLID_BBOX, gentity_s::spawnflags, gentity_s::splashDamage, gentity_s::splashRadius, trace_t::startsolid, SVF_PLAYER_USABLE, entityShared_t::svFlags, gentity_s::takedamage, gentity_s::think, level_locals_t::time, TR_STATIONARY, trap_LinkEntity(), trap_Trace(), trajectory_t::trBase, trajectory_t::trType, gentity_s::use, vec3_t, VectorCopy, VectorSet, entityState_s::weapon, and WP_EMPLACED_GUN.

04916 {
04917         const char *name = "models/map_objects/mp/turret_chair.glm";
04918         vec3_t down;
04919         trace_t tr;
04920 
04921         //make sure our assets are precached
04922         RegisterItem( BG_FindItemForWeapon(WP_EMPLACED_GUN) );
04923 
04924         ent->r.contents = CONTENTS_SOLID;
04925         ent->s.solid = SOLID_BBOX;
04926 
04927         ent->genericValue5 = 0;
04928 
04929         VectorSet( ent->r.mins, -30, -20, 8 );
04930         VectorSet( ent->r.maxs, 30, 20, 60 );
04931 
04932         VectorCopy(ent->s.origin, down);
04933 
04934         down[2] -= 1024;
04935 
04936         trap_Trace(&tr, ent->s.origin, ent->r.mins, ent->r.maxs, down, ent->s.number, MASK_SOLID);
04937 
04938         if (tr.fraction != 1 && !tr.allsolid && !tr.startsolid)
04939         {
04940                 VectorCopy(tr.endpos, ent->s.origin);
04941         }
04942 
04943         ent->spawnflags |= 4; // deadsolid
04944 
04945         ent->health = EMPLACED_GUN_HEALTH;
04946 
04947         if (ent->spawnflags & EMPLACED_CANRESPAWN)
04948         { //make it somewhat easier to kill if it can respawn
04949                 ent->health *= 0.4;
04950         }
04951 
04952         ent->maxHealth = ent->health;
04953         G_ScaleNetHealth(ent);
04954 
04955         ent->genericValue4 = 0;
04956 
04957         ent->takedamage = qtrue;
04958         ent->pain = emplaced_gun_pain;
04959         ent->die = emplaced_gun_die;
04960 
04961         // being caught in this thing when it blows would be really bad.
04962         ent->splashDamage = 80;
04963         ent->splashRadius = 128;
04964 
04965         // amount of ammo that this little poochie has
04966         G_SpawnInt( "count", "600", &ent->count );
04967 
04968         G_SpawnFloat( "constraint", "60", &ent->s.origin2[0] );
04969 
04970         ent->s.modelindex = G_ModelIndex( (char *)name );
04971         ent->s.modelGhoul2 = 1;
04972         ent->s.g2radius = 110;
04973 
04974         //so the cgame knows for sure that we're an emplaced weapon
04975         ent->s.weapon = WP_EMPLACED_GUN;
04976 
04977         G_SetOrigin( ent, ent->s.origin );
04978         
04979         // store base angles for later
04980         VectorCopy( ent->s.angles, ent->pos1 );
04981         VectorCopy( ent->s.angles, ent->r.currentAngles );
04982         VectorCopy( ent->s.angles, ent->s.apos.trBase );
04983 
04984         ent->think = emplaced_gun_update;
04985         ent->nextthink = level.time + 50;
04986 
04987         ent->use = emplaced_gun_realuse;
04988 
04989         ent->r.svFlags |= SVF_PLAYER_USABLE;
04990 
04991         ent->s.pos.trType = TR_STATIONARY;
04992 
04993         ent->s.owner = MAX_CLIENTS+1;
04994         ent->s.shouldtarget = qtrue;
04995         //ent->s.teamowner = 0;
04996 
04997         trap_LinkEntity(ent);
04998 }

void thermalDetonatorExplode gentity_t ent  ) 
 

Definition at line 1934 of file g_weapon.c.

References BG_EvaluateTrajectory(), CHAN_WEAPON, gentity_s::count, entityShared_t::currentOrigin, DirToByte(), ET_GENERAL, entityState_s::eType, EV_MISSILE_MISS, gentity_s::freeAfterEvent, G_AddEvent(), g_entities, G_RadiusDamage(), G_SetOrigin(), G_Sound(), G_SoundIndex(), gentity_s::genericValue5, gentity_t, level, gentity_s::nextthink, entityShared_t::ownerNum, gentity_s::parent, entityState_s::pos, qtrue, gentity_s::r, gentity_s::s, gentity_s::splashDamage, gentity_s::splashMethodOfDeath, gentity_s::splashRadius, SVF_BROADCAST, entityShared_t::svFlags, thermalThinkStandard(), gentity_s::think, level_locals_t::time, trap_LinkEntity(), and vec3_t.

Referenced by thermalThinkStandard().

01936 {
01937         if ( !ent->count )
01938         {
01939                 G_Sound( ent, CHAN_WEAPON, G_SoundIndex( "sound/weapons/thermal/warning.wav" ) );
01940                 ent->count = 1;
01941                 ent->genericValue5 = level.time + 500;
01942                 ent->think = thermalThinkStandard;
01943                 ent->nextthink = level.time;
01944                 ent->r.svFlags |= SVF_BROADCAST;//so everyone hears/sees the explosion?
01945         }
01946         else
01947         {
01948                 vec3_t  origin;
01949                 vec3_t  dir={0,0,1};
01950 
01951                 BG_EvaluateTrajectory( &ent->s.pos, level.time, origin );
01952                 origin[2] += 8;
01953                 SnapVector( origin );
01954                 G_SetOrigin( ent, origin );
01955 
01956                 ent->s.eType = ET_GENERAL;
01957                 G_AddEvent( ent, EV_MISSILE_MISS, DirToByte( dir ) );
01958                 ent->freeAfterEvent = qtrue;
01959 
01960                 if (G_RadiusDamage( ent->r.currentOrigin, ent->parent,  ent->splashDamage, ent->splashRadius, 
01961                                 ent, ent, ent->splashMethodOfDeath))
01962                 {
01963                         g_entities[ent->r.ownerNum].client->accuracy_hits++;
01964                 }
01965 
01966                 trap_LinkEntity( ent );
01967         }
01968 }

void thermalThinkStandard gentity_t ent  ) 
 

Definition at line 1970 of file g_weapon.c.

References G_RunObject(), gentity_s::genericValue5, gentity_t, level, gentity_s::nextthink, thermalDetonatorExplode(), gentity_s::think, and level_locals_t::time.

Referenced by thermalDetonatorExplode(), and WP_FireThermalDetonator().

01971 {
01972         if (ent->genericValue5 < level.time)
01973         {
01974                 ent->think = thermalDetonatorExplode;
01975                 ent->nextthink = level.time;
01976                 return;
01977         }
01978 
01979         G_RunObject(ent);
01980         ent->nextthink = level.time;
01981 }

void touch_NULL gentity_t ent,
gentity_t other,
trace_t trace
 

Definition at line 165 of file g_weapon.c.

References gentity_t.

Referenced by laserTrapStick(), and WP_FireThermalDetonator().

00166 {
00167 
00168 }

void touchLaserTrap gentity_t ent,
gentity_t other,
trace_t trace
 

Definition at line 2294 of file g_weapon.c.

References gentity_s::activator, trace_t::endpos, gentity_s::enemy, trace_t::entityNum, ENTITYNUM_NONE, ENTITYNUM_WORLD, FRAMETIME, g_entities, gentity_t, laserTrapExplode(), laserTrapStick(), level, gentity_s::nextthink, cplane_s::normal, entityState_s::number, trace_t::plane, entityState_s::pos, gentity_s::s, gentity_s::think, level_locals_t::time, gentity_s::touch, trajectory_t::trDelta, and VectorCopy.

Referenced by CreateLaserTrap(), and laserTrapStick().

02295 {
02296         if (other && other->s.number < ENTITYNUM_WORLD)
02297         { //just explode if we hit any entity. This way we don't have things happening like tripmines floating
02298           //in the air after getting stuck to a moving door
02299                 if ( ent->activator != other )
02300                 {
02301                         ent->touch = 0;
02302                         ent->nextthink = level.time + FRAMETIME;
02303                         ent->think = laserTrapExplode;
02304                         VectorCopy(trace->plane.normal, ent->s.pos.trDelta);
02305                 }
02306         }
02307         else
02308         {
02309                 ent->touch = 0;
02310                 if (trace->entityNum != ENTITYNUM_NONE)
02311                 {
02312                         ent->enemy = &g_entities[trace->entityNum];
02313                 }
02314                 laserTrapStick(ent, trace->endpos, trace->plane.normal);
02315         }
02316 }

void TrapThink gentity_t ent  ) 
 

Definition at line 2469 of file g_weapon.c.

References G_RunObject(), gentity_t, level, gentity_s::nextthink, and level_locals_t::time.

Referenced by CreateLaserTrap().

02470 { //laser trap think
02471         ent->nextthink = level.time + 50;
02472         G_RunObject(ent);
02473 }

qboolean TryHeal gentity_t ent,
gentity_t target
 

Definition at line 1546 of file g_utils.c.

References bgSiegeClasses, BOTH_BUTTON_HOLD, BOTH_CONSOLE1, CHAN_AUTO, gentity_s::client, g_gametype, G_ScaleNetHealth(), G_SetAnim(), G_Sound(), G_SoundIndex(), gentity_t, GT_SIEGE, gentity_s::healingclass, gentity_s::healingDebounce, gentity_s::healingrate, gentity_s::healingsound, gentity_s::health, vmCvar_t::integer, gentity_s::inuse, level, gentity_s::maxHealth, siegeClass_t::name, NULL, gclient_s::ps, Q_stricmp(), qboolean, qfalse, qtrue, gentity_s::s, SETANIM_FLAG_HOLD, SETANIM_FLAG_OVERRIDE, SETANIM_TORSO, gclient_s::siegeClass, entityState_s::solid, SOLID_BMODEL, gentity_s::target_ent, level_locals_t::time, playerState_s::torsoAnim, and playerState_s::torsoTimer.

Referenced by emplaced_gun_use(), and TryUse().

01547 {
01548         if (g_gametype.integer == GT_SIEGE && ent->client->siegeClass != -1 &&
01549                 target && target->inuse && target->maxHealth && target->healingclass &&
01550                 target->healingclass[0] && target->health > 0 && target->health < target->maxHealth)
01551         { //it's not dead yet...
01552                 siegeClass_t *scl = &bgSiegeClasses[ent->client->siegeClass];
01553 
01554                 if (!Q_stricmp(scl->name, target->healingclass))
01555                 { //this thing can be healed by the class this player is using
01556                         if (target->healingDebounce < level.time)
01557                         { //do the actual heal
01558                                 target->health += 10;
01559                                 if (target->health > target->maxHealth)
01560                                 { //don't go too high
01561                                         target->health = target->maxHealth;
01562                                 }
01563                                 target->healingDebounce = level.time + target->healingrate;
01564                                 if (target->healingsound && target->healingsound[0])
01565                                 { //play it
01566                                         if (target->s.solid == SOLID_BMODEL)
01567                                         { //ok, well, just play it on the client then.
01568                                                 G_Sound(ent, CHAN_AUTO, G_SoundIndex(target->healingsound));
01569                                         }
01570                                         else
01571                                         {
01572                                                 G_Sound(target, CHAN_AUTO, G_SoundIndex(target->healingsound));
01573                                         }
01574                                 }
01575 
01576                                 //update net health for bar
01577                                 G_ScaleNetHealth(target);
01578                                 if (target->target_ent &&
01579                                         target->target_ent->maxHealth)
01580                                 {
01581                                         target->target_ent->health = target->health;
01582                                         G_ScaleNetHealth(target->target_ent);
01583                                 }
01584                         }
01585 
01586                         //keep them in the healing anim even when the healing debounce is not yet expired
01587                         if (ent->client->ps.torsoAnim == BOTH_BUTTON_HOLD ||
01588                                 ent->client->ps.torsoAnim == BOTH_CONSOLE1)
01589                         { //extend the time
01590                                 ent->client->ps.torsoTimer = 500;
01591                         }
01592                         else
01593                         {
01594                                 G_SetAnim( ent, NULL, SETANIM_TORSO, BOTH_BUTTON_HOLD, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0 );
01595                         }
01596 
01597                         return qtrue;
01598                 }
01599         }
01600 
01601         return qfalse;
01602 }

void VectorNPos vec3_t  in,
vec3_t  out
 

Definition at line 2634 of file g_weapon.c.

References vec3_t.

Referenced by charge_stick().

02635 {
02636         if (in[0] < 0) { out[0] = -in[0]; } else { out[0] = in[0]; }
02637         if (in[1] < 0) { out[1] = -in[1]; } else { out[1] = in[1]; }
02638         if (in[2] < 0) { out[2] = -in[2]; } else { out[2] = in[2]; }
02639 }

void W_TraceSetStart gentity_t ent,
vec3_t  start,
vec3_t  mins,
vec3_t  maxs
 

Definition at line 180 of file g_weapon.c.

References trace_t::allsolid, gentity_s::client, CONTENTS_SHOTCLIP, entityShared_t::currentOrigin, trace_t::endpos, trace_t::fraction, G_BoxInBounds(), gentity_t, MASK_SOLID, entityShared_t::maxs, entityShared_t::mins, entityState_s::number, entityState_s::pos, gclient_s::ps, gentity_s::r, gentity_s::s, trace_t::startsolid, trap_Trace(), trajectory_t::trBase, vec3_t, VectorAdd, VectorCopy, and playerState_s::viewheight.

Referenced by WP_FireThermalDetonator().

00182 {
00183         //make sure our start point isn't on the other side of a wall
00184         trace_t tr;
00185         vec3_t  entMins;
00186         vec3_t  entMaxs;
00187         vec3_t  eyePoint;
00188 
00189         VectorAdd( ent->r.currentOrigin, ent->r.mins, entMins );
00190         VectorAdd( ent->r.currentOrigin, ent->r.maxs, entMaxs );
00191 
00192         if ( G_BoxInBounds( start, mins, maxs, entMins, entMaxs ) )
00193         {
00194                 return;
00195         }
00196 
00197         if ( !ent->client )
00198         {
00199                 return;
00200         }
00201 
00202         VectorCopy( ent->s.pos.trBase, eyePoint);
00203         eyePoint[2] += ent->client->ps.viewheight;
00204                 
00205         trap_Trace( &tr, eyePoint, mins, maxs, start, ent->s.number, MASK_SOLID|CONTENTS_SHOTCLIP );
00206 
00207         if ( tr.startsolid || tr.allsolid )
00208         {
00209                 return;
00210         }
00211 
00212         if ( tr.fraction < 1.0f )
00213         {
00214                 VectorCopy( tr.endpos, start );
00215         }
00216 }

void WP_CalcVehMuzzle gentity_t ent,
int  muzzleNum
 

Definition at line 3575 of file g_weapon.c.

References gentity_s::client, gentity_t, gentity_s::ghoul2, level, Vehicle_s::m_iMuzzleTag, Vehicle_s::m_iMuzzleTime, gentity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, Vehicle_s::m_vMuzzleDir, Vehicle_s::m_vMuzzlePos, gentity_s::modelScale, NEGATIVE_Y, NULL, ORIGIN, playerState_s::origin, PITCH, gclient_s::ps, ROLL, level_locals_t::time, trap_G2API_GetBoltMatrix_NoRecNoRot(), vehicleInfo_t::type, vec3_t, VectorCopy, Vehicle_t, VH_ANIMAL, VH_SPEEDER, VH_WALKER, and playerState_s::viewangles.

Referenced by FireVehicleWeapon(), VEH_TurretAim(), VEH_TurretCheckFire(), and VEH_TurretThink().

03576 {
03577         Vehicle_t *pVeh = ent->m_pVehicle;
03578         mdxaBone_t boltMatrix;
03579         vec3_t  vehAngles;
03580 
03581         assert(pVeh);
03582 
03583         if (pVeh->m_iMuzzleTime[muzzleNum] == level.time)
03584         { //already done for this frame, don't need to do it again
03585                 return;
03586         }
03587         //Uh... how about we set this, hunh...?  :)
03588         pVeh->m_iMuzzleTime[muzzleNum] = level.time;
03589         
03590         VectorCopy( ent->client->ps.viewangles, vehAngles );
03591         if ( pVeh->m_pVehicleInfo
03592                 && (pVeh->m_pVehicleInfo->type == VH_ANIMAL
03593                          ||pVeh->m_pVehicleInfo->type == VH_WALKER
03594                          ||pVeh->m_pVehicleInfo->type == VH_SPEEDER) )
03595         {
03596                 vehAngles[PITCH] = vehAngles[ROLL] = 0;
03597         }
03598 
03599         trap_G2API_GetBoltMatrix_NoRecNoRot(ent->ghoul2, 0, pVeh->m_iMuzzleTag[muzzleNum], &boltMatrix, vehAngles,
03600                 ent->client->ps.origin, level.time, NULL, ent->modelScale);
03601         BG_GiveMeVectorFromMatrix(&boltMatrix, ORIGIN, pVeh->m_vMuzzlePos[muzzleNum]);
03602         BG_GiveMeVectorFromMatrix(&boltMatrix, NEGATIVE_Y, pVeh->m_vMuzzleDir[muzzleNum]);
03603 }

void WP_DisruptorAltFire gentity_t ent  ) 
 

Definition at line 640 of file g_weapon.c.

References gclient_s::accuracy_hits, entityState_s::angles, gentity_s::client, entityShared_t::contents, entityShared_t::currentOrigin, d_projectileGhoul2Collision, DAMAGE_NO_KNOCKBACK, DirToByte(), DISRUPTOR_ALT_DAMAGE, DISRUPTOR_ALT_TRACES, DISRUPTOR_CHARGE_UNIT, playerState_s::duelIndex, playerState_s::duelInProgress, EF_ALT_FIRING, EF_DISINTEGRATION, playerState_s::eFlags, entityState_s::eFlags, trace_t::endpos, trace_t::entityNum, ET_MOVER, entityState_s::eType, EV_DISRUPTOR_HIT, EV_DISRUPTOR_SNIPER_MISS, EV_DISRUPTOR_SNIPER_SHOT, EV_MISSILE_MISS, EV_SABER_BLOCK, entityState_s::eventParm, playerState_s::fd, FL_SHIELDED, gentity_s::flags, FORCE_LEVEL_3, forcedata_s::forcePowerLevel, FP_SABER_DEFENSE, gclient_s::g2LastSurfaceHit, gclient_s::g2LastSurfaceTime, G2TRFLAG_DOGHOULTRACE, G2TRFLAG_GETSURFINDEX, G2TRFLAG_HITCORPSES, G2TRFLAG_THICK, G_CanDisruptify(), G_Damage(), g_entities, g_g2TraceLod, g_gametype, G_GetHitLocation(), G_TempEntity(), gentity_t, gentity_s::ghoul2, GT_SIEGE, gentity_s::health, vmCvar_t::integer, gentity_s::inuse, Jedi_DodgeEvasion(), playerState_s::lastHitLoc, playerState_s::legsAnim, entityState_s::legsAnim, level, LogAccuracyHit(), MASK_SHOT, MOD_DISRUPTOR_SNIPER, cplane_s::normal, NULL, entityState_s::number, entityState_s::origin, playerState_s::origin, entityState_s::origin2, entityState_s::otherEntityNum, trace_t::plane, gclient_s::ps, qboolean, qfalse, qtrue, gentity_s::r, gentity_s::s, entityState_s::shouldtarget, SURF_NOIMPACT, trace_t::surfaceFlags, SVF_GLASS_BRUSH, entityShared_t::svFlags, gentity_s::takedamage, level_locals_t::time, playerState_s::torsoAnim, trap_G2Trace(), trap_Trace(), vec3_t, VectorClear, VectorCopy, VectorMA, playerState_s::velocity, playerState_s::viewangles, playerState_s::viewheight, entityState_s::weapon, playerState_s::weaponChargeTime, and WP_SaberCanBlock().

00642 {
00643         int                     damage = 0, skip;
00644         qboolean        render_impact = qtrue;
00645         vec3_t          start, end;
00646         vec3_t          muzzle2;
00647         trace_t         tr;
00648         gentity_t       *traceEnt, *tent;
00649         float           shotRange = 8192.0f;
00650         int                     i;
00651         int                     count, maxCount = 60;
00652         int                     traces = DISRUPTOR_ALT_TRACES;
00653         qboolean        fullCharge = qfalse;
00654 
00655         damage = DISRUPTOR_ALT_DAMAGE-30;
00656 
00657         VectorCopy( muzzle, muzzle2 ); // making a backup copy
00658 
00659         if (ent->client)
00660         {
00661                 VectorCopy( ent->client->ps.origin, start );
00662                 start[2] += ent->client->ps.viewheight;//By eyes
00663 
00664                 count = ( level.time - ent->client->ps.weaponChargeTime ) / DISRUPTOR_CHARGE_UNIT;
00665                 if ( g_gametype.integer == GT_SIEGE )
00666                 {//maybe a full alt-charge should be a *bit* more dangerous in Siege mode?
00667                         //maxCount = ceil((200.0f-(float)damage)/2.0f);//cap at 200 damage total
00668                         maxCount = 200;//the previous line ALWAYS evaluated to 135 - was that on purpose?
00669                 }
00670         }
00671         else
00672         {
00673                 VectorCopy( ent->r.currentOrigin, start );
00674                 start[2] += 24;
00675 
00676                 count = ( 100 ) / DISRUPTOR_CHARGE_UNIT;
00677         }
00678 
00679         count *= 2;
00680 
00681         if ( count < 1 )
00682         {
00683                 count = 1;
00684         }
00685         else if ( count >= maxCount )
00686         {
00687                 count = maxCount;
00688                 fullCharge = qtrue;
00689         }
00690 
00691         // more powerful charges go through more things
00692         if ( count < 10 )
00693         {
00694                 traces = 1;
00695         }
00696         else if ( count < 20 )
00697         {
00698                 traces = 2;
00699         }
00700 
00701         damage += count;
00702         
00703         skip = ent->s.number;
00704 
00705         for (i = 0; i < traces; i++ )
00706         {
00707                 VectorMA( start, shotRange, forward, end );
00708 
00709                 if (d_projectileGhoul2Collision.integer)
00710                 {
00711                         trap_G2Trace( &tr, start, NULL, NULL, end, skip, MASK_SHOT, G2TRFLAG_DOGHOULTRACE|G2TRFLAG_GETSURFINDEX|G2TRFLAG_THICK|G2TRFLAG_HITCORPSES, g_g2TraceLod.integer );
00712                 }
00713                 else
00714                 {
00715                         trap_Trace( &tr, start, NULL, NULL, end, skip, MASK_SHOT );
00716                 }
00717 
00718                 traceEnt = &g_entities[tr.entityNum];
00719 
00720                 if (d_projectileGhoul2Collision.integer && traceEnt->inuse && traceEnt->client)
00721                 { //g2 collision checks -rww
00722                         if (traceEnt->inuse && traceEnt->client && traceEnt->ghoul2)
00723                         { //since we used G2TRFLAG_GETSURFINDEX, tr.surfaceFlags will actually contain the index of the surface on the ghoul2 model we collided with.
00724                                 traceEnt->client->g2LastSurfaceHit = tr.surfaceFlags;
00725                                 traceEnt->client->g2LastSurfaceTime = level.time;
00726                         }
00727 
00728                         if (traceEnt->ghoul2)
00729                         {
00730                                 tr.surfaceFlags = 0; //clear the surface flags after, since we actually care about them in here.
00731                         }
00732                 }
00733 
00734                 if ( tr.surfaceFlags & SURF_NOIMPACT ) 
00735                 {
00736                         render_impact = qfalse;
00737                 }
00738 
00739                 if (traceEnt && traceEnt->client && traceEnt->client->ps.duelInProgress &&
00740                         traceEnt->client->ps.duelIndex != ent->s.number)
00741                 {
00742                         skip = tr.entityNum;
00743                         VectorCopy(tr.endpos, start);
00744                         continue;
00745                 }
00746 
00747                 if (Jedi_DodgeEvasion(traceEnt, ent, &tr, G_GetHitLocation(traceEnt, tr.endpos)))
00748                 {
00749                         skip = tr.entityNum;
00750                         VectorCopy(tr.endpos, start);
00751                         continue;
00752                 }
00753                 else if (traceEnt && traceEnt->client && traceEnt->client->ps.fd.forcePowerLevel[FP_SABER_DEFENSE] >= FORCE_LEVEL_3)
00754                 {
00755                         if (WP_SaberCanBlock(traceEnt, tr.endpos, 0, MOD_DISRUPTOR_SNIPER, qtrue, 0))
00756                         { //broadcast and stop the shot because it was blocked
00757                                 gentity_t *te = NULL;
00758 
00759                                 tent = G_TempEntity( tr.endpos, EV_DISRUPTOR_SNIPER_SHOT );
00760                                 VectorCopy( muzzle, tent->s.origin2 );
00761                                 tent->s.shouldtarget = fullCharge;
00762                                 tent->s.eventParm = ent->s.number;
00763 
00764                                 te = G_TempEntity( tr.endpos, EV_SABER_BLOCK );
00765                                 VectorCopy(tr.endpos, te->s.origin);
00766                                 VectorCopy(tr.plane.normal, te->s.angles);
00767                                 if (!te->s.angles[0] && !te->s.angles[1] && !te->s.angles[2])
00768                                 {
00769                                         te->s.angles[1] = 1;
00770                                 }
00771                                 te->s.eventParm = 0;
00772                                 te->s.weapon = 0;//saberNum
00773                                 te->s.legsAnim = 0;//bladeNum
00774 
00775                                 return;
00776                         }
00777                 }
00778 
00779                 // always render a shot beam, doing this the old way because I don't much feel like overriding the effect.
00780                 tent = G_TempEntity( tr.endpos, EV_DISRUPTOR_SNIPER_SHOT );
00781                 VectorCopy( muzzle, tent->s.origin2 );
00782                 tent->s.shouldtarget = fullCharge;
00783                 tent->s.eventParm = ent->s.number;
00784 
00785                 // If the beam hits a skybox, etc. it would look foolish to add impact effects
00786                 if ( render_impact ) 
00787                 {
00788                         if ( traceEnt->takedamage && traceEnt->client )
00789                         {
00790                                 tent->s.otherEntityNum = traceEnt->s.number;
00791 
00792                                 // Create a simple impact type mark
00793                                 tent = G_TempEntity(tr.endpos, EV_MISSILE_MISS);
00794                                 tent->s.eventParm = DirToByte(tr.plane.normal);
00795                                 tent->s.eFlags |= EF_ALT_FIRING;
00796         
00797                                 if ( LogAccuracyHit( traceEnt, ent )) 
00798                                 {
00799                                         if (ent->client)
00800                                         {
00801                                                 ent->client->accuracy_hits++;
00802                                         }
00803                                 }
00804                         } 
00805                         else 
00806                         {
00807                                  if ( traceEnt->r.svFlags & SVF_GLASS_BRUSH 
00808                                                 || traceEnt->takedamage 
00809                                                 || traceEnt->s.eType == ET_MOVER )
00810                                  {
00811                                         if ( traceEnt->takedamage )
00812                                         {
00813                                                 G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, 
00814                                                                 DAMAGE_NO_KNOCKBACK, MOD_DISRUPTOR_SNIPER );
00815 
00816                                                 tent = G_TempEntity( tr.endpos, EV_DISRUPTOR_HIT );
00817                                                 tent->s.eventParm = DirToByte( tr.plane.normal );
00818                                         }
00819                                  }
00820                                  else
00821                                  {
00822                                          // Hmmm, maybe don't make any marks on things that could break
00823                                         tent = G_TempEntity( tr.endpos, EV_DISRUPTOR_SNIPER_MISS );
00824                                         tent->s.eventParm = DirToByte( tr.plane.normal );
00825                                  }
00826                                 break; // and don't try any more traces
00827                         }
00828 
00829                         if ( (traceEnt->flags&FL_SHIELDED) )
00830                         {//stops us cold
00831                                 break;
00832                         }
00833 
00834                         if ( traceEnt->takedamage )
00835                         {
00836                                 vec3_t preAng;
00837                                 int preHealth = traceEnt->health;
00838                                 int preLegs = 0;
00839                                 int preTorso = 0;
00840 
00841                                 if (traceEnt->client)
00842                                 {
00843                                         preLegs = traceEnt->client->ps.legsAnim;
00844                                         preTorso = traceEnt->client->ps.torsoAnim;
00845                                         VectorCopy(traceEnt->client->ps.viewangles, preAng);
00846                                 }
00847 
00848                                 G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, DAMAGE_NO_KNOCKBACK, MOD_DISRUPTOR_SNIPER );
00849 
00850                                 if (traceEnt->client && preHealth > 0 && traceEnt->health <= 0 && fullCharge &&
00851                                         G_CanDisruptify(traceEnt))
00852                                 { //was killed by a fully charged sniper shot, so disintegrate
00853                                         VectorCopy(preAng, traceEnt->client->ps.viewangles);
00854 
00855                                         traceEnt->client->ps.eFlags |= EF_DISINTEGRATION;
00856                                         VectorCopy(tr.endpos, traceEnt->client->ps.lastHitLoc);
00857 
00858                                         traceEnt->client->ps.legsAnim = preLegs;
00859                                         traceEnt->client->ps.torsoAnim = preTorso;
00860 
00861                                         traceEnt->r.contents = 0;
00862 
00863                                         VectorClear(traceEnt->client->ps.velocity);
00864                                 }
00865 
00866                                 tent = G_TempEntity( tr.endpos, EV_DISRUPTOR_HIT );
00867                                 tent->s.eventParm = DirToByte( tr.plane.normal );
00868                                 if (traceEnt->client)
00869                                 {
00870                                         tent->s.weapon = 1;
00871                                 }
00872                         }
00873                 }
00874                 else // not rendering impact, must be a skybox or other similar thing?
00875                 {
00876                         break; // don't try anymore traces
00877                 }
00878 
00879                 // Get ready for an attempt to trace through another person
00880                 VectorCopy( tr.endpos, muzzle );
00881                 VectorCopy( tr.endpos, start );
00882                 skip = tr.entityNum;
00883         }
00884 }

void WP_DropDetPack gentity_t ent,
qboolean  alt_fire
 

Definition at line 2878 of file g_weapon.c.

References AngleVectors(), BlowDetpacks(), CalcMuzzlePoint(), CheatsOn(), gentity_s::client, drop_charge(), ENTITYNUM_NONE, FOFS, g_entities, G_Find(), G_FreeEntity(), gentity_t, playerState_s::hasDetPackPlanted, level, MAX_GENTITIES, NULL, entityState_s::number, gentity_s::parent, gclient_s::ps, qtrue, gentity_s::s, gentity_s::setTime, level_locals_t::time, VectorMA, VectorNormalize(), and playerState_s::viewangles.

Referenced by FireWeapon().

02879 {
02880         gentity_t       *found = NULL;
02881         int                     trapcount = 0;
02882         int                     foundDetPacks[MAX_GENTITIES] = {ENTITYNUM_NONE};
02883         int                     trapcount_org;
02884         int                     lowestTimeStamp;
02885         int                     removeMe;
02886         int                     i;
02887 
02888         if ( !ent || !ent->client )
02889         {
02890                 return;
02891         }
02892 
02893         //limit to 10 placed at any one time
02894         //see how many there are now
02895         while ( (found = G_Find( found, FOFS(classname), "detpack" )) != NULL )
02896         {
02897                 if ( found->parent != ent )
02898                 {
02899                         continue;
02900                 }
02901                 foundDetPacks[trapcount++] = found->s.number;
02902         }
02903         //now remove first ones we find until there are only 9 left
02904         found = NULL;
02905         trapcount_org = trapcount;
02906         lowestTimeStamp = level.time;
02907         while ( trapcount > 9 )
02908         {
02909                 removeMe = -1;
02910                 for ( i = 0; i < trapcount_org; i++ )
02911                 {
02912                         if ( foundDetPacks[i] == ENTITYNUM_NONE )
02913                         {
02914                                 continue;
02915                         }
02916                         found = &g_entities[foundDetPacks[i]];
02917                         if ( found->setTime < lowestTimeStamp )
02918                         {
02919                                 removeMe = i;
02920                                 lowestTimeStamp = found->setTime;
02921                         }
02922                 }
02923                 if ( removeMe != -1 )
02924                 {
02925                         //remove it... or blow it?
02926                         if ( &g_entities[foundDetPacks[removeMe]] == NULL )
02927                         {
02928                                 break;
02929                         }
02930                         else
02931                         {
02932                                 if (!CheatsOn())
02933                                 { //Let them have unlimited if cheats are enabled
02934                                         G_FreeEntity( &g_entities[foundDetPacks[removeMe]] );
02935                                 }
02936                         }
02937                         foundDetPacks[removeMe] = ENTITYNUM_NONE;
02938                         trapcount--;
02939                 }
02940                 else
02941                 {
02942                         break;
02943                 }
02944         }
02945 
02946         if ( alt_fire  )
02947         {
02948                 BlowDetpacks(ent);
02949         }
02950         else
02951         {
02952                 AngleVectors( ent->client->ps.viewangles, forward, vright, up );
02953 
02954                 CalcMuzzlePoint( ent, forward, vright, up, muzzle );
02955 
02956                 VectorNormalize( forward );
02957                 VectorMA( muzzle, -4, forward, muzzle );
02958                 drop_charge( ent, muzzle, forward );
02959 
02960                 ent->client->ps.hasDetPackPlanted = qtrue;
02961         }
02962 }

gentity_t* WP_DropThermal gentity_t ent  ) 
 

Definition at line 2072 of file g_weapon.c.

References AngleVectors(), gentity_s::client, gentity_t, gclient_s::ps, qfalse, playerState_s::viewangles, and WP_FireThermalDetonator().

02073 {
02074         AngleVectors( ent->client->ps.viewangles, forward, vright, up );
02075         return (WP_FireThermalDetonator( ent, qfalse ));
02076 }

void WP_ExplosiveDie gentity_t self,
gentity_t inflictor,
gentity_t attacker,
int  damage,
int  mod
 

Definition at line 1541 of file g_weapon.c.

References gentity_t, and laserTrapExplode().

01542 {
01543         laserTrapExplode(self);
01544 }

void WP_FireBlasterMissile gentity_t ent,
vec3_t  start,
vec3_t  dir,
qboolean  altFire
 

Definition at line 357 of file g_weapon.c.

References BLASTER_DAMAGE, BLASTER_VELOCITY, gentity_s::bounceCount, gentity_s::classname, gentity_s::clipmask, CONTENTS_LIGHTSABER, CreateMissile(), gentity_s::damage, DAMAGE_DEATH_KNOCKBACK, gentity_s::dflags, ET_NPC, entityState_s::eType, gentity_t, MASK_SHOT, gentity_s::methodOfDeath, MOD_BLASTER, gentity_s::s, vec3_t, entityState_s::weapon, and WP_BLASTER.

Referenced by Use_Shooter().

00359 {
00360         int velocity    = BLASTER_VELOCITY;
00361         int     damage          = BLASTER_DAMAGE;
00362         gentity_t *missile;
00363 
00364         if (ent->s.eType == ET_NPC)
00365         { //animent
00366                 damage = 10;
00367         }
00368 
00369         missile = CreateMissile( start, dir, velocity, 10000, ent, altFire );
00370 
00371         missile->classname = "blaster_proj";
00372         missile->s.weapon = WP_BLASTER;
00373 
00374         missile->damage = damage;
00375         missile->dflags = DAMAGE_DEATH_KNOCKBACK;
00376         missile->methodOfDeath = MOD_BLASTER;
00377         missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER;
00378 
00379         // we don't want it to bounce forever
00380         missile->bounceCount = 8;
00381 }

void WP_FireEmplacedMissile gentity_t ent,
vec3_t  start,
vec3_t  dir,
qboolean  altFire,
gentity_t ignore
 

Definition at line 420 of file g_weapon.c.

References gentity_s::activator, BLASTER_DAMAGE, BLASTER_VELOCITY, gentity_s::bounceCount, gentity_s::classname, gentity_s::clipmask, CONTENTS_LIGHTSABER, CreateMissile(), gentity_s::damage, DAMAGE_DEATH_KNOCKBACK, DAMAGE_HEAVY_WEAP_CLASS, gentity_s::dflags, gentity_t, MASK_SHOT, gentity_s::methodOfDeath, MOD_VEHICLE, entityState_s::number, gentity_s::passThroughNum, gentity_s::s, vec3_t, entityState_s::weapon, and WP_TURRET.

00422 {
00423         int velocity    = BLASTER_VELOCITY;
00424         int     damage          = BLASTER_DAMAGE;
00425         gentity_t *missile;
00426 
00427         missile = CreateMissile( start, dir, velocity, 10000, ent, altFire );
00428 
00429         missile->classname = "emplaced_gun_proj";
00430         missile->s.weapon = WP_TURRET;//WP_EMPLACED_GUN;
00431 
00432         missile->activator = ignore;
00433 
00434         missile->damage = damage;
00435         missile->dflags = (DAMAGE_DEATH_KNOCKBACK|DAMAGE_HEAVY_WEAP_CLASS);
00436         missile->methodOfDeath = MOD_VEHICLE;
00437         missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER;
00438 
00439         if (ignore)
00440         {
00441                 missile->passThroughNum = ignore->s.number+1;
00442         }
00443 
00444         // we don't want it to bounce forever
00445         missile->bounceCount = 8;
00446 }

void WP_FireGenericBlasterMissile gentity_t ent,
vec3_t  start,
vec3_t  dir,
qboolean  altFire,
int  damage,
int  velocity,
int  mod
 

Definition at line 329 of file g_weapon.c.

References gentity_s::bounceCount, gentity_s::classname, gentity_s::clipmask, CONTENTS_LIGHTSABER, CreateMissile(), gentity_s::damage, DAMAGE_DEATH_KNOCKBACK, gentity_s::dflags, gentity_t, MASK_SHOT, gentity_s::methodOfDeath, gentity_s::s, vec3_t, entityState_s::weapon, and WP_BRYAR_PISTOL.

Referenced by SeekerDroneUpdate().

00331 {
00332         gentity_t *missile;
00333 
00334         missile = CreateMissile( start, dir, velocity, 10000, ent, altFire );
00335 
00336         missile->classname = "generic_proj";
00337         missile->s.weapon = WP_BRYAR_PISTOL;
00338 
00339         missile->damage = damage;
00340         missile->dflags = DAMAGE_DEATH_KNOCKBACK;
00341         missile->methodOfDeath = mod;
00342         missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER;
00343 
00344         // we don't want it to bounce forever
00345         missile->bounceCount = 8;
00346 }

void WP_FireMelee gentity_t ent,
qboolean  alt_fire
 

Definition at line 3358 of file g_weapon.c.

References BOTH_MELEE2, BROKENLIMB_LARM, BROKENLIMB_RARM, playerState_s::brokenLimbs, CHAN_AUTO, gentity_s::client, entityShared_t::currentOrigin, DAMAGE_NO_ARMOR, playerState_s::duelIndex, playerState_s::duelInProgress, trace_t::endpos, trace_t::entityNum, ENTITYNUM_NONE, G_Damage(), g_entities, G_HeavyMelee(), G_Sound(), G_SoundIndex(), gentity_t, MASK_SHOT, MELEE_RANGE, MELEE_SWING1_DAMAGE, MELEE_SWING2_DAMAGE, MOD_MELEE, entityState_s::number, playerState_s::origin, gclient_s::ps, Q_irand(), gentity_s::r, gentity_s::s, gentity_s::takedamage, playerState_s::torsoAnim, trap_Trace(), va(), vec3_t, VectorCopy, VectorMA, VectorScale, VectorSet, and playerState_s::viewheight.

Referenced by FireWeapon().

03359 {
03360         gentity_t       *tr_ent;
03361         trace_t         tr;
03362         vec3_t          mins, maxs, end;
03363         vec3_t          muzzlePunch;
03364 
03365         if (ent->client && ent->client->ps.torsoAnim == BOTH_MELEE2)
03366         { //right
03367                 if (ent->client->ps.brokenLimbs & (1 << BROKENLIMB_RARM))
03368                 {
03369                         return;
03370                 }
03371         }
03372         else
03373         { //left
03374                 if (ent->client->ps.brokenLimbs & (1 << BROKENLIMB_LARM))
03375                 {
03376                         return;
03377                 }
03378         }
03379 
03380         if (!ent->client)
03381         {
03382                 VectorCopy(ent->r.currentOrigin, muzzlePunch);
03383                 muzzlePunch[2] += 8;
03384         }
03385         else
03386         {
03387                 VectorCopy(ent->client->ps.origin, muzzlePunch);
03388                 muzzlePunch[2] += ent->client->ps.viewheight-6;
03389         }
03390 
03391         VectorMA(muzzlePunch, 20.0f, forward, muzzlePunch);
03392         VectorMA(muzzlePunch, 4.0f, vright, muzzlePunch);
03393 
03394         VectorMA( muzzlePunch, MELEE_RANGE, forward, end );
03395 
03396         VectorSet( maxs, 6, 6, 6 );
03397         VectorScale( maxs, -1, mins );
03398 
03399         trap_Trace ( &tr, muzzlePunch, mins, maxs, end, ent->s.number, MASK_SHOT );
03400 
03401         if (tr.entityNum != ENTITYNUM_NONE)
03402         { //hit something
03403                 tr_ent = &g_entities[tr.entityNum];
03404 
03405                 G_Sound( ent, CHAN_AUTO, G_SoundIndex( va("sound/weapons/melee/punch%d", Q_irand(1, 4)) ) );
03406 
03407                 if (tr_ent->takedamage && tr_ent->client)
03408                 { //special duel checks
03409                         if (tr_ent->client->ps.duelInProgress &&
03410                                 tr_ent->client->ps.duelIndex != ent->s.number)
03411                         {
03412                                 return;
03413                         }
03414 
03415                         if (ent->client &&
03416                                 ent->client->ps.duelInProgress &&
03417                                 ent->client->ps.duelIndex != tr_ent->s.number)
03418                         {
03419                                 return;
03420                         }
03421                 }
03422 
03423                 if ( tr_ent->takedamage )
03424                 { //damage them, do more damage if we're in the second right hook
03425                         int dmg = MELEE_SWING1_DAMAGE;
03426 
03427                         if (ent->client && ent->client->ps.torsoAnim == BOTH_MELEE2)
03428                         { //do a tad bit more damage on the second swing
03429                                 dmg = MELEE_SWING2_DAMAGE;
03430                         }
03431 
03432                         if ( G_HeavyMelee( ent ) )
03433                         { //2x damage for heavy melee class
03434                                 dmg *= 2;
03435                         }
03436 
03437                         G_Damage( tr_ent, ent, ent, forward, tr.endpos, dmg, DAMAGE_NO_ARMOR, MOD_MELEE );
03438                 }
03439         }
03440 }

void WP_FireStunBaton gentity_t ent,
qboolean  alt_fire
 

Definition at line 3277 of file g_weapon.c.

References CHAN_WEAPON, CLASS_VEHICLE, gentity_s::client, entityShared_t::currentOrigin, DAMAGE_HALF_ABSORB, DAMAGE_NO_KNOCKBACK, playerState_s::duelIndex, playerState_s::duelInProgress, EFFECT_STUNHIT, playerState_s::electrifyTime, trace_t::endpos, trace_t::entityNum, ENTITYNUM_WORLD, G_Damage(), g_entities, G_PlayEffect(), G_Sound(), G_SoundIndex(), gentity_t, level, gentity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, MASK_SHOT, MOD_STUN_BATON, cplane_s::normal, gclient_s::NPC_class, entityState_s::number, playerState_s::origin, trace_t::plane, gclient_s::ps, Q_irand(), gentity_s::r, gentity_s::s, STUN_BATON_DAMAGE, STUN_BATON_RANGE, gentity_s::takedamage, level_locals_t::time, trap_Trace(), vehicleInfo_t::type, va(), vec3_t, VectorCopy, VectorMA, VectorScale, VectorSet, VH_ANIMAL, VH_FLIER, and playerState_s::viewheight.

Referenced by FireWeapon().

03278 {
03279         gentity_t       *tr_ent;
03280         trace_t         tr;
03281         vec3_t          mins, maxs, end;
03282         vec3_t          muzzleStun;
03283 
03284         if (!ent->client)
03285         {
03286                 VectorCopy(ent->r.currentOrigin, muzzleStun);
03287                 muzzleStun[2] += 8;
03288         }
03289         else
03290         {
03291                 VectorCopy(ent->client->ps.origin, muzzleStun);
03292                 muzzleStun[2] += ent->client->ps.viewheight-6;
03293         }
03294 
03295         VectorMA(muzzleStun, 20.0f, forward, muzzleStun);
03296         VectorMA(muzzleStun, 4.0f, vright, muzzleStun);
03297 
03298         VectorMA( muzzleStun, STUN_BATON_RANGE, forward, end );
03299 
03300         VectorSet( maxs, 6, 6, 6 );
03301         VectorScale( maxs, -1, mins );
03302 
03303         trap_Trace ( &tr, muzzleStun, mins, maxs, end, ent->s.number, MASK_SHOT );
03304 
03305         if ( tr.entityNum >= ENTITYNUM_WORLD )
03306         {
03307                 return;
03308         }
03309 
03310         tr_ent = &g_entities[tr.entityNum];
03311 
03312         if (tr_ent && tr_ent->takedamage && tr_ent->client)
03313         { //see if either party is involved in a duel
03314                 if (tr_ent->client->ps.duelInProgress &&
03315                         tr_ent->client->ps.duelIndex != ent->s.number)
03316                 {
03317                         return;
03318                 }
03319 
03320                 if (ent->client &&
03321                         ent->client->ps.duelInProgress &&
03322                         ent->client->ps.duelIndex != tr_ent->s.number)
03323                 {
03324                         return;
03325                 }
03326         }
03327 
03328         if ( tr_ent && tr_ent->takedamage )
03329         {
03330                 G_PlayEffect( EFFECT_STUNHIT, tr.endpos, tr.plane.normal );
03331 
03332                 G_Sound( tr_ent, CHAN_WEAPON, G_SoundIndex( va("sound/weapons/melee/punch%d", Q_irand(1, 4)) ) );
03333                 G_Damage( tr_ent, ent, ent, forward, tr.endpos, STUN_BATON_DAMAGE, (DAMAGE_NO_KNOCKBACK|DAMAGE_HALF_ABSORB), MOD_STUN_BATON );
03334 
03335                 if (tr_ent->client)
03336                 { //if it's a player then use the shock effect
03337                         if ( tr_ent->client->NPC_class == CLASS_VEHICLE )
03338                         {//not on vehicles
03339                                 if ( !tr_ent->m_pVehicle
03340                                         || tr_ent->m_pVehicle->m_pVehicleInfo->type == VH_ANIMAL 
03341                                         || tr_ent->m_pVehicle->m_pVehicleInfo->type == VH_FLIER )
03342                                 {//can zap animals
03343                                         tr_ent->client->ps.electrifyTime = level.time + Q_irand( 3000, 4000 );
03344                                 }
03345                         }
03346                         else
03347                         {
03348                                 tr_ent->client->ps.electrifyTime = level.time + 700;
03349                         }
03350                 }
03351         }
03352 }

gentity_t* WP_FireThermalDetonator gentity_t ent,
qboolean  altFire
 

Definition at line 1984 of file g_weapon.c.

References gentity_s::bounceCount, gentity_s::classname, gentity_s::client, gentity_s::clipmask, entityShared_t::currentOrigin, gentity_s::damage, gentity_s::dflags, ET_MISSILE, entityState_s::eType, FL_BOUNCE_HALF, gentity_s::flags, G_SoundIndex(), G_Spawn(), gentity_s::genericValue5, gentity_t, gentity_s::health, level, entityState_s::loopIsSoundset, entityState_s::loopSound, MASK_SHOT, entityShared_t::maxs, gentity_s::methodOfDeath, entityShared_t::mins, MOD_THERMAL, MOD_THERMAL_SPLASH, gentity_s::nextthink, entityState_s::number, entityShared_t::ownerNum, gentity_s::parent, gentity_s::physicsObject, entityState_s::pos, gentity_s::pos2, gclient_s::ps, qfalse, qtrue, gentity_s::r, gentity_s::s, gentity_s::splashDamage, gentity_s::splashMethodOfDeath, gentity_s::splashRadius, SVF_USE_CURRENT_ORIGIN, entityShared_t::svFlags, TD_DAMAGE, TD_MIN_CHARGE, TD_SPLASH_DAM, TD_SPLASH_RAD, TD_TIME, TD_VELOCITY, thermalThinkStandard(), gentity_s::think, level_locals_t::time, gentity_s::touch, touch_NULL(), TR_GRAVITY, trajectory_t::trBase, trajectory_t::trDelta, trajectory_t::trTime, trajectory_t::trType, vec3_t, VectorCopy, VectorScale, VectorSet, W_TraceSetStart(), entityState_s::weapon, playerState_s::weaponChargeTime, and WP_THERMAL.

Referenced by FireWeapon(), and WP_DropThermal().

01986 {
01987         gentity_t       *bolt;
01988         vec3_t          dir, start;
01989         float chargeAmount = 1.0f; // default of full charge
01990         
01991         VectorCopy( forward, dir );
01992         VectorCopy( muzzle, start );
01993 
01994         bolt = G_Spawn();
01995         
01996         bolt->physicsObject = qtrue;
01997 
01998         bolt->classname = "thermal_detonator";
01999         bolt->think = thermalThinkStandard;
02000         bolt->nextthink = level.time;
02001         bolt->touch = touch_NULL;
02002 
02003         // How 'bout we give this thing a size...
02004         VectorSet( bolt->r.mins, -3.0f, -3.0f, -3.0f );
02005         VectorSet( bolt->r.maxs, 3.0f, 3.0f, 3.0f );
02006         bolt->clipmask = MASK_SHOT;
02007 
02008         W_TraceSetStart( ent, start, bolt->r.mins, bolt->r.maxs );//make sure our start point isn't on the other side of a wall
02009 
02010         if ( ent->client )
02011         {
02012                 chargeAmount = level.time - ent->client->ps.weaponChargeTime;
02013         }
02014 
02015         // get charge amount
02016         chargeAmount = chargeAmount / (float)TD_VELOCITY;
02017 
02018         if ( chargeAmount > 1.0f )
02019         {
02020                 chargeAmount = 1.0f;
02021         }
02022         else if ( chargeAmount < TD_MIN_CHARGE )
02023         {
02024                 chargeAmount = TD_MIN_CHARGE;
02025         }
02026 
02027         // normal ones bounce, alt ones explode on impact
02028         bolt->genericValue5 = level.time + TD_TIME; // How long 'til she blows
02029         bolt->s.pos.trType = TR_GRAVITY;
02030         bolt->parent = ent;
02031         bolt->r.ownerNum = ent->s.number;
02032         VectorScale( dir, TD_VELOCITY * chargeAmount, bolt->s.pos.trDelta );
02033 
02034         if ( ent->health >= 0 )
02035         {
02036                 bolt->s.pos.trDelta[2] += 120;
02037         }
02038 
02039         if ( !altFire )
02040         {
02041                 bolt->flags |= FL_BOUNCE_HALF;
02042         }
02043 
02044         bolt->s.loopSound = G_SoundIndex( "sound/weapons/thermal/thermloop.wav" );
02045         bolt->s.loopIsSoundset = qfalse;
02046 
02047         bolt->damage = TD_DAMAGE;
02048         bolt->dflags = 0;
02049         bolt->splashDamage = TD_SPLASH_DAM;
02050         bolt->splashRadius = TD_SPLASH_RAD;
02051 
02052         bolt->s.eType = ET_MISSILE;
02053         bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
02054         bolt->s.weapon = WP_THERMAL;
02055 
02056         bolt->methodOfDeath = MOD_THERMAL;
02057         bolt->splashMethodOfDeath = MOD_THERMAL_SPLASH;
02058 
02059         bolt->s.pos.trTime = level.time;                // move a bit on the very first frame
02060         VectorCopy( start, bolt->s.pos.trBase );
02061         
02062         SnapVector( bolt->s.pos.trDelta );                      // save net bandwidth
02063         VectorCopy (start, bolt->r.currentOrigin);
02064 
02065         VectorCopy( start, bolt->pos2 );
02066 
02067         bolt->bounceCount = -5;
02068 
02069         return bolt;
02070 }

void WP_FireTurboLaserMissile gentity_t ent,
vec3_t  start,
vec3_t  dir
 

Definition at line 384 of file g_weapon.c.

References gentity_s::bounceCount, gentity_s::classname, gentity_s::clipmask, CreateMissile(), gentity_s::damage, DAMAGE_DEATH_KNOCKBACK, gentity_s::dflags, entityState_s::emplacedOwner, G_FreeEntity(), gentity_s::genericValue14, gentity_s::genericValue15, gentity_t, level, MASK_SHOT, gentity_s::mass, gentity_s::methodOfDeath, MOD_TURBLAST, gentity_s::nextthink, entityState_s::number, entityState_s::otherEntityNum2, entityState_s::owner, qfalse, gentity_s::s, gentity_s::splashDamage, gentity_s::splashMethodOfDeath, gentity_s::splashRadius, gentity_s::think, level_locals_t::time, vec3_t, entityState_s::weapon, and WP_TURRET.

00386 {
00387         int velocity    = ent->mass; //FIXME: externalize
00388         gentity_t *missile;
00389 
00390         missile = CreateMissile( start, dir, velocity, 10000, ent, qfalse );
00391         
00392         //use a custom shot effect
00393         missile->s.otherEntityNum2 = ent->genericValue14;
00394         //use a custom impact effect
00395         missile->s.emplacedOwner = ent->genericValue15;
00396 
00397         missile->classname = "turbo_proj";
00398         missile->s.weapon = WP_TURRET;
00399 
00400         missile->damage = ent->damage;          //FIXME: externalize
00401         missile->splashDamage = ent->splashDamage;      //FIXME: externalize
00402         missile->splashRadius = ent->splashRadius;      //FIXME: externalize
00403         missile->dflags = DAMAGE_DEATH_KNOCKBACK;
00404         missile->methodOfDeath = MOD_TURBLAST; //count as a heavy weap
00405         missile->splashMethodOfDeath = MOD_TURBLAST;// ?SPLASH;
00406         missile->clipmask = MASK_SHOT;
00407 
00408         // we don't want it to bounce forever
00409         missile->bounceCount = 8;
00410 
00411         //set veh as cgame side owner for purpose of fx overrides
00412         missile->s.owner = ent->s.number;
00413 
00414         //don't let them last forever
00415         missile->think = G_FreeEntity;
00416         missile->nextthink = level.time + 5000;//at 20000 speed, that should be more than enough
00417 }

void WP_FireTurretMissile gentity_t ent,
vec3_t  start,
vec3_t  dir,
qboolean  altFire,
int  damage,
int  velocity,
int  mod,
gentity_t ignore
 

Definition at line 302 of file g_weapon.c.

References gentity_s::bounceCount, gentity_s::classname, gentity_s::clipmask, CONTENTS_LIGHTSABER, CreateMissile(), gentity_s::damage, DAMAGE_DEATH_KNOCKBACK, gentity_s::dflags, gentity_t, MASK_SHOT, gentity_s::methodOfDeath, entityState_s::number, gentity_s::passThroughNum, gentity_s::s, vec3_t, entityState_s::weapon, and WP_TURRET.

Referenced by pas_fire().

00304 {
00305         gentity_t *missile;
00306 
00307         missile = CreateMissile( start, dir, velocity, 10000, ent, altFire );
00308 
00309         missile->classname = "generic_proj";
00310         missile->s.weapon = WP_TURRET;
00311 
00312         missile->damage = damage;
00313         missile->dflags = DAMAGE_DEATH_KNOCKBACK;
00314         missile->methodOfDeath = mod;
00315         missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER;
00316 
00317         if (ignore)
00318         {
00319                 missile->passThroughNum = ignore->s.number+1;
00320         }
00321 
00322         // we don't want it to bounce forever
00323         missile->bounceCount = 8;
00324 }

gentity_t* WP_FireVehicleWeapon gentity_t ent,
vec3_t  start,
vec3_t  dir,
vehWeaponInfo_t vehWeapon,
qboolean  alt_fire,
qboolean  isTurretWeap
 

Definition at line 3623 of file g_weapon.c.

References gentity_s::angle, vehWeaponInfo_t::bExplodeOnExpire, vehWeaponInfo_t::bHasGravity, vehWeaponInfo_t::bIonWeapon, vehWeaponInfo_t::bIsProjectile, gentity_s::bounceCount, vehWeaponInfo_t::bSaberBlockable, CLASS_VEHICLE, gentity_s::classname, gentity_s::client, gentity_s::clipmask, entityShared_t::contents, CONTENTS_LIGHTSABER, CreateMissile(), gentity_s::damage, DAMAGE_DEATH_KNOCKBACK, gentity_s::dflags, gentity_s::die, EF_ALT_FIRING, EF_JETPACK_ACTIVE, EF_RADAROBJECT, entityState_s::eFlags, gentity_s::enemy, ENTITYNUM_NONE, vehWeaponInfo_t::fHeight, vehWeaponInfo_t::fHoming, vehWeaponInfo_t::fHomingFOV, vehWeaponInfo_t::fSpeed, vehWeaponInfo_t::fSplashRadius, vehWeaponInfo_t::fWidth, g_entities, G_ExplodeMissile(), G_FreeEntity(), G_SetOrigin(), g_vehWeaponInfo, entityState_s::genericenemyindex, gentity_s::genericValue1, gentity_s::genericValue2, gentity_t, gentity_s::health, vehWeaponInfo_t::iDamage, vehWeaponInfo_t::iHealth, vehWeaponInfo_t::iLifeTime, vehWeaponInfo_t::iLockOnTime, vehWeaponInfo_t::iSplashDamage, level, Vehicle_s::m_pPilot, gentity_s::m_pVehicle, MASK_SHOT, gentity_s::mass, MAX_GENTITIES, entityShared_t::maxs, gentity_s::methodOfDeath, entityShared_t::mins, MOD_VEHICLE, gentity_s::movedir, gentity_s::nextthink, entityState_s::NPC_class, NULL, entityState_s::number, OnSameTeam(), entityState_s::otherEntityNum, entityState_s::otherEntityNum2, entityState_s::owner, entityShared_t::ownerNum, entityState_s::pos, gclient_s::ps, qfalse, qtrue, gentity_s::r, gentity_s::radius, gentity_s::random, RocketDie(), playerState_s::rocketLastValidTime, playerState_s::rocketLockIndex, playerState_s::rocketLockTime, rocketThink(), bgEntity_s::s, gentity_s::s, gentity_s::spawnflags, gentity_s::speed, gentity_s::splashDamage, gentity_s::splashMethodOfDeath, gentity_s::splashRadius, gentity_s::takedamage, gentity_s::think, level_locals_t::time, gentity_s::touch, TR_GRAVITY, trajectory_t::trType, vec3_t, VectorCopy, VectorScale, VectorSet, VEH_HOMING_MISSILE_THINK_TIME, entityState_s::weapon, WP_BLASTER, WP_DEMP2, WP_ROCKET_LAUNCHER, WP_THERMAL, WP_TouchVehMissile(), WP_TURRET, and WP_VehWeapSetSolidToOwner().

Referenced by FireVehicleWeapon(), and VEH_TurretCheckFire().

03624 {
03625         gentity_t       *missile = NULL;
03626 
03627         //FIXME: add some randomness...?  Inherent inaccuracy stat of weapon?  Pilot skill?
03628         if ( !vehWeapon )
03629         {//invalid vehicle weapon
03630                 return NULL;
03631         }
03632         else if ( vehWeapon->bIsProjectile )
03633         {//projectile entity
03634                 vec3_t          mins, maxs;
03635 
03636                 VectorSet( maxs, vehWeapon->fWidth/2.0f,vehWeapon->fWidth/2.0f,vehWeapon->fHeight/2.0f );
03637                 VectorScale( maxs, -1, mins );
03638 
03639                 //make sure our start point isn't on the other side of a wall
03640                 WP_TraceSetStart( ent, start, mins, maxs );
03641                 
03642                 //FIXME: CUSTOM MODEL?
03643                 //QUERY: alt_fire true or not?  Does it matter?
03644                 missile = CreateMissile( start, dir, vehWeapon->fSpeed, 10000, ent, qfalse );
03645 
03646                 missile->classname = "vehicle_proj";
03647                 
03648                 missile->s.genericenemyindex = ent->s.number+MAX_GENTITIES;
03649                 missile->damage = vehWeapon->iDamage;
03650                 missile->splashDamage = vehWeapon->iSplashDamage;
03651                 missile->splashRadius = vehWeapon->fSplashRadius;
03652 
03653                 //FIXME: externalize some of these properties?
03654                 missile->dflags = DAMAGE_DEATH_KNOCKBACK;
03655                 missile->clipmask = MASK_SHOT;
03656                 //Maybe by checking flags...?
03657                 if ( vehWeapon->bSaberBlockable )
03658                 {
03659                         missile->clipmask |= CONTENTS_LIGHTSABER;
03660                 }
03661                 /*
03662                 if ( (vehWeapon->iFlags&VWF_KNOCKBACK) )
03663                 {
03664                         missile->dflags &= ~DAMAGE_DEATH_KNOCKBACK;
03665                 }
03666                 if ( (vehWeapon->iFlags&VWF_RADAR) )
03667                 {
03668                         missile->s.eFlags |= EF_RADAROBJECT;
03669                 }
03670                 */
03671                 // Make it easier to hit things
03672                 VectorCopy( mins, missile->r.mins );
03673                 VectorCopy( maxs, missile->r.maxs );
03674                 //some slightly different stuff for things with bboxes
03675                 if ( vehWeapon->fWidth || vehWeapon->fHeight )
03676                 {//we assume it's a rocket-like thing
03677                         missile->s.weapon = WP_ROCKET_LAUNCHER;//does this really matter?
03678                         missile->methodOfDeath = MOD_VEHICLE;//MOD_ROCKET;
03679                         missile->splashMethodOfDeath = MOD_VEHICLE;//MOD_ROCKET;// ?SPLASH;
03680 
03681                         // we don't want it to ever bounce
03682                         missile->bounceCount = 0;
03683 
03684                         missile->mass = 10;
03685                 }
03686                 else
03687                 {//a blaster-laser-like thing
03688                         missile->s.weapon = WP_BLASTER;//does this really matter?
03689                         missile->methodOfDeath = MOD_VEHICLE; //count as a heavy weap
03690                         missile->splashMethodOfDeath = MOD_VEHICLE;// ?SPLASH;
03691                         // we don't want it to bounce forever
03692                         missile->bounceCount = 8;
03693                 }
03694                 
03695                 if ( vehWeapon->bHasGravity )
03696                 {//TESTME: is this all we need to do?
03697                         missile->s.weapon = WP_THERMAL;//does this really matter?
03698                         missile->s.pos.trType = TR_GRAVITY;
03699                 }
03700                 
03701                 if ( vehWeapon->bIonWeapon )
03702                 {//so it disables ship shields and sends them out of control
03703                         missile->s.weapon = WP_DEMP2;
03704                 }
03705 
03706                 if ( vehWeapon->iHealth )
03707                 {//the missile can take damage
03708                         missile->health = vehWeapon->iHealth;
03709                         missile->takedamage = qtrue;
03710                         missile->r.contents = MASK_SHOT;
03711                         missile->die = RocketDie;
03712                 }
03713 
03714                 //pilot should own this projectile on server if we have a pilot
03715                 if (ent->m_pVehicle && ent->m_pVehicle->m_pPilot)
03716                 {//owned by vehicle pilot
03717                         missile->r.ownerNum = ent->m_pVehicle->m_pPilot->s.number;
03718                 }
03719                 else
03720                 {//owned by vehicle?
03721                         missile->r.ownerNum = ent->s.number;
03722                 }
03723 
03724                 //set veh as cgame side owner for purpose of fx overrides
03725                 missile->s.owner = ent->s.number;
03726                 if ( alt_fire )
03727                 {//use the second weapon's iShotFX
03728                         missile->s.eFlags |= EF_ALT_FIRING;
03729                 }
03730                 if ( isTurretWeap )
03731                 {//look for the turret weapon info on cgame side, not vehicle weapon info
03732                         missile->s.weapon = WP_TURRET;
03733                 }
03734                 if ( vehWeapon->iLifeTime )
03735                 {//expire after a time
03736                         if ( vehWeapon->bExplodeOnExpire )
03737                         {//blow up when your lifetime is up
03738                                 missile->think = G_ExplodeMissile;//FIXME: custom func?
03739                         }
03740                         else
03741                         {//just remove yourself
03742                                 missile->think = G_FreeEntity;//FIXME: custom func?
03743                         }
03744                         missile->nextthink = level.time + vehWeapon->iLifeTime;
03745                 }
03746                 missile->s.otherEntityNum2 = (vehWeapon-&g_vehWeaponInfo[0]);
03747                 missile->s.eFlags |= EF_JETPACK_ACTIVE;
03748                 //homing
03749                 if ( vehWeapon->fHoming )
03750                 {//homing missile
03751                         if ( ent->client && ent->client->ps.rocketLockIndex != ENTITYNUM_NONE )
03752                         {
03753                                 int dif = 0;
03754                                 float rTime;
03755                                 rTime = ent->client->ps.rocketLockTime;
03756 
03757                                 if (rTime == -1)
03758                                 {
03759                                         rTime = ent->client->ps.rocketLastValidTime;
03760                                 }
03761 
03762                                 if ( !vehWeapon->iLockOnTime )
03763                                 {//no minimum lock-on time
03764                                         dif = 10;//guaranteed lock-on
03765                                 }
03766                                 else
03767                                 {
03768                                         float lockTimeInterval = vehWeapon->iLockOnTime/16.0f;
03769                                         dif = ( level.time - rTime ) / lockTimeInterval;
03770                                 }
03771 
03772                                 if (dif < 0)
03773                                 {
03774                                         dif = 0;
03775                                 }
03776 
03777                                 //It's 10 even though it locks client-side at 8, because we want them to have a sturdy lock first, and because there's a slight difference in time between server and client
03778                                 if ( dif >= 10 && rTime != -1 )
03779                                 {
03780                                         missile->enemy = &g_entities[ent->client->ps.rocketLockIndex];
03781 
03782                                         if (missile->enemy && missile->enemy->client && missile->enemy->health > 0 && !OnSameTeam(ent, missile->enemy))
03783                                         { //if enemy became invalid, died, or is on the same team, then don't seek it
03784                                                 missile->spawnflags |= 1;//just to let it know it should be faster...
03785                                                 missile->speed = vehWeapon->fSpeed;
03786                                                 missile->angle = vehWeapon->fHoming;
03787                                                 missile->radius = vehWeapon->fHomingFOV;
03788                                                 //crap, if we have a lifetime, need to store that somewhere else on ent and have rocketThink func check it every frame...
03789                                                 if ( vehWeapon->iLifeTime )
03790                                                 {//expire after a time
03791                                                         missile->genericValue1 = level.time + vehWeapon->iLifeTime;
03792                                                         missile->genericValue2 = (int)(vehWeapon->bExplodeOnExpire);
03793                                                 }
03794                                                 //now go ahead and use the rocketThink func
03795                                                 missile->think = rocketThink;//FIXME: custom func?
03796                                                 missile->nextthink = level.time + VEH_HOMING_MISSILE_THINK_TIME;
03797                                                 missile->s.eFlags |= EF_RADAROBJECT;//FIXME: externalize
03798                                                 if ( missile->enemy->s.NPC_class == CLASS_VEHICLE )
03799                                                 {//let vehicle know we've locked on to them
03800                                                         missile->s.otherEntityNum = missile->enemy->s.number;
03801                                                 }
03802                                         }
03803                                 }
03804 
03805                                 VectorCopy( dir, missile->movedir );
03806                                 missile->random = 1.0f;//FIXME: externalize?
03807                         }
03808                 }
03809                 if ( !vehWeapon->fSpeed )
03810                 {//a mine or something?
03811                         //only do damage when someone touches us
03812                         missile->s.weapon = WP_THERMAL;//does this really matter?
03813                         G_SetOrigin( missile, start );
03814                         missile->touch = WP_TouchVehMissile;
03815                         missile->s.eFlags |= EF_RADAROBJECT;//FIXME: externalize
03816                         //crap, if we have a lifetime, need to store that somewhere else on ent and have rocketThink func check it every frame...
03817                         if ( vehWeapon->iLifeTime )
03818                         {//expire after a time
03819                                 missile->genericValue1 = vehWeapon->iLifeTime;
03820                                 missile->genericValue2 = (int)(vehWeapon->bExplodeOnExpire);
03821                         }
03822                         //now go ahead and use the setsolidtoowner func
03823                         missile->think = WP_VehWeapSetSolidToOwner;
03824                         missile->nextthink = level.time + 3000;
03825                 }
03826         }
03827         else
03828         {//traceline
03829                 //FIXME: implement
03830         }
03831 
03832         return missile;
03833 }

void WP_flechette_alt_blow gentity_t ent  ) 
 

Definition at line 1547 of file g_weapon.c.

References gentity_t, laserTrapExplode(), entityState_s::pos, gentity_s::s, and trajectory_t::trDelta.

01549 {
01550         ent->s.pos.trDelta[0] = 1;
01551         ent->s.pos.trDelta[1] = 0;
01552         ent->s.pos.trDelta[2] = 0;
01553 
01554         laserTrapExplode(ent);
01555 }

void WP_GetVehicleCamPos gentity_t ent,
gentity_t pilot,
vec3_t  camPos
 

Definition at line 3946 of file g_weapon.c.

References vehicleInfo_t::cameraHorzOffset, vehicleInfo_t::cameraPitchDependantVertOffset, vehicleInfo_t::cameraPitchOffset, vehicleInfo_t::cameraRange, vehicleInfo_t::cameraVertOffset, gentity_s::client, fabs(), G_EstimateCamPos(), gentity_t, playerState_s::hackingTime, gentity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, MAX_STRAFE_TIME, entityState_s::number, playerState_s::origin, PITCH, gclient_s::ps, gentity_s::s, vec3_t, playerState_s::viewangles, and playerState_s::viewheight.

Referenced by BG_VehTraceFromCamPos().

03947 {
03948         float thirdPersonHorzOffset = ent->m_pVehicle->m_pVehicleInfo->cameraHorzOffset;
03949         float thirdPersonRange = ent->m_pVehicle->m_pVehicleInfo->cameraRange;
03950         float pitchOffset = ent->m_pVehicle->m_pVehicleInfo->cameraPitchOffset;
03951         float vertOffset = ent->m_pVehicle->m_pVehicleInfo->cameraVertOffset;
03952 
03953         if ( ent->client->ps.hackingTime )
03954         {
03955                 thirdPersonHorzOffset += (((float)ent->client->ps.hackingTime)/MAX_STRAFE_TIME) * -80.0f;
03956                 thirdPersonRange += fabs(((float)ent->client->ps.hackingTime)/MAX_STRAFE_TIME) * 100.0f;
03957         }
03958 
03959         if ( ent->m_pVehicle->m_pVehicleInfo->cameraPitchDependantVertOffset )
03960         {
03961                 if ( pilot->client->ps.viewangles[PITCH] > 0 )
03962                 {
03963                         vertOffset = 130+pilot->client->ps.viewangles[PITCH]*-10;
03964                         if ( vertOffset < -170 )
03965                         {
03966                                 vertOffset = -170;
03967                         }
03968                 }
03969                 else if ( pilot->client->ps.viewangles[PITCH] < 0 )
03970                 {
03971                         vertOffset = 130+pilot->client->ps.viewangles[PITCH]*-5;
03972                         if ( vertOffset > 130 )
03973                         {
03974                                 vertOffset = 130;
03975                         }
03976                 }
03977                 else
03978                 {
03979                         vertOffset = 30;
03980                 }
03981                 if ( pilot->client->ps.viewangles[PITCH] > 0 )
03982                 {
03983                         pitchOffset = pilot->client->ps.viewangles[PITCH]*-0.75;
03984                 }
03985                 else if ( pilot->client->ps.viewangles[PITCH] < 0 )
03986                 {
03987                         pitchOffset = pilot->client->ps.viewangles[PITCH]*-0.75;
03988                 }
03989                 else
03990                 {
03991                         pitchOffset = 0;
03992                 }
03993         }
03994 
03995         //Control Scheme 3 Method:
03996         G_EstimateCamPos( ent->client->ps.viewangles, pilot->client->ps.origin, pilot->client->ps.viewheight, thirdPersonRange, 
03997                 thirdPersonHorzOffset, vertOffset, pitchOffset, 
03998                 pilot->s.number, camPos );
03999         /*
04000         //Control Scheme 2 Method:
04001         G_EstimateCamPos( ent->m_pVehicle->m_vOrientation, ent->r.currentOrigin, pilot->client->ps.viewheight, thirdPersonRange, 
04002                 thirdPersonHorzOffset, vertOffset, pitchOffset, 
04003                 pilot->s.number, camPos );
04004         */
04005 }

qboolean WP_LobFire gentity_t self,
vec3_t  start,
vec3_t  target,
vec3_t  mins,
vec3_t  maxs,
int  clipmask,
vec3_t  velocity,
qboolean  tracePath,
int  ignoreEntNum,
int  enemyNum,
float  minSpeed,
float  maxSpeed,
float  idealSpeed,
qboolean  mustHit
 

Definition at line 2080 of file g_weapon.c.

References trace_t::allsolid, BG_EvaluateTrajectory(), trace_t::endpos, trace_t::entityNum, ENTITYNUM_WORLD, floor(), trace_t::fraction, g_entities, g_gravity, gentity_t, level, cplane_s::normal, OnSameTeam(), trace_t::plane, Q3_INFINITE, qboolean, qfalse, qtrue, trace_t::startsolid, gentity_s::takedamage, level_locals_t::time, TR_GRAVITY, trap_Trace(), trajectory_t::trBase, trajectory_t::trDelta, trajectory_t::trTime, trajectory_t::trType, vmCvar_t::value, vec3_t, VectorCopy, VectorNormalize(), VectorScale, and VectorSubtract.

Referenced by NPC_BSGM_Attack().

02084 { //for the galak mech NPC
02085         float   targetDist, shotSpeed, speedInc = 100, travelTime, impactDist, bestImpactDist = Q3_INFINITE;//fireSpeed, 
02086         vec3_t  targetDir, shotVel, failCase; 
02087         trace_t trace;
02088         trajectory_t    tr;
02089         qboolean        blocked;
02090         int             elapsedTime, skipNum, timeStep = 500, hitCount = 0, maxHits = 7;
02091         vec3_t  lastPos, testPos;
02092         gentity_t       *traceEnt;
02093         
02094         if ( !idealSpeed )
02095         {
02096                 idealSpeed = 300;
02097         }
02098         else if ( idealSpeed < speedInc )
02099         {
02100                 idealSpeed = speedInc;
02101         }
02102         shotSpeed = idealSpeed;
02103         skipNum = (idealSpeed-speedInc)/speedInc;
02104         if ( !minSpeed )
02105         {
02106                 minSpeed = 100;
02107         }
02108         if ( !maxSpeed )
02109         {
02110                 maxSpeed = 900;
02111         }
02112         while ( hitCount < maxHits )
02113         {
02114                 VectorSubtract( target, start, targetDir );
02115                 targetDist = VectorNormalize( targetDir );
02116 
02117                 VectorScale( targetDir, shotSpeed, shotVel );
02118                 travelTime = targetDist/shotSpeed;
02119                 shotVel[2] += travelTime * 0.5 * g_gravity.value;
02120 
02121                 if ( !hitCount )                
02122                 {//save the first (ideal) one as the failCase (fallback value)
02123                         if ( !mustHit )
02124                         {//default is fine as a return value
02125                                 VectorCopy( shotVel, failCase );
02126                         }
02127                 }
02128 
02129                 if ( tracePath )
02130                 {//do a rough trace of the path
02131                         blocked = qfalse;
02132 
02133                         VectorCopy( start, tr.trBase );
02134                         VectorCopy( shotVel, tr.trDelta );
02135                         tr.trType = TR_GRAVITY;
02136                         tr.trTime = level.time;
02137                         travelTime *= 1000.0f;
02138                         VectorCopy( start, lastPos );
02139                         
02140                         //This may be kind of wasteful, especially on long throws... use larger steps?  Divide the travelTime into a certain hard number of slices?  Trace just to apex and down?
02141                         for ( elapsedTime = timeStep; elapsedTime < floor(travelTime)+timeStep; elapsedTime += timeStep )
02142                         {
02143                                 if ( (float)elapsedTime > travelTime )
02144                                 {//cap it
02145                                         elapsedTime = floor( travelTime );
02146                                 }
02147                                 BG_EvaluateTrajectory( &tr, level.time + elapsedTime, testPos );
02148                                 trap_Trace( &trace, lastPos, mins, maxs, testPos, ignoreEntNum, clipmask );
02149 
02150                                 if ( trace.allsolid || trace.startsolid )
02151                                 {
02152                                         blocked = qtrue;
02153                                         break;
02154                                 }
02155                                 if ( trace.fraction < 1.0f )
02156                                 {//hit something
02157                                         if ( trace.entityNum == enemyNum )
02158                                         {//hit the enemy, that's perfect!
02159                                                 break;
02160                                         }
02161                                         else if ( trace.plane.normal[2] > 0.7 && DistanceSquared( trace.endpos, target ) < 4096 )//hit within 64 of desired location, should be okay
02162                                         {//close enough!
02163                                                 break;
02164                                         }
02165                                         else
02166                                         {//FIXME: maybe find the extents of this brush and go above or below it on next try somehow?
02167                                                 impactDist = DistanceSquared( trace.endpos, target );
02168                                                 if ( impactDist < bestImpactDist )
02169                                                 {
02170                                                         bestImpactDist = impactDist;
02171                                                         VectorCopy( shotVel, failCase );
02172                                                 }
02173                                                 blocked = qtrue;
02174                                                 //see if we should store this as the failCase
02175                                                 if ( trace.entityNum < ENTITYNUM_WORLD )
02176                                                 {//hit an ent
02177                                                         traceEnt = &g_entities[trace.entityNum];
02178                                                         if ( traceEnt && traceEnt->takedamage && !OnSameTeam( self, traceEnt ) )
02179                                                         {//hit something breakable, so that's okay
02180                                                                 //we haven't found a clear shot yet so use this as the failcase
02181                                                                 VectorCopy( shotVel, failCase );
02182                                                         }
02183                                                 }
02184                                                 break;
02185                                         }
02186                                 }
02187                                 if ( elapsedTime == floor( travelTime ) )
02188                                 {//reached end, all clear
02189                                         break;
02190                                 }
02191                                 else
02192                                 {
02193                                         //all clear, try next slice
02194                                         VectorCopy( testPos, lastPos );
02195                                 }
02196                         }
02197                         if ( blocked )
02198                         {//hit something, adjust speed (which will change arc)
02199                                 hitCount++;
02200                                 shotSpeed = idealSpeed + ((hitCount-skipNum) * speedInc);//from min to max (skipping ideal)
02201                                 if ( hitCount >= skipNum )
02202                                 {//skip ideal since that was the first value we tested
02203                                         shotSpeed += speedInc;
02204                                 }
02205                         }
02206                         else
02207                         {//made it!
02208                                 break;
02209                         }
02210                 }
02211                 else
02212                 {//no need to check the path, go with first calc
02213                         break;
02214                 }
02215         }
02216 
02217         if ( hitCount >= maxHits )
02218         {//NOTE: worst case scenario, use the one that impacted closest to the target (or just use the first try...?)
02219                 VectorCopy( failCase, velocity );
02220                 return qfalse;
02221         }
02222         VectorCopy( shotVel, velocity );
02223         return qtrue;
02224 }

void WP_PlaceLaserTrap gentity_t ent,
qboolean  alt_fire
 

Definition at line 2531 of file g_weapon.c.

References gentity_s::count, CreateLaserTrap(), ENTITYNUM_NONE, FOFS, g_entities, G_Find(), G_FreeEntity(), G_Spawn(), gentity_t, level, MAX_GENTITIES, NULL, entityState_s::number, gentity_s::parent, entityState_s::pos, gentity_s::s, gentity_s::setTime, level_locals_t::time, TR_GRAVITY, trap_LinkEntity(), trajectory_t::trDelta, trajectory_t::trType, vec3_t, VectorCopy, and VectorScale.

Referenced by FireWeapon().

02532 {
02533         gentity_t       *laserTrap;
02534         gentity_t       *found = NULL;
02535         vec3_t          dir, start;
02536         int                     trapcount = 0;
02537         int                     foundLaserTraps[MAX_GENTITIES];
02538         int                     trapcount_org;
02539         int                     lowestTimeStamp;
02540         int                     removeMe;
02541         int                     i;
02542 
02543         foundLaserTraps[0] = ENTITYNUM_NONE;
02544 
02545         VectorCopy( forward, dir );
02546         VectorCopy( muzzle, start );
02547 
02548         laserTrap = G_Spawn();
02549         
02550         //limit to 10 placed at any one time
02551         //see how many there are now
02552         while ( (found = G_Find( found, FOFS(classname), "laserTrap" )) != NULL )
02553         {
02554                 if ( found->parent != ent )
02555                 {
02556                         continue;
02557                 }
02558                 foundLaserTraps[trapcount++] = found->s.number;
02559         }
02560         //now remove first ones we find until there are only 9 left
02561         found = NULL;
02562         trapcount_org = trapcount;
02563         lowestTimeStamp = level.time;
02564         while ( trapcount > 9 )
02565         {
02566                 removeMe = -1;
02567                 for ( i = 0; i < trapcount_org; i++ )
02568                 {
02569                         if ( foundLaserTraps[i] == ENTITYNUM_NONE )
02570                         {
02571                                 continue;
02572                         }
02573                         found = &g_entities[foundLaserTraps[i]];
02574                         if ( laserTrap && found->setTime < lowestTimeStamp )
02575                         {
02576                                 removeMe = i;
02577                                 lowestTimeStamp = found->setTime;
02578                         }
02579                 }
02580                 if ( removeMe != -1 )
02581                 {
02582                         //remove it... or blow it?
02583                         if ( &g_entities[foundLaserTraps[removeMe]] == NULL )
02584                         {
02585                                 break;
02586                         }
02587                         else
02588                         {
02589                                 G_FreeEntity( &g_entities[foundLaserTraps[removeMe]] );
02590                         }
02591                         foundLaserTraps[removeMe] = ENTITYNUM_NONE;
02592                         trapcount--;
02593                 }
02594                 else
02595                 {
02596                         break;
02597                 }
02598         }
02599 
02600         //now make the new one
02601         CreateLaserTrap( laserTrap, start, ent );
02602 
02603         //set player-created-specific fields
02604         laserTrap->setTime = level.time;//remember when we placed it
02605 
02606         if (!alt_fire)
02607         {//tripwire
02608                 laserTrap->count = 1;
02609         }
02610 
02611         //move it
02612         laserTrap->s.pos.trType = TR_GRAVITY;
02613 
02614         if (alt_fire)
02615         {
02616                 VectorScale( dir, 512, laserTrap->s.pos.trDelta );
02617         }
02618         else
02619         {
02620                 VectorScale( dir, 256, laserTrap->s.pos.trDelta );
02621         }
02622 
02623         trap_LinkEntity(laserTrap);
02624 }

float WP_SpeedOfMissileForWeapon int  wp,
qboolean  alt_fire
 

Definition at line 174 of file g_weapon.c.

00175 {
00176         return 500;
00177 }

void WP_TouchVehMissile gentity_t ent,
gentity_t other,
trace_t trace
 

Definition at line 3564 of file g_weapon.c.

References G_MissileImpact(), gentity_t, memcpy(), entityState_s::number, and gentity_s::s.

Referenced by WP_FireVehicleWeapon().

03565 {
03566         trace_t myTrace;
03567         memcpy( (void *)&myTrace, (void *)trace, sizeof(myTrace) );
03568         if ( other )
03569         {
03570                 myTrace.entityNum = other->s.number;
03571         }
03572         G_MissileImpact( ent, &myTrace );
03573 }

qboolean WP_VehCheckTraceFromCamPos gentity_t ent,
const vec3_t  shotStart,
vec3_t  shotDir
 

Definition at line 4023 of file g_weapon.c.

References AngleVectors(), BG_VehTraceFromCamPos(), bgEntity_t, gentity_s::client, CONTENTS_BODY, CONTENTS_SOLID, entityShared_t::currentOrigin, DEFAULT_MINS_2, trace_t::endpos, trace_t::fraction, g_cullDistance, g_entities, gentity_t, vehicleInfo_t::height, Vehicle_s::m_pPilot, gentity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, Vehicle_s::m_vOrientation, MAX_CLIENTS, MAX_XHAIR_DIST_ACCURACY, NULL, entityState_s::number, gclient_s::ps, qboolean, qfalse, qtrue, gentity_s::r, gentity_s::s, bgEntity_s::s, trap_Trace(), vehicleInfo_t::type, vec3_origin, vec3_t, VectorCopy, VectorMA, VectorNormalize(), VectorSet, VectorSubtract, VH_FIGHTER, VH_SPEEDER, VH_WALKER, playerState_s::viewangles, and WP_VehLeadCrosshairVeh().

Referenced by FireVehicleWeapon().

04024 {
04025         //FIXME: only if dynamicCrosshair and dynamicCrosshairPrecision is on!
04026         if ( !ent 
04027                 || !ent->m_pVehicle 
04028                 || !ent->m_pVehicle->m_pVehicleInfo 
04029                 || !ent->m_pVehicle->m_pPilot//not being driven
04030                 || !((gentity_t*)ent->m_pVehicle->m_pPilot)->client//not being driven by a client...?!!!
04031                 || (ent->m_pVehicle->m_pPilot->s.number >= MAX_CLIENTS) )//being driven, but not by a real client, no need to worry about crosshair
04032         {
04033                 return qfalse;
04034         }
04035         if ( (ent->m_pVehicle->m_pVehicleInfo->type == VH_FIGHTER && g_cullDistance > MAX_XHAIR_DIST_ACCURACY )
04036                 || ent->m_pVehicle->m_pVehicleInfo->type == VH_WALKER)
04037         {
04038                 //FIRST: simulate the normal crosshair trace from the center of the veh straight forward
04039                 trace_t trace;
04040                 vec3_t  dir, start, end;
04041                 if ( ent->m_pVehicle->m_pVehicleInfo->type == VH_WALKER )
04042                 {//for some reason, the walker always draws the crosshair out from from the first muzzle point
04043                         AngleVectors( ent->client->ps.viewangles, dir, NULL, NULL );
04044                         VectorCopy( ent->r.currentOrigin, start );
04045                         start[2] += ent->m_pVehicle->m_pVehicleInfo->height-DEFAULT_MINS_2-48;
04046                 }
04047                 else
04048                 {
04049                         vec3_t ang;
04050                         if (ent->m_pVehicle->m_pVehicleInfo->type == VH_SPEEDER)
04051                         {
04052                                 VectorSet(ang, 0.0f, ent->m_pVehicle->m_vOrientation[1], 0.0f);
04053                         }
04054                         else
04055                         {
04056                                 VectorCopy(ent->m_pVehicle->m_vOrientation, ang);
04057                         }
04058                         AngleVectors( ang, dir, NULL, NULL );
04059                         VectorCopy( ent->r.currentOrigin, start );
04060                 }
04061                 VectorMA( start, g_cullDistance, dir, end );
04062                 trap_Trace( &trace, start, vec3_origin, vec3_origin, end, 
04063                         ent->s.number, CONTENTS_SOLID|CONTENTS_BODY );
04064 
04065                 if ( ent->m_pVehicle->m_pVehicleInfo->type == VH_WALKER )
04066                 {//just use the result of that one trace since walkers don't do the extra trace
04067                         VectorSubtract( trace.endpos, shotStart, shotDir );
04068                         VectorNormalize( shotDir );
04069                         return qtrue;
04070                 }
04071                 else
04072                 {//NOW do the trace from the camPos and compare with above trace
04073                         trace_t extraTrace;
04074                         vec3_t  newEnd;
04075                         int camTraceEntNum = BG_VehTraceFromCamPos( &extraTrace, (bgEntity_t *)ent, ent->r.currentOrigin, shotStart, end, newEnd, shotDir, (trace.fraction*g_cullDistance) );
04076                         if ( camTraceEntNum )
04077                         {
04078                                 WP_VehLeadCrosshairVeh( &g_entities[camTraceEntNum-1], newEnd, dir, shotStart, shotDir );
04079                                 return qtrue;
04080                         }
04081                 }
04082         }
04083         return qfalse;
04084 }

void WP_VehLeadCrosshairVeh gentity_t camTraceEnt,
vec3_t  newEnd,
const vec3_t  dir,
const vec3_t  shotStart,
vec3_t  shotDir
 

Definition at line 4007 of file g_weapon.c.

References CLASS_VEHICLE, gentity_s::client, DotProduct, gentity_t, gclient_s::NPC_class, gclient_s::ps, vec3_t, VectorMA, VectorNormalize(), VectorSubtract, and playerState_s::velocity.

Referenced by FireVehicleWeapon(), and WP_VehCheckTraceFromCamPos().

04008 {
04009         if ( camTraceEnt 
04010                 && camTraceEnt->client
04011                 && camTraceEnt->client->NPC_class == CLASS_VEHICLE )
04012         {//if the crosshair is on a vehicle, lead it
04013                 float distAdjust = DotProduct( camTraceEnt->client->ps.velocity, dir );
04014                 VectorMA( newEnd, distAdjust, dir, newEnd );
04015         }
04016         VectorSubtract( newEnd, shotStart, shotDir );
04017         VectorNormalize( shotDir );
04018 }

void WP_VehWeapSetSolidToOwner gentity_t self  ) 
 

Definition at line 3605 of file g_weapon.c.

References G_ExplodeMissile(), G_FreeEntity(), gentity_s::genericValue1, gentity_s::genericValue2, gentity_t, level, gentity_s::nextthink, gentity_s::r, SVF_OWNERNOTSHARED, entityShared_t::svFlags, gentity_s::think, and level_locals_t::time.

Referenced by WP_FireVehicleWeapon().

03606 {
03607         self->r.svFlags |= SVF_OWNERNOTSHARED;
03608         if ( self->genericValue1 )
03609         {//expire after a time
03610                 if ( self->genericValue2 )
03611                 {//blow up when your lifetime is up
03612                         self->think = G_ExplodeMissile;//FIXME: custom func?
03613                 }
03614                 else
03615                 {//just remove yourself
03616                         self->think = G_FreeEntity;//FIXME: custom func?
03617                 }
03618                 self->nextthink = level.time + self->genericValue1;
03619         }
03620 }


Variable Documentation

float g_cullDistance
 

Definition at line 4021 of file g_weapon.c.

Referenced by SP_worldspawn(), and WP_VehCheckTraceFromCamPos().