📄 hl1_npc_nihilanth.cpp
字号:
if (m_hFriend[i] == NULL)
{
if ( random->RandomInt( 0, 1 ) == 0)
{
int iNode = GetNavigator()->GetNetwork()->NearestNodeToPoint( vecStart );
CAI_Node *pNode = GetNavigator()->GetNetwork()->GetNode( iNode );
if ( pNode && pNode->GetType() == NODE_AIR )
{
trace_t tr;
Vector vNodeOrigin = pNode->GetOrigin();
UTIL_TraceHull( vNodeOrigin + Vector( 0, 0, 32 ), vNodeOrigin + Vector( 0, 0, 32 ), Vector(-40,-40, 0), Vector(40, 40, 100), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );
if ( tr.startsolid == 0 )
m_hFriend[i] = Create("monster_alien_controller", vNodeOrigin, GetAbsAngles() );
}
}
else
{
int iNode = GetNavigator()->GetNetwork()->NearestNodeToPoint( vecStart );
CAI_Node *pNode = GetNavigator()->GetNetwork()->GetNode( iNode );
if ( pNode && ( pNode->GetType() == NODE_GROUND || pNode->GetType() == NODE_WATER ) )
{
trace_t tr;
Vector vNodeOrigin = pNode->GetOrigin();
UTIL_TraceHull( vNodeOrigin + Vector( 0, 0, 36 ), vNodeOrigin + Vector( 0, 0, 36 ), Vector( -15, -15, 0), Vector( 20, 15, 72 ), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );
if (tr.startsolid == 0)
m_hFriend[i] = Create("monster_alien_slave", vNodeOrigin, GetAbsAngles() );
}
}
if (m_hFriend[i] != NULL)
{
CPASAttenuationFilter filter( this );
enginesound->EmitSound( filter, m_hFriend[i]->entindex(), CHAN_WEAPON, "debris/beamstart7.wav", 1.0, ATTN_NORM );
}
return;
}
}
}
void CNPC_Nihilanth::ShootBalls( void )
{
if (m_flShootEnd > gpGlobals->curtime)
{
Vector vecHand;
QAngle vecAngle;
while (m_flShootTime < m_flShootEnd && m_flShootTime < gpGlobals->curtime)
{
if ( GetEnemy() != NULL)
{
Vector vecSrc, vecDir;
CNihilanthHVR *pEntity = NULL;
GetAttachment( 3, vecHand, vecAngle );
vecSrc = vecHand + GetAbsVelocity() * (m_flShootTime - gpGlobals->curtime);
vecDir = m_posTarget - GetAbsOrigin();
VectorNormalize( vecDir );
vecSrc = vecSrc + vecDir * (gpGlobals->curtime - m_flShootTime);
pEntity = (CNihilanthHVR *)CREATE_ENTITY( CNihilanthHVR, "nihilanth_energy_ball" );
pEntity->SetAbsOrigin( vecSrc );
pEntity->SetAbsAngles( vecAngle );
pEntity->SetOwnerEntity( this );
pEntity->Spawn();
pEntity->SetAbsVelocity( vecDir * 200.0 );
pEntity->ZapInit( GetEnemy() );
GetAttachment( 4, vecHand, vecAngle );
vecSrc = vecHand + GetAbsVelocity() * (m_flShootTime - gpGlobals->curtime);
vecDir = m_posTarget - GetAbsOrigin();
VectorNormalize( vecDir );
vecSrc = vecSrc + vecDir * (gpGlobals->curtime - m_flShootTime);
pEntity = (CNihilanthHVR *)CREATE_ENTITY( CNihilanthHVR, "nihilanth_energy_ball" );
pEntity->SetAbsOrigin( vecSrc );
pEntity->SetAbsAngles( vecAngle );
pEntity->SetOwnerEntity( this );
pEntity->Spawn();
pEntity->SetAbsVelocity( vecDir * 200.0 );
pEntity->ZapInit( GetEnemy() );
}
m_flShootTime += 0.2;
}
}
}
void CNPC_Nihilanth::FloatSequence( void )
{
if (m_irritation >= 2)
{
SetSequence( LookupSequence( "float_open" ) );
}
else if (m_avelocity.y > 30)
{
SetSequence( LookupSequence( "walk_r" ) );
}
else if (m_avelocity.y < -30)
{
SetSequence( LookupSequence( "walk_l" ) );
}
else if (m_velocity.z > 30)
{
SetSequence( LookupSequence( "walk_u" ) );
}
else if (m_velocity.z < -30)
{
SetSequence( LookupSequence( "walk_d" ) );
}
else
{
SetSequence( LookupSequence( "float" ) );
}
}
void CNPC_Nihilanth::DyingThink( void )
{
SetNextThink( gpGlobals->curtime + 0.1 );
DispatchAnimEvents( this );
StudioFrameAdvance( );
if ( m_lifeState == LIFE_ALIVE )
{
DeathSound( );
m_lifeState = LIFE_DYING;
m_posDesired.z = m_flMaxZ;
}
if ( GetAbsOrigin().z < m_flMaxZ && m_lifeState == LIFE_DEAD )
{
SetAbsOrigin( Vector( GetAbsOrigin().x, GetAbsOrigin().y, m_flMaxZ ) );
SetAbsVelocity( Vector( 0, 0, 0 ) );
}
if ( m_lifeState == LIFE_DYING )
{
Flight( );
if (fabs( GetAbsOrigin().z - m_flMaxZ ) < 16)
{
CBaseEntity *pTrigger = NULL;
SetAbsVelocity( Vector( 0, 0, 0 ) );
SetGravity( 0 );
while( pTrigger = gEntList.FindEntityByName( pTrigger, m_szDeadUse, NULL ) )
{
CLogicRelay *pRelay = (CLogicRelay*)pTrigger;
pRelay->m_OnTrigger.FireOutput( this, this );
}
m_lifeState = LIFE_DEAD;
}
}
if ( IsSequenceFinished() )
{
QAngle qAngularVel = GetLocalAngularVelocity();
qAngularVel.y += random->RandomFloat( -100, 100 );
if ( qAngularVel.y < -100)
qAngularVel.y = -100;
if ( qAngularVel.y > 100)
qAngularVel.y = 100;
SetLocalAngularVelocity( qAngularVel );
SetSequence( LookupSequence( "die1" ) );
}
if ( m_pBall )
{
if (m_pBall->GetBrightness() > 0)
{
m_pBall->SetBrightness( max( 0, m_pBall->GetBrightness() - 7 ), 0 );
}
else
{
UTIL_Remove( m_pBall );
m_pBall = NULL;
}
}
Vector vecDir, vecSrc;
QAngle vecAngles;
Vector vForward, vRight, vUp;
AngleVectors( GetAbsAngles(), &vForward, &vRight, &vUp );
int iAttachment = random->RandomInt( 1, 4 );
do {
vecDir = Vector( random->RandomFloat( -1, 1 ), random->RandomFloat( -1, 1 ), random->RandomFloat( -1, 1 ) );
} while (DotProduct( vecDir, vecDir) > 1.0);
switch( random->RandomInt( 1, 4 ))
{
case 1: // head
vecDir.z = fabs( vecDir.z ) * 0.5;
vecDir = vecDir + 2 * vUp;
break;
case 2: // eyes
if (DotProduct( vecDir, vForward ) < 0)
vecDir = vecDir * -1;
vecDir = vecDir + 2 * vForward;
break;
case 3: // left hand
if (DotProduct( vecDir, vRight ) > 0)
vecDir = vecDir * -1;
vecDir = vecDir - 2 * vRight;
break;
case 4: // right hand
if (DotProduct( vecDir, vRight ) < 0)
vecDir = vecDir * -1;
vecDir = vecDir + 2 * vRight;
break;
}
GetAttachment( iAttachment, vecSrc, vecAngles );
trace_t tr;
UTIL_TraceLine( vecSrc, vecSrc + vecDir * 4096, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );
CBeam *pBeam = CBeam::BeamCreate( "sprites/laserbeam.vmt", 16 );
if ( pBeam == NULL )
return;
pBeam->PointEntInit( tr.endpos, this );
pBeam->SetEndAttachment( iAttachment );
pBeam->SetColor( 64, 128, 255 );
pBeam->SetFadeLength( 50 );
pBeam->SetBrightness( 255 );
pBeam->SetNoise( 12 );
pBeam->SetScrollRate( 1.0 );
pBeam->LiveForTime( 0.5 );
GetAttachment( 0, vecSrc, vecAngles );
CNihilanthHVR *pEntity = (CNihilanthHVR *)CREATE_ENTITY( CNihilanthHVR, "nihilanth_energy_ball" );
pEntity->SetAbsOrigin( vecSrc );
pEntity->SetAbsAngles( GetAbsAngles() );
pEntity->SetOwnerEntity( this );
pEntity->SetAbsVelocity( Vector ( random->RandomFloat( -0.7, 0.7 ), random->RandomFloat( -0.7, 0.7 ), 1.0 ) * 600.0 );
pEntity->Spawn();
pEntity->GreenBallInit();
return;
}
void CNPC_Nihilanth::HandleAnimEvent( animevent_t *pEvent )
{
switch( pEvent->event )
{
case 1: // shoot
break;
case 2: // zen
if ( GetEnemy() != NULL)
{
Vector vOrigin;
QAngle vAngle;
CPASAttenuationFilter filter( this );
if ( random->RandomInt(0,4) == 0)
enginesound->EmitSound( filter, entindex(), CHAN_VOICE, RANDOM_SOUND_ARRAY( pAttackSounds ), 1.0, 0.2 );
enginesound->EmitSound( filter, entindex(), CHAN_WEAPON, RANDOM_SOUND_ARRAY( pBallSounds ), 1.0, 0.2 );
GetAttachment( 2, vOrigin, vAngle);
CBroadcastRecipientFilter filterlight;
te->DynamicLight( filterlight, 0.0, &vOrigin, 128, 128, 255, 0, 256, 1.0f, 128 );
GetAttachment( 3, vOrigin, vAngle);
te->DynamicLight( filterlight, 0.0, &vOrigin, 128, 128, 255, 0, 256, 1.0f, 128 );
m_flShootTime = gpGlobals->curtime;
m_flShootEnd = gpGlobals->curtime + 1.0;
}
break;
case 3: // prayer
if (GetEnemy() != NULL)
{
char szText[32];
Q_snprintf( szText, sizeof( szText ), "%s%d", m_szTeleportTouch, m_iTeleport );
CBaseEntity *pTouch = gEntList.FindEntityByName( NULL, szText, NULL );
Q_snprintf( szText, sizeof( szText ), "%s%d", m_szTeleportUse, m_iTeleport );
CBaseEntity *pTrigger = gEntList.FindEntityByName( NULL, szText, NULL );
if (pTrigger != NULL || pTouch != NULL)
{
CPASAttenuationFilter filter( this );
enginesound->EmitSound( filter, entindex(), CHAN_VOICE, RANDOM_SOUND_ARRAY( pAttackSounds ), 1.0, 0.2 );
Vector vecSrc;
QAngle vecAngles;
GetAttachment( 2, vecSrc, vecAngles );
CNihilanthHVR *pEntity = (CNihilanthHVR *)CREATE_ENTITY( CNihilanthHVR, "nihilanth_energy_ball" );
pEntity->SetAbsOrigin( vecSrc );
pEntity->SetAbsAngles( vecAngles );
pEntity->SetOwnerEntity( this );
pEntity->Spawn();
pEntity->TeleportInit( this, GetEnemy(), pTrigger, pTouch );
pEntity->SetAbsVelocity( GetAbsOrigin() - vecSrc );
pEntity->SetAbsVelocity( Vector( GetAbsVelocity().x, GetAbsVelocity().y, GetAbsVelocity().z * 0.2 ) );
}
else
{
Vector vOrigin;
QAngle vAngle;
m_iTeleport++; // unexpected failure
CPASAttenuationFilter filter( this );
enginesound->EmitSound( filter, entindex(), CHAN_WEAPON, RANDOM_SOUND_ARRAY( pBallSounds ), 1.0, 0.2 );
Msg( "nihilanth can't target %s\n", szText );
GetAttachment( 2, vOrigin, vAngle);
CBroadcastRecipientFilter filterlight;
te->DynamicLight( filterlight, 0.0, &vOrigin, 128, 128, 255, 0, 256, 1.0f, 128 );
GetAttachment( 3, vOrigin, vAngle);
te->DynamicLight( filterlight, 0.0, &vOrigin, 128, 128, 255, 0, 256, 1.0f, 128 );
m_flShootTime = gpGlobals->curtime;
m_flShootEnd = gpGlobals->curtime + 1.0;
}
}
break;
case 4: // get a sphere
{
if (m_hRecharger != NULL)
{
if (!EmitSphere( ))
{
m_hRecharger = NULL;
}
}
}
break;
case 5: // start up sphere machine
{
CPASAttenuationFilter filter( this );
enginesound->EmitSound( filter, entindex(), CHAN_VOICE , RANDOM_SOUND_ARRAY( pRechargeSounds ), 1.0, 0.2 );
}
break;
case 6:
if ( GetEnemy() != NULL)
{
Vector vecSrc;
QAngle vecAngles;
GetAttachment( 3, vecSrc, vecAngles );
CNihilanthHVR *pEntity = (CNihilanthHVR *)CREATE_ENTITY( CNihilanthHVR, "nihilanth_energy_ball" );
pEntity->SetAbsOrigin( vecSrc );
pEntity->SetAbsAngles( vecAngles );
pEntity->SetOwnerEntity( this );
pEntity->Spawn();
pEntity->SetAbsVelocity( GetAbsOrigin() - vecSrc );
pEntity->ZapInit( GetEnemy() );
}
break;
case 7:
/*
Vector vecSrc, vecAngles;
GetAttachment( 0, vecSrc, vecAngles );
CNihilanthHVR *pEntity = (CNihilanthHVR *)Create( "nihilanth_energy_ball", vecSrc, pev->angles, edict() );
pEntity->pev->velocity = Vector ( RANDOM_FLOAT( -0.7, 0.7 ), RANDOM_FLOAT( -0.7, 0.7 ), 1.0 ) * 600.0;
pEntity->GreenBallInit( );
*/
break;
}
}
//=========================================================
// Controller bouncy ball attack
//=========================================================
void CNihilanthHVR::Spawn( void )
{
Precache( );
}
void CNihilanthHVR::Precache( void )
{
engine->PrecacheModel("sprites/flare6.vmt");
engine->PrecacheModel("sprites/nhth1.vmt");
engine->PrecacheModel("sprites/exit1.vmt");
engine->PrecacheModel("sprites/tele1.vmt");
engine->PrecacheModel("sprites/animglow01.vmt");
engine->PrecacheModel("sprites/xspark4.vmt");
engine->PrecacheModel("sprites/muzzleflash3.vmt");
enginesound->PrecacheSound("debris/zap4.wav");
enginesound->PrecacheSound("weapons/electro4.wav");
enginesound->PrecacheSound("x/x_teleattack1.wav");
engine->PrecacheModel("sprites/laserbeam.vmt");
}
void CNihilanthHVR::CircleInit( CBaseEntity *pTarget )
{
SetMoveType( MOVETYPE_FLY );
SetSolid( SOLID_NONE );
UTIL_SetSize( this, Vector( 0, 0, 0), Vector(0, 0, 0));
UTIL_SetOrigin( this, GetAbsOrigin() );
SetThink( &CNihilanthHVR::HoverThink );
SetTouch( &CNihilanthHVR::BounceTouch );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -