#include "g_local.h"#include "w_saber.h"#include "q_shared.h"#include "../namespace_begin.h"#include "../namespace_end.h"Go to the source code of this file.
Defines | |
| #define | MISSILE_PRESTEP_TIME 50 |
Functions | |
| void | laserTrapStick (gentity_t *ent, vec3_t endpos, vec3_t normal) |
| void | Jedi_Decloak (gentity_t *self) |
| qboolean | FighterIsLanded (Vehicle_t *pVeh, playerState_t *parentPS) |
| float | RandFloat (float min, float max) |
| void | G_ReflectMissile (gentity_t *ent, gentity_t *missile, vec3_t forward) |
| void | G_DeflectMissile (gentity_t *ent, gentity_t *missile, vec3_t forward) |
| void | G_BounceMissile (gentity_t *ent, trace_t *trace) |
| void | G_ExplodeMissile (gentity_t *ent) |
| void | G_RunStuckMissile (gentity_t *ent) |
| void | G_BounceProjectile (vec3_t start, vec3_t impact, vec3_t dir, vec3_t endout) |
| gentity_t * | CreateMissile (vec3_t org, vec3_t dir, float vel, int life, gentity_t *owner, qboolean altFire) |
| void | G_MissileBounceEffect (gentity_t *ent, vec3_t org, vec3_t dir) |
| void | WP_SaberBlockNonRandom (gentity_t *self, vec3_t hitloc, qboolean missileBlock) |
| void | G_MissileImpact (gentity_t *ent, trace_t *trace) |
| void | G_RunMissile (gentity_t *ent) |
|
|
Definition at line 7 of file g_missile.c. |
|
||||||||||||||||||||||||||||
|
||||||||||||
|
Definition at line 297 of file FighterNPC.c. References FighterOverValidLandingSurface(), playerState_t, qboolean, qfalse, qtrue, playerState_s::speed, and Vehicle_t. Referenced by G_MissileImpact(), and PM_VehicleImpact().
00298 {
00299 if ( FighterOverValidLandingSurface( pVeh )
00300 && !parentPS->speed )//stopped
00301 {
00302 return qtrue;
00303 }
00304 return qfalse;
00305 }
|
|
||||||||||||
|
Definition at line 148 of file g_missile.c. References BG_EvaluateTrajectoryDelta(), gentity_s::bounceCount, CHAN_BODY, entityShared_t::currentOrigin, DotProduct, trace_t::endpos, FL_BOUNCE_HALF, FL_BOUNCE_SHRAPNEL, gentity_s::flags, trace_t::fraction, G2_MODEL_PART, G_SetOrigin(), G_Sound(), G_SoundIndex(), gentity_t, level, gentity_s::nextthink, cplane_s::normal, trace_t::plane, entityState_s::pos, level_locals_t::previousTime, Q_irand(), gentity_s::r, gentity_s::s, level_locals_t::time, TR_GRAVITY, trajectory_t::trBase, trajectory_t::trDelta, trajectory_t::trTime, trajectory_t::trType, va(), vec3_t, VectorAdd, VectorCopy, VectorMA, VectorScale, entityState_s::weapon, WP_SABER, and WP_THERMAL. Referenced by G_MissileImpact().
00148 {
00149 vec3_t velocity;
00150 float dot;
00151 int hitTime;
00152
00153 // reflect the velocity on the trace plane
00154 hitTime = level.previousTime + ( level.time - level.previousTime ) * trace->fraction;
00155 BG_EvaluateTrajectoryDelta( &ent->s.pos, hitTime, velocity );
00156 dot = DotProduct( velocity, trace->plane.normal );
00157 VectorMA( velocity, -2*dot, trace->plane.normal, ent->s.pos.trDelta );
00158
00159
00160 if ( ent->flags & FL_BOUNCE_SHRAPNEL )
00161 {
00162 VectorScale( ent->s.pos.trDelta, 0.25f, ent->s.pos.trDelta );
00163 ent->s.pos.trType = TR_GRAVITY;
00164
00165 // check for stop
00166 if ( trace->plane.normal[2] > 0.7 && ent->s.pos.trDelta[2] < 40 ) //this can happen even on very slightly sloped walls, so changed it from > 0 to > 0.7
00167 {
00168 G_SetOrigin( ent, trace->endpos );
00169 ent->nextthink = level.time + 100;
00170 return;
00171 }
00172 }
00173 else if ( ent->flags & FL_BOUNCE_HALF )
00174 {
00175 VectorScale( ent->s.pos.trDelta, 0.65, ent->s.pos.trDelta );
00176 // check for stop
00177 if ( trace->plane.normal[2] > 0.2 && VectorLength( ent->s.pos.trDelta ) < 40 )
00178 {
00179 G_SetOrigin( ent, trace->endpos );
00180 return;
00181 }
00182 }
00183
00184 if (ent->s.weapon == WP_THERMAL)
00185 { //slight hack for hit sound
00186 G_Sound(ent, CHAN_BODY, G_SoundIndex(va("sound/weapons/thermal/bounce%i.wav", Q_irand(1, 2))));
00187 }
00188 else if (ent->s.weapon == WP_SABER)
00189 {
00190 G_Sound(ent, CHAN_BODY, G_SoundIndex(va("sound/weapons/saber/bounce%i.wav", Q_irand(1, 3))));
00191 }
00192 else if (ent->s.weapon == G2_MODEL_PART)
00193 {
00194 //Limb bounce sound?
00195 }
00196
00197 VectorAdd( ent->r.currentOrigin, trace->plane.normal, ent->r.currentOrigin);
00198 VectorCopy( ent->r.currentOrigin, ent->s.pos.trBase );
00199 ent->s.pos.trTime = level.time;
00200
00201 if (ent->bounceCount != -5)
00202 {
00203 ent->bounceCount--;
00204 }
00205 }
|
|
||||||||||||||||||||
|
Definition at line 277 of file g_missile.c. References DotProduct, vec3_t, VectorMA, VectorNormalize(), and VectorSubtract.
00277 {
00278 vec3_t v, newv;
00279 float dot;
00280
00281 VectorSubtract( impact, start, v );
00282 dot = DotProduct( v, dir );
00283 VectorMA( v, -2*dot, dir, newv );
00284
00285 VectorNormalize(newv);
00286 VectorMA(impact, 8192, newv, endout);
00287 }
|
|
||||||||||||||||
|
Definition at line 91 of file g_missile.c. References AngleVectors(), gentity_s::client, entityShared_t::currentOrigin, DotProduct, G2_MODEL_PART, gentity_t, level, gentity_s::nextthink, entityState_s::number, entityShared_t::ownerNum, entityState_s::pos, gclient_s::ps, gentity_s::r, RandFloat(), gentity_s::s, gentity_s::think, level_locals_t::time, trajectory_t::trBase, trajectory_t::trDelta, trajectory_t::trTime, vec3_t, VectorCopy, VectorNormalize(), VectorScale, playerState_s::viewangles, entityState_s::weapon, WP_ROCKET_LAUNCHER, and WP_SABER. Referenced by G_MissileImpact().
00092 {
00093 vec3_t bounce_dir;
00094 int i;
00095 float speed;
00096 int isowner = 0;
00097 vec3_t missile_dir;
00098
00099 if (missile->r.ownerNum == ent->s.number)
00100 { //the original owner is bouncing the missile, so don't try to bounce it back at him
00101 isowner = 1;
00102 }
00103
00104 //save the original speed
00105 speed = VectorNormalize( missile->s.pos.trDelta );
00106
00107 if (ent->client)
00108 {
00109 //VectorSubtract( ent->r.currentOrigin, missile->r.currentOrigin, missile_dir );
00110 AngleVectors(ent->client->ps.viewangles, missile_dir, 0, 0);
00111 VectorCopy(missile_dir, bounce_dir);
00112 //VectorCopy( missile->s.pos.trDelta, bounce_dir );
00113 VectorScale( bounce_dir, DotProduct( forward, missile_dir ), bounce_dir );
00114 VectorNormalize( bounce_dir );
00115 }
00116 else
00117 {
00118 VectorCopy(forward, bounce_dir);
00119 VectorNormalize(bounce_dir);
00120 }
00121
00122 for ( i = 0; i < 3; i++ )
00123 {
00124 bounce_dir[i] += RandFloat( -1.0f, 1.0f );
00125 }
00126
00127 VectorNormalize( bounce_dir );
00128 VectorScale( bounce_dir, speed, missile->s.pos.trDelta );
00129 missile->s.pos.trTime = level.time; // move a bit on the very first frame
00130 VectorCopy( missile->r.currentOrigin, missile->s.pos.trBase );
00131 if ( missile->s.weapon != WP_SABER && missile->s.weapon != G2_MODEL_PART )
00132 {//you are mine, now!
00133 missile->r.ownerNum = ent->s.number;
00134 }
00135 if ( missile->s.weapon == WP_ROCKET_LAUNCHER )
00136 {//stop homing
00137 missile->think = 0;
00138 missile->nextthink = 0;
00139 }
00140 }
|
|
|
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 324 of file g_missile.c. References entityState_s::angles, entityShared_t::currentOrigin, EV_SABER_BLOCK, entityState_s::eventParm, G_EffectIndex(), G_PlayEffectID(), G_TempEntity(), gentity_t, entityState_s::legsAnim, entityState_s::origin, gentity_s::r, gentity_s::s, vec3_t, VectorCopy, entityState_s::weapon, WP_BLASTER, WP_BOWCASTER, and WP_BRYAR_PISTOL. Referenced by G_MissileImpact().
00325 {
00326 //FIXME: have an EV_BOUNCE_MISSILE event that checks the s.weapon and does the appropriate effect
00327 switch( ent->s.weapon )
00328 {
00329 case WP_BOWCASTER:
00330 G_PlayEffectID( G_EffectIndex("bowcaster/deflect"), ent->r.currentOrigin, dir );
00331 break;
00332 case WP_BLASTER:
00333 case WP_BRYAR_PISTOL:
00334 G_PlayEffectID( G_EffectIndex("blaster/deflect"), ent->r.currentOrigin, dir );
00335 break;
00336 default:
00337 {
00338 gentity_t *te = G_TempEntity( org, EV_SABER_BLOCK );
00339 VectorCopy(org, te->s.origin);
00340 VectorCopy(dir, te->s.angles);
00341 te->s.eventParm = 0;
00342 te->s.weapon = 0;//saberNum
00343 te->s.legsAnim = 0;//bladeNum
00344 }
00345 break;
00346 }
00347 }
|
|
||||||||||||
|
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 24 of file g_missile.c. References entityShared_t::currentOrigin, DotProduct, G2_MODEL_PART, g_entities, gentity_t, level, gentity_s::nextthink, entityState_s::number, entityShared_t::ownerNum, entityState_s::pos, gentity_s::r, RandFloat(), gentity_s::s, gentity_s::think, level_locals_t::time, trajectory_t::trBase, trajectory_t::trDelta, trajectory_t::trTime, vec3_t, VectorCopy, VectorNormalize(), VectorScale, VectorSubtract, entityState_s::weapon, WP_ROCKET_LAUNCHER, and WP_SABER. Referenced by ForceThrow(), and G_MissileImpact().
00025 {
00026 vec3_t bounce_dir;
00027 int i;
00028 float speed;
00029 gentity_t *owner = ent;
00030 int isowner = 0;
00031
00032 if ( ent->r.ownerNum )
00033 {
00034 owner = &g_entities[ent->r.ownerNum];
00035 }
00036
00037 if (missile->r.ownerNum == ent->s.number)
00038 { //the original owner is bouncing the missile, so don't try to bounce it back at him
00039 isowner = 1;
00040 }
00041
00042 //save the original speed
00043 speed = VectorNormalize( missile->s.pos.trDelta );
00044
00045 //if ( ent && owner && owner->NPC && owner->enemy && Q_stricmp( "Tavion", owner->NPC_type ) == 0 && Q_irand( 0, 3 ) )
00046 if ( &g_entities[missile->r.ownerNum] && missile->s.weapon != WP_SABER && missile->s.weapon != G2_MODEL_PART && !isowner )
00047 {//bounce back at them if you can
00048 VectorSubtract( g_entities[missile->r.ownerNum].r.currentOrigin, missile->r.currentOrigin, bounce_dir );
00049 VectorNormalize( bounce_dir );
00050 }
00051 else if (isowner)
00052 { //in this case, actually push the missile away from me, and since we're giving boost to our own missile by pushing it, up the velocity
00053 vec3_t missile_dir;
00054
00055 speed *= 1.5;
00056
00057 VectorSubtract( missile->r.currentOrigin, ent->r.currentOrigin, missile_dir );
00058 VectorCopy( missile->s.pos.trDelta, bounce_dir );
00059 VectorScale( bounce_dir, DotProduct( forward, missile_dir ), bounce_dir );
00060 VectorNormalize( bounce_dir );
00061 }
00062 else
00063 {
00064 vec3_t missile_dir;
00065
00066 VectorSubtract( ent->r.currentOrigin, missile->r.currentOrigin, missile_dir );
00067 VectorCopy( missile->s.pos.trDelta, bounce_dir );
00068 VectorScale( bounce_dir, DotProduct( forward, missile_dir ), bounce_dir );
00069 VectorNormalize( bounce_dir );
00070 }
00071 for ( i = 0; i < 3; i++ )
00072 {
00073 bounce_dir[i] += RandFloat( -0.2f, 0.2f );
00074 }
00075
00076 VectorNormalize( bounce_dir );
00077 VectorScale( bounce_dir, speed, missile->s.pos.trDelta );
00078 missile->s.pos.trTime = level.time; // move a bit on the very first frame
00079 VectorCopy( missile->r.currentOrigin, missile->s.pos.trBase );
00080 if ( missile->s.weapon != WP_SABER && missile->s.weapon != G2_MODEL_PART )
00081 {//you are mine, now!
00082 missile->r.ownerNum = ent->s.number;
00083 }
00084 if ( missile->s.weapon == WP_ROCKET_LAUNCHER )
00085 {//stop homing
00086 missile->think = 0;
00087 missile->nextthink = 0;
00088 }
00089 }
|
|
|
Definition at line 798 of file g_missile.c. References trace_t::allsolid, entityState_s::apos, BG_EvaluateTrajectory(), gentity_s::bounceCount, gentity_s::client, gentity_s::clipmask, entityShared_t::currentOrigin, d_projectileGhoul2Collision, EF_JETPACK_ACTIVE, EF_MISSILE_STICK, entityState_s::eFlags, trace_t::endpos, trace_t::entityNum, ENTITYNUM_NONE, ENTITYNUM_WORLD, ET_MISSILE, ET_NPC, entityState_s::eType, EV_GHOUL2_MARK, FL_BOUNCE_HALF, gentity_s::flags, trace_t::fraction, G2_MODEL_PART, gclient_s::g2LastSurfaceHit, gclient_s::g2LastSurfaceTime, G2TRFLAG_DOGHOULTRACE, G2TRFLAG_GETSURFINDEX, G2TRFLAG_HITCORPSES, G2TRFLAG_THICK, G_AddEvent(), g_entities, G_FreeEntity(), g_g2TraceLod, G_MissileImpact(), G_RunStuckMissile(), G_RunThink(), gentity_t, gentity_s::ghoul2, entityState_s::groundEntityNum, gclient_s::hook, vmCvar_t::integer, gentity_s::inuse, gentity_s::isSaberEntity, level, MAX_CLIENTS, entityShared_t::maxs, entityShared_t::mins, gentity_s::neverFree, NULL, entityState_s::number, entityState_s::origin, entityState_s::origin2, entityState_s::otherEntityNum, entityShared_t::ownerNum, gentity_s::parent, gentity_s::passThroughNum, PITCH, entityState_s::pos, qboolean, qfalse, qtrue, gentity_s::r, ROLL, gentity_s::s, trace_t::startsolid, SURF_NOIMPACT, trace_t::surfaceFlags, SVF_OWNERNOTSHARED, entityShared_t::svFlags, gentity_s::target_ent, level_locals_t::time, TR_GRAVITY, TR_LINEAR, TR_STATIONARY, trap_G2Trace(), trap_LinkEntity(), trap_Trace(), trajectory_t::trBase, trajectory_t::trDelta, entityState_s::trickedentindex, trajectory_t::trTime, trajectory_t::trType, vec3_t, VectorClear, VectorCopy, entityState_s::weapon, WP_NONE, WP_NUM_WEAPONS, and WP_SABER. Referenced by G_RunFrame().
00798 {
00799 vec3_t origin, groundSpot;
00800 trace_t tr;
00801 int passent;
00802 qboolean isKnockedSaber = qfalse;
00803
00804 if (ent->neverFree && ent->s.weapon == WP_SABER && (ent->flags & FL_BOUNCE_HALF))
00805 {
00806 isKnockedSaber = qtrue;
00807 ent->s.pos.trType = TR_GRAVITY;
00808 }
00809
00810 // get current position
00811 BG_EvaluateTrajectory( &ent->s.pos, level.time, origin );
00812
00813 // if this missile bounced off an invulnerability sphere
00814 if ( ent->target_ent ) {
00815 passent = ent->target_ent->s.number;
00816 }
00817 else {
00818 // ignore interactions with the missile owner
00819 if ( (ent->r.svFlags&SVF_OWNERNOTSHARED)
00820 && (ent->s.eFlags&EF_JETPACK_ACTIVE) )
00821 {//A vehicle missile that should be solid to its owner
00822 //I don't care about hitting my owner
00823 passent = ent->s.number;
00824 }
00825 else
00826 {
00827 passent = ent->r.ownerNum;
00828 }
00829 }
00830 // trace a line from the previous position to the current position
00831 if (d_projectileGhoul2Collision.integer)
00832 {
00833 trap_G2Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, origin, passent, ent->clipmask, G2TRFLAG_DOGHOULTRACE|G2TRFLAG_GETSURFINDEX|G2TRFLAG_THICK|G2TRFLAG_HITCORPSES, g_g2TraceLod.integer );
00834
00835 if (tr.fraction != 1.0 && tr.entityNum < ENTITYNUM_WORLD)
00836 {
00837 gentity_t *g2Hit = &g_entities[tr.entityNum];
00838
00839 if (g2Hit->inuse && g2Hit->client && g2Hit->ghoul2)
00840 { //since we used G2TRFLAG_GETSURFINDEX, tr.surfaceFlags will actually contain the index of the surface on the ghoul2 model we collided with.
00841 g2Hit->client->g2LastSurfaceHit = tr.surfaceFlags;
00842 g2Hit->client->g2LastSurfaceTime = level.time;
00843 }
00844
00845 if (g2Hit->ghoul2)
00846 {
00847 tr.surfaceFlags = 0; //clear the surface flags after, since we actually care about them in here.
00848 }
00849 }
00850 }
00851 else
00852 {
00853 trap_Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, origin, passent, ent->clipmask );
00854 }
00855
00856 if ( tr.startsolid || tr.allsolid ) {
00857 // make sure the tr.entityNum is set to the entity we're stuck in
00858 trap_Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, ent->r.currentOrigin, passent, ent->clipmask );
00859 tr.fraction = 0;
00860 }
00861 else {
00862 VectorCopy( tr.endpos, ent->r.currentOrigin );
00863 }
00864
00865 if (ent->passThroughNum && tr.entityNum == (ent->passThroughNum-1))
00866 {
00867 VectorCopy( origin, ent->r.currentOrigin );
00868 trap_LinkEntity( ent );
00869 goto passthrough;
00870 }
00871
00872 trap_LinkEntity( ent );
00873
00874 if (ent->s.weapon == G2_MODEL_PART && !ent->bounceCount)
00875 {
00876 vec3_t lowerOrg;
00877 trace_t trG;
00878
00879 VectorCopy(ent->r.currentOrigin, lowerOrg);
00880 lowerOrg[2] -= 1;
00881 trap_Trace( &trG, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, lowerOrg, passent, ent->clipmask );
00882
00883 VectorCopy(trG.endpos, groundSpot);
00884
00885 if (!trG.startsolid && !trG.allsolid && trG.entityNum == ENTITYNUM_WORLD)
00886 {
00887 ent->s.groundEntityNum = trG.entityNum;
00888 }
00889 else
00890 {
00891 ent->s.groundEntityNum = ENTITYNUM_NONE;
00892 }
00893 }
00894
00895 if ( tr.fraction != 1) {
00896 // never explode or bounce on sky
00897 if ( tr.surfaceFlags & SURF_NOIMPACT ) {
00898 // If grapple, reset owner
00899 if (ent->parent && ent->parent->client && ent->parent->client->hook == ent) {
00900 ent->parent->client->hook = NULL;
00901 }
00902
00903 if ((ent->s.weapon == WP_SABER && ent->isSaberEntity) || isKnockedSaber)
00904 {
00905 G_RunThink( ent );
00906 return;
00907 }
00908 else if (ent->s.weapon != G2_MODEL_PART)
00909 {
00910 G_FreeEntity( ent );
00911 return;
00912 }
00913 }
00914
00915 #if 0 //will get stomped with missile impact event...
00916 if (ent->s.weapon > WP_NONE && ent->s.weapon < WP_NUM_WEAPONS &&
00917 (tr.entityNum < MAX_CLIENTS || g_entities[tr.entityNum].s.eType == ET_NPC))
00918 { //player or NPC, try making a mark on him
00919 /*
00920 gentity_t *evEnt = G_TempEntity(ent->r.currentOrigin, EV_GHOUL2_MARK);
00921
00922 evEnt->s.owner = tr.entityNum; //the entity the mark should be placed on
00923 evEnt->s.weapon = ent->s.weapon; //the weapon used (to determine mark type)
00924 VectorCopy(ent->r.currentOrigin, evEnt->s.origin); //the point of impact
00925
00926 //origin2 gets the predicted trajectory-based position.
00927 BG_EvaluateTrajectory( &ent->s.pos, level.time, evEnt->s.origin2 );
00928
00929 //If they are the same, there will be problems.
00930 if (VectorCompare(evEnt->s.origin, evEnt->s.origin2))
00931 {
00932 evEnt->s.origin2[2] += 2; //whatever, at least it won't mess up.
00933 }
00934 */
00935 //ok, let's try adding it to the missile ent instead (tempents bad!)
00936 G_AddEvent(ent, EV_GHOUL2_MARK, 0);
00937
00938 //copy current pos to s.origin, and current projected traj to origin2
00939 VectorCopy(ent->r.currentOrigin, ent->s.origin);
00940 BG_EvaluateTrajectory( &ent->s.pos, level.time, ent->s.origin2 );
00941
00942 //the index for whoever we are hitting
00943 ent->s.otherEntityNum = tr.entityNum;
00944
00945 if (VectorCompare(ent->s.origin, ent->s.origin2))
00946 {
00947 ent->s.origin2[2] += 2.0f; //whatever, at least it won't mess up.
00948 }
00949 }
00950 #else
00951 if (ent->s.weapon > WP_NONE && ent->s.weapon < WP_NUM_WEAPONS &&
00952 (tr.entityNum < MAX_CLIENTS || g_entities[tr.entityNum].s.eType == ET_NPC))
00953 { //player or NPC, try making a mark on him
00954 //copy current pos to s.origin, and current projected traj to origin2
00955 VectorCopy(ent->r.currentOrigin, ent->s.origin);
00956 BG_EvaluateTrajectory( &ent->s.pos, level.time, ent->s.origin2 );
00957
00958 if (VectorCompare(ent->s.origin, ent->s.origin2))
00959 {
00960 ent->s.origin2[2] += 2.0f; //whatever, at least it won't mess up.
00961 }
00962 }
00963 #endif
00964
00965 G_MissileImpact( ent, &tr );
00966
00967 if (tr.entityNum == ent->s.otherEntityNum)
00968 { //if the impact event other and the trace ent match then it's ok to do the g2 mark
00969 ent->s.trickedentindex = 1;
00970 }
00971
00972 if ( ent->s.eType != ET_MISSILE && ent->s.weapon != G2_MODEL_PART )
00973 {
00974 return; // exploded
00975 }
00976 }
00977
00978 passthrough:
00979 if ( ent->s.pos.trType == TR_STATIONARY && (ent->s.eFlags&EF_MISSILE_STICK) )
00980 {//stuck missiles should check some special stuff
00981 G_RunStuckMissile( ent );
00982 return;
00983 }
00984
00985 if (ent->s.weapon == G2_MODEL_PART)
00986 {
00987 if (ent->s.groundEntityNum == ENTITYNUM_WORLD)
00988 {
00989 ent->s.pos.trType = TR_LINEAR;
00990 VectorClear(ent->s.pos.trDelta);
00991 ent->s.pos.trTime = level.time;
00992
00993 VectorCopy(groundSpot, ent->s.pos.trBase);
00994 VectorCopy(groundSpot, ent->r.currentOrigin);
00995
00996 if (ent->s.apos.trType != TR_STATIONARY)
00997 {
00998 ent->s.apos.trType = TR_STATIONARY;
00999 ent->s.apos.trTime = level.time;
01000
01001 ent->s.apos.trBase[ROLL] = 0;
01002 ent->s.apos.trBase[PITCH] = 0;
01003 }
01004 }
01005 }
01006
01007 // check think function after bouncing
01008 G_RunThink( ent );
01009 }
|
|
|
Definition at line 252 of file g_missile.c. References entityState_s::apos, ENTITYNUM_WORLD, G_Damage(), g_entities, G_RunThink(), gentity_t, entityState_s::groundEntityNum, MOD_CRUSH, NULL, entityState_s::pos, gentity_s::s, gentity_s::takedamage, TR_STATIONARY, trajectory_t::trDelta, trajectory_t::trType, and vec3_origin. Referenced by G_RunMissile().
00253 {
00254 if ( ent->takedamage )
00255 {
00256 if ( ent->s.groundEntityNum >= 0 && ent->s.groundEntityNum < ENTITYNUM_WORLD )
00257 {
00258 gentity_t *other = &g_entities[ent->s.groundEntityNum];
00259
00260 if ( (!VectorCompare( vec3_origin, other->s.pos.trDelta ) && other->s.pos.trType != TR_STATIONARY) ||
00261 (!VectorCompare( vec3_origin, other->s.apos.trDelta ) && other->s.apos.trType != TR_STATIONARY) )
00262 {//thing I stuck to is moving or rotating now, kill me
00263 G_Damage( ent, other, other, NULL, NULL, 99999, 0, MOD_CRUSH );
00264 return;
00265 }
00266 }
00267 }
00268 // check think function
00269 G_RunThink( ent );
00270 }
|
|
|
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 2400 of file g_weapon.c. References entityState_s::angles, entityState_s::apos, entityState_s::bolt2, CHAN_WEAPON, gentity_s::count, entityShared_t::currentAngles, gentity_s::die, EF_FIRING, entityState_s::eFlags, G_SetOrigin(), G_Sound(), G_SoundIndex(), gentity_s::genericValue15, gentity_t, gentity_s::health, laserTrapDelayedExplode(), laserTrapThink(), level, LT_ACTIVATION_DELAY, LT_ALT_TIME, LT_SIZE, entityShared_t::maxs, entityShared_t::mins, gentity_s::movedir, gentity_s::nextthink, entityState_s::pos, gentity_s::pos1, proxMineThink(), qtrue, gentity_s::r, gentity_s::s, SVF_OWNERNOTSHARED, entityShared_t::svFlags, gentity_s::takedamage, gentity_s::think, entityState_s::time, level_locals_t::time, gentity_s::touch, touch_NULL(), touchLaserTrap(), TR_STATIONARY, trajectory_t::trBase, trajectory_t::trDelta, trajectory_t::trTime, trajectory_t::trType, vec3_t, vectoangles(), VectorClear, VectorCopy, and VectorSet.
02401 {
02402 G_SetOrigin( ent, endpos );
02403 VectorCopy( normal, ent->pos1 );
02404
02405 VectorClear( ent->s.apos.trDelta );
02406 // This will orient the object to face in the direction of the normal
02407 VectorCopy( normal, ent->s.pos.trDelta );
02408 //VectorScale( normal, -1, ent->s.pos.trDelta );
02409 ent->s.pos.trTime = level.time;
02410
02411
02412 //This does nothing, cg_missile makes assumptions about direction of travel controlling angles
02413 vectoangles( normal, ent->s.apos.trBase );
02414 VectorClear( ent->s.apos.trDelta );
02415 ent->s.apos.trType = TR_STATIONARY;
02416 VectorCopy( ent->s.apos.trBase, ent->s.angles );
02417 VectorCopy( ent->s.angles, ent->r.currentAngles );
02418
02419
02420 G_Sound( ent, CHAN_WEAPON, G_SoundIndex( "sound/weapons/laser_trap/stick.wav" ) );
02421 if ( ent->count )
02422 {//a tripwire
02423 //add draw line flag
02424 VectorCopy( normal, ent->movedir );
02425 ent->think = laserTrapThink;
02426 ent->nextthink = level.time + LT_ACTIVATION_DELAY;//delay the activation
02427 ent->touch = touch_NULL;
02428 //make it shootable
02429 ent->takedamage = qtrue;
02430 ent->health = 5;
02431 ent->die = laserTrapDelayedExplode;
02432
02433 //shove the box through the wall
02434 VectorSet( ent->r.mins, -LT_SIZE*2, -LT_SIZE*2, -LT_SIZE*2 );
02435 VectorSet( ent->r.maxs, LT_SIZE*2, LT_SIZE*2, LT_SIZE*2 );
02436
02437 //so that the owner can blow it up with projectiles
02438 ent->r.svFlags |= SVF_OWNERNOTSHARED;
02439 }
02440 else
02441 {
02442 ent->touch = touchLaserTrap;
02443 ent->think = proxMineThink;//laserTrapExplode;
02444 ent->genericValue15 = level.time + 30000; //auto-explode after 30 seconds.
02445 ent->nextthink = level.time + LT_ALT_TIME; // How long 'til she blows
02446
02447 //make it shootable
02448 ent->takedamage = qtrue;
02449 ent->health = 5;
02450 ent->die = laserTrapDelayedExplode;
02451
02452 //shove the box through the wall
02453 VectorSet( ent->r.mins, -LT_SIZE*2, -LT_SIZE*2, -LT_SIZE*2 );
02454 VectorSet( ent->r.maxs, LT_SIZE*2, LT_SIZE*2, LT_SIZE*2 );
02455
02456 //so that the owner can blow it up with projectiles
02457 ent->r.svFlags |= SVF_OWNERNOTSHARED;
02458
02459 if ( !(ent->s.eFlags&EF_FIRING) )
02460 {//arm me
02461 G_Sound( ent, CHAN_WEAPON, G_SoundIndex( "sound/weapons/laser_trap/warning.wav" ) );
02462 ent->s.eFlags |= EF_FIRING;
02463 ent->s.time = -1;
02464 ent->s.bolt2 = 1;
02465 }
02466 }
02467 }
|
|
||||||||||||
|
Definition at line 39 of file w_saber.c. Referenced by G_DeflectMissile(), G_ReflectMissile(), and WP_SaberBlock().
|
|
||||||||||||||||
|
Definition at line 9122 of file w_saber.c. References AngleVectors(), BLOCKED_LOWER_LEFT, BLOCKED_LOWER_RIGHT, BLOCKED_TOP, BLOCKED_UPPER_LEFT, BLOCKED_UPPER_RIGHT, gentity_s::client, DotProduct, gentity_t, NULL, playerState_s::origin, gclient_s::ps, playerState_s::saberBlocked, vec3_t, VectorCopy, VectorNormalize(), VectorSubtract, playerState_s::viewangles, playerState_s::viewheight, and WP_MissileBlockForBlock().
09123 {
09124 vec3_t diff, fwdangles={0,0,0}, right;
09125 vec3_t clEye;
09126 float rightdot;
09127 float zdiff;
09128
09129 VectorCopy(self->client->ps.origin, clEye);
09130 clEye[2] += self->client->ps.viewheight;
09131
09132 VectorSubtract( hitloc, clEye, diff );
09133 diff[2] = 0;
09134 VectorNormalize( diff );
09135
09136 fwdangles[1] = self->client->ps.viewangles[1];
09137 // Ultimately we might care if the shot was ahead or behind, but for now, just quadrant is fine.
09138 AngleVectors( fwdangles, NULL, right, NULL );
09139
09140 rightdot = DotProduct(right, diff);
09141 zdiff = hitloc[2] - clEye[2];
09142
09143 if ( zdiff > 0 )
09144 {
09145 if ( rightdot > 0.3 )
09146 {
09147 self->client->ps.saberBlocked = BLOCKED_UPPER_RIGHT;
09148 }
09149 else if ( rightdot < -0.3 )
09150 {
09151 self->client->ps.saberBlocked = BLOCKED_UPPER_LEFT;
09152 }
09153 else
09154 {
09155 self->client->ps.saberBlocked = BLOCKED_TOP;
09156 }
09157 }
09158 else if ( zdiff > -20 )//20 )
09159 {
09160 if ( zdiff < -10 )//30 )
09161 {//hmm, pretty low, but not low enough to use the low block, so we need to duck
09162
09163 }
09164 if ( rightdot > 0.1 )
09165 {
09166 self->client->ps.saberBlocked = BLOCKED_UPPER_RIGHT;
09167 }
09168 else if ( rightdot < -0.1 )
09169 {
09170 self->client->ps.saberBlocked = BLOCKED_UPPER_LEFT;
09171 }
09172 else
09173 {
09174 self->client->ps.saberBlocked = BLOCKED_TOP;
09175 }
09176 }
09177 else
09178 {
09179 if ( rightdot >= 0 )
09180 {
09181 self->client->ps.saberBlocked = BLOCKED_LOWER_RIGHT;
09182 }
09183 else
09184 {
09185 self->client->ps.saberBlocked = BLOCKED_LOWER_LEFT;
09186 }
09187 }
09188
09189 if ( missileBlock )
09190 {
09191 self->client->ps.saberBlocked = WP_MissileBlockForBlock( self->client->ps.saberBlocked );
09192 }
09193 }
|