本文整理汇总了C++中CBaseEntity::BodyTarget方法的典型用法代码示例。如果您正苦于以下问题:C++ CBaseEntity::BodyTarget方法的具体用法?C++ CBaseEntity::BodyTarget怎么用?C++ CBaseEntity::BodyTarget使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类CBaseEntity
的用法示例。
在下文中一共展示了CBaseEntity::BodyTarget方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: Vector
//=========================================================
// CheckRangeAttack1
//=========================================================
BOOL COtis :: CheckRangeAttack1 ( float flDot, float flDist )
{
if ( flDist <= 1024 && flDot >= 0.5 )
{
if ( gpGlobals->time > m_checkAttackTime )
{
TraceResult tr;
Vector shootOrigin = pev->origin + Vector( 0, 0, 55 );
CBaseEntity *pEnemy = m_hEnemy;
Vector shootTarget = ( (pEnemy->BodyTarget( shootOrigin ) - pEnemy->pev->origin) + m_vecEnemyLKP );
UTIL_TraceLine( shootOrigin, shootTarget, dont_ignore_monsters, ENT(pev), &tr );
m_checkAttackTime = gpGlobals->time + 1;
if ( tr.flFraction == 1.0 || (tr.pHit != NULL && CBaseEntity::Instance(tr.pHit) == pEnemy) )
m_lastAttackCheck = TRUE;
else
m_lastAttackCheck = FALSE;
m_checkAttackTime = gpGlobals->time + 1.5;
}
return m_lastAttackCheck;
}
return FALSE;
}
示例2: RadiusDamage
void CBlackHole::RadiusDamage( )
{
CBaseEntity *pEntity = NULL;
TraceResult tr;
float flAdjustedDamage;
Vector vecSpot;
entvars_t *pevOwner = VARS( pev->owner );
Vector vecSrc = pev->origin + Vector(0,0,1);
if ( !pevOwner )
pevOwner = pev;
CBaseEntity *pPlayer = CBaseEntity::Instance (pevOwner);
// iterate on all entities in the vicinity.
while ((pEntity = UTIL_FindEntityInSphere( pEntity, vecSrc, (dmg_chrono_radius.value * (mp_wpn_power.value/100)) )) != NULL)
{
if ( pEntity->pev->movetype != MOVETYPE_PUSH && pEntity->pev->movetype != MOVETYPE_NONE && pEntity->pev->movetype != MOVETYPE_FOLLOW && pEntity->pev->movetype != MOVETYPE_NOCLIP )
{
if (pEntity == this) continue;
if (CVAR_GET_FLOAT("mp_noselfdamage")==1 && pEntity->pev == pevOwner )
continue;
if (CVAR_GET_FLOAT("mp_noteamdamage")==1 && g_pGameRules->PlayerRelationship(pPlayer, pEntity) == GR_TEAMMATE && pEntity->pev != pevOwner)
continue;
vecSpot = pEntity->BodyTarget( vecSrc );
UTIL_TraceLine ( vecSrc, vecSpot, ignore_monsters, ENT(pev), &tr );
if ( tr.flFraction == 1.0 || tr.pHit == pEntity->edict() )
{
flAdjustedDamage = ( vecSrc - tr.vecEndPos ).Length();
if ( flAdjustedDamage < 1 )
flAdjustedDamage = 1;
Vector m_vel = ( vecSrc - tr.vecEndPos ).Normalize() * ((500 * (dmg_chrono_radius.value * (mp_wpn_power.value/100)) / flAdjustedDamage) + 150);
if (m_vel.Length() > 1000) m_vel = m_vel.Normalize() * 1000;
pEntity->pev->velocity = m_vel;
if (flAdjustedDamage < 200)
{
if (!(pEntity->Classify() == CLASS_MACHINE || pEntity->IsBot() || pEntity->IsPlayer() || FClassnameIs(pEntity->pev, "laser_dot") || FClassnameIs(pEntity->pev, "laser_spot")))
{
pEntity->Killed ( pevOwner, 0 );
return;
}
}
}
}
}
}
示例3: Explode
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CPhysExplosion::Explode( CBaseEntity *pActivator )
{
CBaseEntity *pEntity = NULL;
float adjustedDamage, falloff, flDist;
Vector vecSpot;
falloff = 1.0 / 2.5;
// iterate on all entities in the vicinity.
// I've removed the traceline heuristic from phys explosions. SO right now they will
// affect entities through walls. (sjb)
// UNDONE: Try tracing world-only?
while ((pEntity = FindEntity(pEntity, pActivator)) != NULL)
{
// UNDONE: Ask the object if it should get force if it's not MOVETYPE_VPHYSICS?
if ( pEntity->m_takedamage != DAMAGE_NO && (pEntity->GetMoveType() == MOVETYPE_VPHYSICS || (pEntity->VPhysicsGetObject() && !pEntity->IsPlayer())) )
{
vecSpot = pEntity->BodyTarget( GetAbsOrigin() );
// decrease damage for an ent that's farther from the bomb.
flDist = ( GetAbsOrigin() - vecSpot ).Length();
if( m_radius == 0 || flDist <= m_radius )
{
adjustedDamage = flDist * falloff;
adjustedDamage = m_damage - adjustedDamage;
if ( adjustedDamage < 0 )
{
adjustedDamage = 0;
}
CTakeDamageInfo info( this, this, adjustedDamage, DMG_BLAST );
CalculateExplosiveDamageForce( &info, (vecSpot - GetAbsOrigin()), GetAbsOrigin() );
if ( HasSpawnFlags( SF_PHYSEXPLOSION_NODAMAGE ) )
{
pEntity->VPhysicsTakeDamage( info );
}
else
{
pEntity->TakeDamage( info );
}
}
}
}
}
示例4: VecCheckSplatToss
// Mortar launch
BOOL CBigMomma::CheckRangeAttack1( float flDot, float flDist )
{
if ( flDist <= BIG_MORTARDIST && m_mortarTime < gpGlobals->time )
{
CBaseEntity *pEnemy = m_hEnemy;
if ( pEnemy )
{
Vector startPos = pev->origin;
startPos.z += 180;
pev->movedir = VecCheckSplatToss( pev, startPos, pEnemy->BodyTarget( pev->origin ), RANDOM_FLOAT( 150, 500 ) );
if ( pev->movedir != g_vecZero )
return TRUE;
}
}
return FALSE;
}
示例5: DoWashPush
//-----------------------------------------------------------------------------
// Purpose: Push a physics object in our wash. Return false if it's now out of our wash
//-----------------------------------------------------------------------------
bool CBaseHelicopter::DoWashPush( washentity_t *pWash, Vector vecWashOrigin )
{
if ( !pWash || !pWash->hEntity.Get() )
return false;
// Make sure the entity is still within our wash's radius
CBaseEntity *pEntity = pWash->hEntity;
Vector vecSpot = pEntity->BodyTarget( vecWashOrigin );
Vector vecToSpot = ( vecSpot - vecWashOrigin );
vecToSpot.z = 0;
float flDist = VectorNormalize( vecToSpot );
if ( flDist > BASECHOPPER_WASH_RADIUS )
return false;
IPhysicsObject *pPhysObject = pEntity->VPhysicsGetObject();
if ( pPhysObject == NULL )
return false;
// Push it away from the center of the wash
float flMass = pPhysObject->GetMass();
float flPushTime = (gpGlobals->curtime - pWash->flWashStartTime);
float flMinPush = BASECHOPPER_WASH_PUSH_MIN * flMass;
float flMaxPush = BASECHOPPER_WASH_PUSH_MAX * flMass;
float flWashAmount = min( flMaxPush, RemapVal( flPushTime, 0, BASECHOPPER_WASH_RAMP_TIME, flMinPush, flMaxPush ) );
Vector vecForce = flWashAmount * vecToSpot * phys_pushscale.GetFloat();
pEntity->VPhysicsTakeDamage( CTakeDamageInfo( this, this, vecForce, vecWashOrigin, flWashAmount, DMG_BLAST ) );
// Debug
if ( g_debug_basehelicopter.GetInt() == BASECHOPPER_DEBUG_WASH )
{
NDebugOverlay::Cross3D( pEntity->GetAbsOrigin(), -Vector(4,4,4), Vector(4,4,4), 255, 0, 0, true, 0.1f );
NDebugOverlay::Line( pEntity->GetAbsOrigin(), pEntity->GetAbsOrigin() + vecForce, 255, 255, 0, true, 0.1f );
IPhysicsObject *pPhysObject = pEntity->VPhysicsGetObject();
Msg("Pushed %s (mass %f) with force %f (min %.2f max %.2f) at time %.2f\n", pEntity->GetClassname(), pPhysObject->GetMass(), flWashAmount, flMinPush, flMaxPush, gpGlobals->curtime );
}
// If we've pushed this thing for some time, remove it to give us a chance to find lighter things nearby
if ( flPushTime > 2.0 )
return false;
return true;
}
示例6: GetAbsOrigin
//=========================================================
// CheckRangeAttack1
//=========================================================
bool CNPC_HL1Barney::CheckRangeAttack1 ( float flDot, float flDist )
{
if ( gpGlobals->curtime > m_flCheckAttackTime )
{
trace_t tr;
Vector shootOrigin = GetAbsOrigin() + Vector( 0, 0, 55 );
CBaseEntity *pEnemy = GetEnemy();
Vector shootTarget = ( (pEnemy->BodyTarget( shootOrigin ) - pEnemy->GetAbsOrigin()) + GetEnemyLKP() );
UTIL_TraceLine ( shootOrigin, shootTarget, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr);
m_flCheckAttackTime = gpGlobals->curtime + 1;
if ( tr.fraction == 1.0 || ( tr.m_pEnt != NULL && tr.m_pEnt == pEnemy) )
m_fLastAttackCheck = TRUE;
else
m_fLastAttackCheck = FALSE;
m_flCheckAttackTime = gpGlobals->curtime + 1.5;
}
return m_fLastAttackCheck;
}
示例7: GetEnemy
// Mortar launch
int CNPC_BigMomma::RangeAttack1Conditions( float flDot, float flDist )
{
if ( flDist > BIG_MORTARDIST )
return COND_TOO_FAR_TO_ATTACK;
if ( flDist <= BIG_MORTARDIST && m_mortarTime < gpGlobals->curtime )
{
CBaseEntity *pEnemy = GetEnemy();
if ( pEnemy )
{
Vector startPos = GetAbsOrigin();
startPos.z += 180;
m_vTossDir = VecCheckSplatToss( this, startPos, pEnemy->BodyTarget( GetAbsOrigin() ), random->RandomFloat( 150, 500 ) );
if ( m_vTossDir != vec3_origin )
return COND_CAN_RANGE_ATTACK1;
}
}
return COND_NONE;
}
示例8: TrackTarget
void CAPCController::TrackTarget( void )
{
trace_t tr;
bool updateTime = FALSE, lineOfSight;
QAngle angles;
Vector barrelEnd;
CBaseEntity *pTarget = NULL;
barrelEnd.Init();
if ( IsActive() )
{
SetNextThink( gpGlobals->curtime + 0.1f );
}
else
{
return;
}
// -----------------------------------
// Get world target position
// -----------------------------------
barrelEnd = WorldBarrelPosition();
Vector worldTargetPosition;
CBaseEntity *pEntity = (CBaseEntity *)m_hTarget;
if ( !pEntity || ( pEntity->GetFlags() & FL_NOTARGET ) )
{
m_hTarget = FindTarget( m_targetEntityName, NULL );
if ( IsActive() )
{
SetNextThink( gpGlobals->curtime + 2 ); // Wait 2 sec s
}
return;
}
pTarget = pEntity;
// Calculate angle needed to aim at target
worldTargetPosition = pEntity->EyePosition();
float range = (worldTargetPosition - barrelEnd).Length();
if ( !InRange( range ) )
{
m_bFireDelayed = false;
return;
}
UTIL_TraceLine( barrelEnd, worldTargetPosition, MASK_BLOCKLOS, this, COLLISION_GROUP_NONE, &tr );
lineOfSight = FALSE;
// No line of sight, don't track
if ( tr.fraction == 1.0 || tr.m_pEnt == pTarget )
{
lineOfSight = TRUE;
CBaseEntity *pInstance = pTarget;
if ( InRange( range ) && pInstance && pInstance->IsAlive() )
{
updateTime = TRUE;
// Sight position is BodyTarget with no noise (so gun doesn't bob up and down)
m_sightOrigin = pInstance->BodyTarget( GetLocalOrigin(), false );
}
}
// Convert targetPosition to parent
angles = AimBarrelAt( m_parentMatrix.WorldToLocal( m_sightOrigin ) );
// Force the angles to be relative to the center position
float offsetY = UTIL_AngleDistance( angles.y, m_yawCenter );
float offsetX = UTIL_AngleDistance( angles.x, m_pitchCenter );
angles.y = m_yawCenter + offsetY;
angles.x = m_pitchCenter + offsetX;
// Move toward target at rate or less
float distY = UTIL_AngleDistance( angles.y, GetLocalAngles().y );
QAngle vecAngVel = GetLocalAngularVelocity();
vecAngVel.y = distY * 10;
vecAngVel.y = clamp( vecAngVel.y, -m_yawRate, m_yawRate );
// Move toward target at rate or less
float distX = UTIL_AngleDistance( angles.x, GetLocalAngles().x );
vecAngVel.x = distX * 10;
vecAngVel.x = clamp( vecAngVel.x, -m_pitchRate, m_pitchRate );
SetLocalAngularVelocity( vecAngVel );
SetMoveDoneTime( 0.1 );
Vector forward;
AngleVectors( GetLocalAngles(), &forward );
forward = m_parentMatrix.ApplyRotation( forward );
AngleVectors(angles, &forward);
if ( lineOfSight == TRUE )
{
// FIXME: This will ultimately have to deal with NPCs being in the vehicle as well
//.........这里部分代码省略.........
示例9: RunTask
void CGargantua::RunTask( const Task_t& task )
{
switch ( task.iTask )
{
case TASK_DIE:
if ( gpGlobals->time > m_flWaitFinished )
{
SetRenderFX( kRenderFxExplode );
SetRenderColor( Vector( 255, 0, 0 ) );
StopAnimation();
SetNextThink( gpGlobals->time + 0.15 );
SetThink( &CGargantua::SUB_Remove );
int i;
int parts = MODEL_FRAMES( gGargGibModel );
for ( i = 0; i < 10; i++ )
{
auto pGib = CGib::GibCreate( GARG_GIB_MODEL );
int bodyPart = 0;
if ( parts > 1 )
bodyPart = RANDOM_LONG( 0, GetBody() -1 );
pGib->SetBody( bodyPart );
pGib->m_bloodColor = BLOOD_COLOR_YELLOW;
pGib->m_material = matNone;
pGib->SetAbsOrigin( GetAbsOrigin() );
pGib->SetAbsVelocity( UTIL_RandomBloodVector() * RANDOM_FLOAT( 300, 500 ) );
pGib->SetNextThink( gpGlobals->time + 1.25 );
pGib->SetThink( &CGib::SUB_FadeOut );
}
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, GetAbsOrigin() );
WRITE_BYTE( TE_BREAKMODEL);
// position
WRITE_COORD( GetAbsOrigin().x );
WRITE_COORD( GetAbsOrigin().y );
WRITE_COORD( GetAbsOrigin().z );
// size
WRITE_COORD( 200 );
WRITE_COORD( 200 );
WRITE_COORD( 128 );
// velocity
WRITE_COORD( 0 );
WRITE_COORD( 0 );
WRITE_COORD( 0 );
// randomization
WRITE_BYTE( 200 );
// Model
WRITE_SHORT( gGargGibModel ); //model id#
// # of shards
WRITE_BYTE( 50 );
// duration
WRITE_BYTE( 20 );// 3.0 seconds
// flags
WRITE_BYTE( BREAK_FLESH );
MESSAGE_END();
return;
}
else
CBaseMonster::RunTask( task );
break;
case TASK_FLAME_SWEEP:
if ( gpGlobals->time > m_flWaitFinished )
{
FlameDestroy();
TaskComplete();
FlameControls( 0, 0 );
SetBoneController( 0, 0 );
SetBoneController( 1, 0 );
}
else
{
bool cancel = false;
Vector angles = g_vecZero;
FlameUpdate();
CBaseEntity *pEnemy = m_hEnemy;
if ( pEnemy )
{
Vector org = GetAbsOrigin();
org.z += 64;
Vector dir = pEnemy->BodyTarget(org) - org;
angles = UTIL_VecToAngles( dir );
angles.x = -angles.x;
angles.y -= GetAbsAngles().y;
if ( dir.Length() > 400 )
cancel = true;
}
if ( fabs(angles.y) > 60 )
//.........这里部分代码省略.........
示例10: FireBullet
void CNPC_Portal_FloorTurret::FireBullet( const char *pTargetName )
{
CBaseEntity *pEnemy = gEntList.FindEntityByName( NULL, pTargetName );
if ( !pEnemy )
return;
//Get our shot positions
Vector vecMid = EyePosition();
Vector vecMidEnemy = pEnemy->BodyTarget( vecMid );
// Store off our last seen location so we can suppress it later
m_vecEnemyLKP = vecMidEnemy;
//Calculate dir and dist to enemy
Vector vecDirToEnemy = vecMidEnemy - vecMid;
m_flDistToEnemy = VectorNormalize( vecDirToEnemy );
//We want to look at the enemy's eyes so we don't jitter
Vector vecDirToEnemyEyes = vecMidEnemy - vecMid;
VectorNormalize( vecDirToEnemyEyes );
QAngle vecAnglesToEnemy;
VectorAngles( vecDirToEnemyEyes, vecAnglesToEnemy );
Vector vecMuzzle, vecMuzzleDir;
GetAttachment( m_iMuzzleAttachment, vecMuzzle, &vecMuzzleDir );
if ( m_flShotTime < gpGlobals->curtime )
{
Vector2D vecDirToEnemy2D = vecDirToEnemy.AsVector2D();
Vector2D vecMuzzleDir2D = vecMuzzleDir.AsVector2D();
if ( m_flDistToEnemy < 60.0 )
{
vecDirToEnemy2D.NormalizeInPlace();
vecMuzzleDir2D.NormalizeInPlace();
}
//Fire the gun
if( m_bOutOfAmmo )
{
DryFire();
}
else
{
SetActivity( (Activity) ACT_FLOOR_TURRET_OPEN_IDLE );
SetActivity( (Activity)( ( m_bShootWithBottomBarrels ) ? ( ACT_FLOOR_TURRET_FIRE2 ) : ( ACT_FLOOR_TURRET_FIRE ) ) );
//Fire the weapon
#if !DISABLE_SHOT
Shoot( vecMuzzle, vecDirToEnemy, true );
#endif
}
//If we can see our enemy, face it
m_vecGoalAngles.y = vecAnglesToEnemy.y;
m_vecGoalAngles.x = vecAnglesToEnemy.x;
//Turn to face
UpdateFacing();
EmitSound( "NPC_FloorTurret.Alert" );
SetThink( &CNPC_FloorTurret::SuppressThink );
}
}
示例11: DoRotorPhysicsPush
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseHelicopter::DoRotorPhysicsPush( const Vector &vecRotorOrigin, float flAltitude )
{
CBaseEntity *pEntity = NULL;
trace_t tr;
// First, trace down and find out where the was is hitting the ground
UTIL_TraceLine( vecRotorOrigin, vecRotorOrigin+Vector(0,0,-flAltitude), (MASK_SOLID_BRUSHONLY|CONTENTS_WATER), NULL, COLLISION_GROUP_NONE, &tr );
// Always raise the physics origin a bit
Vector vecPhysicsOrigin = tr.endpos + Vector(0,0,64);
// Debug
if ( g_debug_basehelicopter.GetInt() == BASECHOPPER_DEBUG_WASH )
{
NDebugOverlay::Cross3D( vecPhysicsOrigin, -Vector(16,16,16), Vector(16,16,16), 0, 255, 255, true, 0.1f );
}
// Push entities that we've pushed before, and are still within range
// Walk backwards because they may be removed if they're now out of range
int iCount = m_hEntitiesPushedByWash.Count();
bool bWasPushingObjects = (iCount > 0);
for ( int i = (iCount-1); i >= 0; i-- )
{
if ( !DoWashPush( &(m_hEntitiesPushedByWash[i]), vecPhysicsOrigin ) )
{
// Out of range now, so remove
m_hEntitiesPushedByWash.Remove(i);
}
}
if ( m_flRotorWashEntitySearchTime > gpGlobals->curtime )
return;
// Any spare slots?
iCount = m_hEntitiesPushedByWash.Count();
if ( iCount >= BASECHOPPER_WASH_MAX_OBJECTS )
return;
// Find the lightest physics entity below us and add it to our list to push around
CBaseEntity *pLightestEntity = NULL;
float flLightestMass = 9999;
while ((pEntity = gEntList.FindEntityInSphere(pEntity, vecPhysicsOrigin, BASECHOPPER_WASH_RADIUS )) != NULL)
{
IRotorWashShooter *pShooter = GetRotorWashShooter( pEntity );
if ( pEntity->IsEFlagSet( EFL_NO_ROTORWASH_PUSH ))
continue;
if ( pShooter || pEntity->GetMoveType() == MOVETYPE_VPHYSICS || (pEntity->VPhysicsGetObject() && !pEntity->IsPlayer()) )
{
// Make sure it's not already in our wash
bool bAlreadyPushing = false;
for ( int i = 0; i < iCount; i++ )
{
if ( m_hEntitiesPushedByWash[i].hEntity == pEntity )
{
bAlreadyPushing = true;
break;
}
}
if ( bAlreadyPushing )
continue;
float flMass = FLT_MAX;
if ( pShooter )
{
flMass = 1.0f;
}
else
{
// Don't try to push anything too big
IPhysicsObject *pPhysObject = pEntity->VPhysicsGetObject();
if ( pPhysObject )
{
flMass = pPhysObject->GetMass();
if ( flMass > BASECHOPPER_WASH_MAX_MASS )
continue;
}
}
// Ignore anything bigger than the one we've already found
if ( flMass > flLightestMass )
continue;
Vector vecSpot = pEntity->BodyTarget( vecPhysicsOrigin );
// Don't push things too far below our starting point (helps reduce through-roof cases w/o doing a trace)
if ( fabs( vecSpot.z - vecPhysicsOrigin.z ) > 96 )
continue;
Vector vecToSpot = ( vecSpot - vecPhysicsOrigin );
vecToSpot.z = 0;
float flDist = VectorNormalize( vecToSpot );
if ( flDist > BASECHOPPER_WASH_RADIUS )
continue;
// Try to cast to the helicopter; if we can't, then we can't be hit.
//.........这里部分代码省略.........
示例12: RadiusDamage
// Add the ability to ignore the world trace
void CSDKGameRules::RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrcIn, float flRadius, int iClassIgnore, bool bIgnoreWorld )
{
CBaseEntity *pEntity = NULL;
trace_t tr;
float flAdjustedDamage, falloff;
Vector vecSpot;
Vector vecToTarget;
Vector vecEndPos;
Vector vecSrc = vecSrcIn;
if ( flRadius )
falloff = info.GetDamage() / flRadius;
else
falloff = 1.0;
int bInWater = (UTIL_PointContents ( vecSrc ) & MASK_WATER) ? true : false;
vecSrc.z += 1;// in case grenade is lying on the ground
// iterate on all entities in the vicinity.
for ( CEntitySphereQuery sphere( vecSrc, flRadius ); ( pEntity = sphere.GetCurrentEntity() ) != NULL; sphere.NextEntity() )
{
if ( pEntity->m_takedamage != DAMAGE_NO )
{
// UNDONE: this should check a damage mask, not an ignore
if ( iClassIgnore != CLASS_NONE && pEntity->Classify() == iClassIgnore )
{// houndeyes don't hurt other houndeyes with their attack
continue;
}
// blast's don't tavel into or out of water
if (bInWater && pEntity->GetWaterLevel() == 0)
continue;
if (!bInWater && pEntity->GetWaterLevel() == 3)
continue;
// radius damage can only be blocked by the world
vecSpot = pEntity->BodyTarget( vecSrc );
bool bHit = false;
if( bIgnoreWorld )
{
vecEndPos = vecSpot;
bHit = true;
}
else
{
UTIL_TraceLine( vecSrc, vecSpot, MASK_SOLID_BRUSHONLY, info.GetInflictor(), COLLISION_GROUP_NONE, &tr );
if (tr.startsolid)
{
// if we're stuck inside them, fixup the position and distance
tr.endpos = vecSrc;
tr.fraction = 0.0;
}
vecEndPos = tr.endpos;
if( tr.fraction == 1.0 || tr.m_pEnt == pEntity )
{
bHit = true;
}
}
if ( bHit )
{
// the explosion can 'see' this entity, so hurt them!
//vecToTarget = ( vecSrc - vecEndPos );
vecToTarget = ( vecEndPos - vecSrc );
// decrease damage for an ent that's farther from the bomb.
flAdjustedDamage = vecToTarget.Length() * falloff;
flAdjustedDamage = info.GetDamage() - flAdjustedDamage;
if ( flAdjustedDamage > 0 )
{
CTakeDamageInfo adjustedInfo = info;
adjustedInfo.SetDamage( flAdjustedDamage );
Vector dir = vecToTarget;
VectorNormalize( dir );
// If we don't have a damage force, manufacture one
if ( adjustedInfo.GetDamagePosition() == vec3_origin || adjustedInfo.GetDamageForce() == vec3_origin )
{
CalculateExplosiveDamageForce( &adjustedInfo, dir, vecSrc, 1.5 /* explosion scale! */ );
}
else
{
// Assume the force passed in is the maximum force. Decay it based on falloff.
float flForce = adjustedInfo.GetDamageForce().Length() * falloff;
adjustedInfo.SetDamageForce( dir * flForce );
adjustedInfo.SetDamagePosition( vecSrc );
}
//.........这里部分代码省略.........
示例13: ActiveThink
void CNPC_Portal_FloorTurret::ActiveThink( void )
{
LaserOn();
//Allow descended classes a chance to do something before the think function
if ( PreThink( TURRET_ACTIVE ) )
return;
HackFindEnemy();
//Update our think time
SetNextThink( gpGlobals->curtime + 0.1f );
CBaseEntity *pEnemy = GetEnemy();
//If we've become inactive, go back to searching
if ( ( m_bActive == false ) || ( pEnemy == NULL ) )
{
SetEnemy( NULL );
m_flLastSight = gpGlobals->curtime + FLOOR_TURRET_MAX_WAIT;
SetThink( &CNPC_FloorTurret::SearchThink );
m_vecGoalAngles = GetAbsAngles();
return;
}
//Get our shot positions
Vector vecMid = EyePosition();
Vector vecMidEnemy = pEnemy->BodyTarget( vecMid );
// Store off our last seen location so we can suppress it later
m_vecEnemyLKP = vecMidEnemy;
//Look for our current enemy
bool bEnemyInFOV = FInViewCone( pEnemy );
bool bEnemyVisible = FVisible( pEnemy ) && pEnemy->IsAlive();
//Calculate dir and dist to enemy
Vector vecDirToEnemy = vecMidEnemy - vecMid;
m_flDistToEnemy = VectorNormalize( vecDirToEnemy );
// If the enemy isn't in the normal fov, check the fov through portals
CProp_Portal *pPortal = NULL;
if ( pEnemy->IsAlive() )
{
pPortal = FInViewConeThroughPortal( pEnemy );
if ( pPortal && FVisibleThroughPortal( pPortal, pEnemy ) )
{
// Translate our target across the portal
Vector vecMidEnemyTransformed;
UTIL_Portal_PointTransform( pPortal->m_hLinkedPortal->MatrixThisToLinked(), vecMidEnemy, vecMidEnemyTransformed );
//Calculate dir and dist to enemy
Vector vecDirToEnemyTransformed = vecMidEnemyTransformed - vecMid;
float flDistToEnemyTransformed = VectorNormalize( vecDirToEnemyTransformed );
// If it's not visible through normal means or the enemy is closer through the portal, use the translated info
if ( !bEnemyInFOV || !bEnemyVisible || flDistToEnemyTransformed < m_flDistToEnemy )
{
bEnemyInFOV = true;
bEnemyVisible = true;
vecMidEnemy = vecMidEnemyTransformed;
vecDirToEnemy = vecDirToEnemyTransformed;
m_flDistToEnemy = flDistToEnemyTransformed;
}
else
{
pPortal = NULL;
}
}
else
{
pPortal = NULL;
}
}
//Draw debug info
if ( g_debug_turret.GetBool() )
{
NDebugOverlay::Cross3D( vecMid, -Vector(2,2,2), Vector(2,2,2), 0, 255, 0, false, 0.05 );
NDebugOverlay::Cross3D( GetEnemy()->WorldSpaceCenter(), -Vector(2,2,2), Vector(2,2,2), 0, 255, 0, false, 0.05 );
NDebugOverlay::Line( vecMid, GetEnemy()->WorldSpaceCenter(), 0, 255, 0, false, 0.05 );
NDebugOverlay::Cross3D( vecMid, -Vector(2,2,2), Vector(2,2,2), 0, 255, 0, false, 0.05 );
NDebugOverlay::Cross3D( vecMidEnemy, -Vector(2,2,2), Vector(2,2,2), 0, 255, 0, false, 0.05 );
NDebugOverlay::Line( vecMid, vecMidEnemy, 0, 255, 0, false, 0.05f );
}
//See if they're past our FOV of attack
if ( bEnemyInFOV == false )
{
// Should we look for a new target?
ClearEnemyMemory();
SetEnemy( NULL );
if ( m_spawnflags & SF_FLOOR_TURRET_FASTRETIRE )
{
// Retire quickly in this case. (The case where we saw the player, but he hid again).
m_flLastSight = gpGlobals->curtime + FLOOR_TURRET_SHORT_WAIT;
}
//.........这里部分代码省略.........
示例14: RunTask
void CNPC_Hydra::RunTask( const Task_t *pTask )
{
switch( pTask->iTask )
{
case TASK_HYDRA_DEPLOY:
{
m_flHeadGoalInfluence = 1.0;
float dist = (EyePosition() - m_vecHeadGoal).Length();
if (dist < m_idealSegmentLength)
{
TaskComplete();
}
AimHeadInTravelDirection( 0.2 );
}
break;
case TASK_HYDRA_PREP_STAB:
{
int i;
if (m_body.Count() < 2)
{
TaskFail( "hydra is too short to begin stab" );
return;
}
CBaseEntity *pTarget = GetTarget();
if (pTarget == NULL)
{
TaskFail( FAIL_NO_TARGET );
}
if (pTarget->IsPlayer())
{
m_vecTarget = pTarget->EyePosition( );
}
else
{
m_vecTarget = pTarget->BodyTarget( EyePosition( ) );
}
float distToTarget = (m_vecTarget - m_vecHeadGoal).Length();
float distToBase = (m_vecHeadGoal - GetAbsOrigin()).Length();
m_idealLength = distToTarget + distToBase * 0.5;
if (m_idealLength > HYDRA_MAX_LENGTH)
m_idealLength = HYDRA_MAX_LENGTH;
if (distToTarget < 100.0)
{
m_vecTargetDir = (m_vecTarget - m_vecHeadGoal);
VectorNormalize( m_vecTargetDir );
m_vecHeadGoal = m_vecHeadGoal - m_vecTargetDir * (100 - distToTarget) * 0.5;
}
else if (distToTarget > 200.0)
{
m_vecTargetDir = (m_vecTarget - m_vecHeadGoal);
VectorNormalize( m_vecTargetDir );
m_vecHeadGoal = m_vecHeadGoal - m_vecTargetDir * (200.0 - distToTarget) * 0.5;
}
// face enemy
m_vecTargetDir = (m_vecTarget - m_body[m_body.Count()-1].vecPos);
VectorNormalize( m_vecTargetDir );
m_vecHeadDir = m_vecHeadDir * 0.6 + m_vecTargetDir * 0.4;
VectorNormalize( m_vecHeadDir.GetForModify() );
// build tension towards strike time
float influence = 1.0 - (m_flTaskEndTime - gpGlobals->curtime) / pTask->flTaskData;
if (influence > 1)
influence = 1.0;
influence = influence * influence * influence;
m_flHeadGoalInfluence = influence;
// keep head segment straight
i = m_body.Count() - 2;
m_body[i].vecGoalPos = m_vecHeadGoal - m_vecHeadDir * m_body[i].flActualLength;
m_body[i].flGoalInfluence = influence;
// curve neck into spiral
float distBackFromHead = m_body[i].flActualLength;
Vector right, up;
VectorVectors( m_vecHeadDir, right, up );
for (i = i - 1; i > 1 && distBackFromHead < distToTarget; i--)
{
distBackFromHead += m_body[i].flActualLength;
float r = (distBackFromHead / 200) * 3.1415 * 2;
// spiral
Vector p0 = m_vecHeadGoal
- m_vecHeadDir * distBackFromHead * 0.5
+ cos( r ) * m_body[i].flActualLength * right
+ sin( r ) * m_body[i].flActualLength * up;
//.........这里部分代码省略.........
示例15: SearchThink
//-----------------------------------------------------------------------------
// Purpose: Target doesn't exist or has eluded us, so search for one
//-----------------------------------------------------------------------------
void CNPC_Portal_FloorTurret::SearchThink( void )
{
//Allow descended classes a chance to do something before the think function
if ( PreThink( TURRET_SEARCHING ) )
return;
SetNextThink( gpGlobals->curtime + 0.05f );
SetActivity( (Activity) ACT_FLOOR_TURRET_OPEN_IDLE );
//If our enemy has died, pick a new enemy
if ( ( GetEnemy() != NULL ) && ( GetEnemy()->IsAlive() == false ) )
{
SetEnemy( NULL );
}
//Acquire the target
if ( GetEnemy() == NULL )
{
HackFindEnemy();
}
LaserOn();
CBaseEntity *pEnemy = GetEnemy();
//If we've found a target, spin up the barrel and start to attack
if ( pEnemy != NULL )
{
//Get our shot positions
Vector vecMid = EyePosition();
Vector vecMidEnemy = pEnemy->BodyTarget( vecMid );
//Look for our current enemy
bool bEnemyInFOV = FInViewCone( pEnemy );
bool bEnemyVisible = FVisible( pEnemy );
//Calculate dir and dist to enemy
Vector vecDirToEnemy = vecMidEnemy - vecMid;
m_flDistToEnemy = VectorNormalize( vecDirToEnemy );
// If the enemy isn't in the normal fov, check the fov through portals
CProp_Portal *pPortal = NULL;
pPortal = FInViewConeThroughPortal( pEnemy );
if ( pPortal && FVisibleThroughPortal( pPortal, pEnemy ) )
{
// Translate our target across the portal
Vector vecMidEnemyTransformed;
UTIL_Portal_PointTransform( pPortal->m_hLinkedPortal->MatrixThisToLinked(), vecMidEnemy, vecMidEnemyTransformed );
//Calculate dir and dist to enemy
Vector vecDirToEnemyTransformed = vecMidEnemyTransformed - vecMid;
float flDistToEnemyTransformed = VectorNormalize( vecDirToEnemyTransformed );
// If it's not visible through normal means or the enemy is closer through the portal, use the translated info
if ( !bEnemyInFOV || !bEnemyVisible || flDistToEnemyTransformed < m_flDistToEnemy )
{
bEnemyInFOV = true;
bEnemyVisible = true;
vecMidEnemy = vecMidEnemyTransformed;
vecDirToEnemy = vecDirToEnemyTransformed;
m_flDistToEnemy = flDistToEnemyTransformed;
}
}
// Give enemies that are farther away a longer grace period
float fDistanceRatio = m_flDistToEnemy / PORTAL_FLOOR_TURRET_RANGE;
m_flShotTime = gpGlobals->curtime + fDistanceRatio * fDistanceRatio * PORTAL_FLOOR_TURRET_MAX_SHOT_DELAY;
m_flLastSight = 0;
SetThink( &CNPC_FloorTurret::ActiveThink );
SetEyeState( TURRET_EYE_SEE_TARGET );
SpinUp();
if ( gpGlobals->curtime > m_flNextActivateSoundTime )
{
EmitSound( "NPC_FloorTurret.Activate" );
m_flNextActivateSoundTime = gpGlobals->curtime + 3.0;
}
return;
}
//Are we out of time and need to retract?
if ( gpGlobals->curtime > m_flLastSight )
{
//Before we retrace, make sure that we are spun down.
m_flLastSight = 0;
SetThink( &CNPC_FloorTurret::Retire );
return;
}
//Display that we're scanning
m_vecGoalAngles.x = GetAbsAngles().x + ( sin( ( m_flLastSight + gpGlobals->curtime * m_fSearchSpeed ) * 1.5f ) * 20.0f );
m_vecGoalAngles.y = GetAbsAngles().y + ( sin( ( m_flLastSight + gpGlobals->curtime * m_fSearchSpeed ) * 2.5f ) * 20.0f );
//.........这里部分代码省略.........