#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.
|
|
Definition at line 130 of file g_weapon.c. |
|
|
Definition at line 131 of file g_weapon.c. |
|
|
Definition at line 129 of file g_weapon.c. |
|
|
Definition at line 146 of file g_weapon.c. |
|
|
Definition at line 145 of file g_weapon.c. |
|
|
Definition at line 154 of file g_weapon.c. |
|
|
Definition at line 155 of file g_weapon.c. |
|
|
Definition at line 152 of file g_weapon.c. |
|
|
Definition at line 153 of file g_weapon.c. |
|
|
Definition at line 144 of file g_weapon.c. |
|
|
Definition at line 135 of file g_weapon.c. |
|
|
Definition at line 137 of file g_weapon.c. |
|
|
Definition at line 139 of file g_weapon.c. |
|
|
Definition at line 138 of file g_weapon.c. |
|
|
Definition at line 140 of file g_weapon.c. |
|
|
Definition at line 141 of file g_weapon.c. |
|
|
Definition at line 142 of file g_weapon.c. |
|
|
Definition at line 136 of file g_weapon.c. |
|
|
Definition at line 148 of file g_weapon.c. |
|
|
Definition at line 150 of file g_weapon.c. |
|
|
Definition at line 149 of file g_weapon.c. |
|
|
Definition at line 27 of file g_weapon.c. Referenced by WP_FireBlasterMissile(), and WP_FireEmplacedMissile(). |
|
|
Definition at line 25 of file g_weapon.c. |
|
|
Definition at line 26 of file g_weapon.c. Referenced by WP_FireBlasterMissile(), and WP_FireEmplacedMissile(). |
|
|
Definition at line 48 of file g_weapon.c. |
|
|
Definition at line 50 of file g_weapon.c. |
|
|
Definition at line 42 of file g_weapon.c. |
|
|
Definition at line 46 of file g_weapon.c. Referenced by Mark1_FireRocket(), and Mark1Dead_FireRocket(). |
|
|
Definition at line 44 of file g_weapon.c. Referenced by Mark1_FireRocket(), and Mark1Dead_FireRocket(). |
|
|
Definition at line 45 of file g_weapon.c. Referenced by Mark1_FireRocket(), and Mark1Dead_FireRocket(). |
|
|
Definition at line 49 of file g_weapon.c. |
|
|
Definition at line 43 of file g_weapon.c. Referenced by Mark1_FireRocket(), and Mark1Dead_FireRocket(). |
|
|
Definition at line 21 of file g_weapon.c. |
|
|
Definition at line 20 of file g_weapon.c. |
|
|
Definition at line 19 of file g_weapon.c. |
|
|
Definition at line 18 of file g_weapon.c. |
|
|
Definition at line 110 of file g_weapon.c. |
|
|
Definition at line 111 of file g_weapon.c. |
|
|
Definition at line 113 of file g_weapon.c. |
|
|
Definition at line 112 of file g_weapon.c. |
|
|
Definition at line 103 of file g_weapon.c. |
|
|
Definition at line 104 of file g_weapon.c. |
|
|
Definition at line 106 of file g_weapon.c. |
|
|
Definition at line 105 of file g_weapon.c. |
|
|
Definition at line 107 of file g_weapon.c. |
|
|
Definition at line 108 of file g_weapon.c. |
|
|
Definition at line 102 of file g_weapon.c. |
|
|
Definition at line 71 of file g_weapon.c. |
|
|
Definition at line 73 of file g_weapon.c. |
|
|
Definition at line 74 of file g_weapon.c. |
|
|
Definition at line 72 of file g_weapon.c. |
|
|
Definition at line 67 of file g_weapon.c. |
|
|
Definition at line 69 of file g_weapon.c. |
|
|
Definition at line 68 of file g_weapon.c. |
|
|
Definition at line 35 of file g_weapon.c. Referenced by WP_DisruptorAltFire(). |
|
|
Definition at line 37 of file g_weapon.c. Referenced by WP_DisruptorAltFire(). |
|
|
Definition at line 38 of file g_weapon.c. Referenced by WP_DisruptorAltFire(). |
|
|
Definition at line 31 of file g_weapon.c. |
|
|
Definition at line 32 of file g_weapon.c. |
|
|
Definition at line 36 of file g_weapon.c. |
|
|
Definition at line 33 of file g_weapon.c. |
|
|
Definition at line 4633 of file g_weapon.c. Referenced by emplaced_gun_update(), and SP_emplaced_gun(). |
|
|
Definition at line 4796 of file g_weapon.c. Referenced by emplaced_gun_update(), and SP_emplaced_gun(). |
|
|
Definition at line 84 of file g_weapon.c. |
|
|
Definition at line 85 of file g_weapon.c. |
|
|
Definition at line 86 of file g_weapon.c. |
|
|
Definition at line 80 of file g_weapon.c. |
|
|
Definition at line 83 of file g_weapon.c. Referenced by prox_mine_think(). |
|
|
Definition at line 78 of file g_weapon.c. Referenced by FireWeapon(). |
|
|
Definition at line 82 of file g_weapon.c. |
|
|
Definition at line 79 of file g_weapon.c. |
|
|
Definition at line 81 of file g_weapon.c. |
|
|
Definition at line 2239 of file g_weapon.c. Referenced by laserTrapStick(). |
|
|
Definition at line 2238 of file g_weapon.c. Referenced by laserTrapStick(). |
|
|
Definition at line 2233 of file g_weapon.c. Referenced by CreateLaserTrap(). |
|
|
Definition at line 2240 of file g_weapon.c. Referenced by laserTrapThink(). |
|
|
Definition at line 2237 of file g_weapon.c. Referenced by CreateLaserTrap(), and laserTrapStick(). |
|
|
Definition at line 2235 of file g_weapon.c. Referenced by CreateLaserTrap(). |
|
|
Definition at line 2234 of file g_weapon.c. Referenced by CreateLaserTrap(). |
|
|
Definition at line 2236 of file g_weapon.c. |
|
|
Definition at line 4020 of file g_weapon.c. |
|
|
Definition at line 125 of file g_weapon.c. Referenced by WP_FireMelee(). |
|
|
Definition at line 123 of file g_weapon.c. Referenced by WP_FireMelee(). |
|
|
Definition at line 124 of file g_weapon.c. Referenced by WP_FireMelee(). |
|
|
Definition at line 59 of file g_weapon.c. |
|
|
Definition at line 58 of file g_weapon.c. Referenced by NPC_BSGM_Attack(). |
|
|
Definition at line 60 of file g_weapon.c. |
|
|
Definition at line 62 of file g_weapon.c. |
|
|
Definition at line 61 of file g_weapon.c. |
|
|
Definition at line 63 of file g_weapon.c. |
|
|
Definition at line 55 of file g_weapon.c. |
|
|
Definition at line 54 of file g_weapon.c. |
|
|
Definition at line 56 of file g_weapon.c. |
|
|
Definition at line 95 of file g_weapon.c. Referenced by rocketThink(). |
|
|
Definition at line 91 of file g_weapon.c. |
|
|
Definition at line 94 of file g_weapon.c. |
|
|
Definition at line 92 of file g_weapon.c. |
|
|
Definition at line 93 of file g_weapon.c. |
|
|
Definition at line 90 of file g_weapon.c. Referenced by rocketThink(). |
|
|
Definition at line 118 of file g_weapon.c. |
|
|
Definition at line 117 of file g_weapon.c. Referenced by WP_FireStunBaton(). |
|
|
Definition at line 119 of file g_weapon.c. Referenced by WP_FireStunBaton(). |
|
|
Definition at line 1924 of file g_weapon.c. |
|
|
Definition at line 1928 of file g_weapon.c. |
|
|
Definition at line 1926 of file g_weapon.c. |
|
|
Definition at line 1925 of file g_weapon.c. |
|
|
Definition at line 1929 of file g_weapon.c. |
|
|
Definition at line 1929 of file g_weapon.c. |
|
|
Definition at line 1927 of file g_weapon.c. |
|
|
Definition at line 1916 of file g_weapon.c. Referenced by WP_FireThermalDetonator(). |
|
|
Definition at line 1920 of file g_weapon.c. Referenced by WP_FireThermalDetonator(). |
|
|
Definition at line 1918 of file g_weapon.c. Referenced by WP_FireThermalDetonator(). |
|
|
Definition at line 1917 of file g_weapon.c. Referenced by WP_FireThermalDetonator(). |
|
|
Definition at line 1921 of file g_weapon.c. Referenced by WP_FireThermalDetonator(). |
|
|
Definition at line 1919 of file g_weapon.c. Referenced by WP_FireThermalDetonator(). |
|
|
Definition at line 3622 of file g_weapon.c. Referenced by WP_FireVehicleWeapon(). |
|
||||||||||||||||||||
|
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 }
|
|
||||||||||||||||||||||||||||||||||||
|
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 }
|
|
|
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 }
|
|
||||||||||||||||||||||||
|
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 }
|
|
||||||||||||||||||||||||||||
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
|
Definition at line 2869 of file g_weapon.c. References g_cheats, vmCvar_t::integer, qboolean, qfalse, and qtrue. Referenced by WP_DropDetPack().
|
|
||||||||||||||||
|
|
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 }
|
|
|
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 }
|
|
|
||||||||||||||||||||||||
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
||||||||||||||||
|
||||||||||||||||||||||||
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||||||||||||||
|
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 }
|
|
|
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 }
|
|
||||||||||||||||||||||||||||||||||||||||
|
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 }
|
|
|
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 }
|
|
||||||||||||
|
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 }
|
|
|
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
|
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 }
|
|
||||||||||||||||||||||||
|
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 }
|
|
|
||||||||||||||||
|
Referenced by G_MissileImpact(), and touchLaserTrap(). |
|
|
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 }
|
|
||||||||||||
|
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 }
|
|
|
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 }
|
|
|
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, |