📄 hl1_npc_nihilanth.cpp
字号:
SetNextThink( gpGlobals->curtime + 0.1 );
CSprite *pSprite = SpriteInit( "sprites/muzzleflash3.vmt", this );
if ( pSprite )
{
m_flBallScale = 2.0f;
pSprite->SetScale( 2.0 );
pSprite->SetTransparency( kRenderTransAdd, 255, 224, 192, 255, kRenderFxNone );
}
SetTarget( pTarget );
}
CSprite *CNihilanthHVR::SpriteInit( const char *pSpriteName, CNihilanthHVR *pOwner )
{
pOwner->SetSprite( CSprite::SpriteCreate( pSpriteName, pOwner->GetAbsOrigin(), true ) );
CSprite *pSprite = (CSprite*)pOwner->GetSprite();
if ( pSprite )
{
pSprite->SetAttachment( pOwner, 0 );
pSprite->SetOwnerEntity( pOwner );
pSprite->AnimateForTime( 5, 9999 );
pSprite->Relink();
}
return pSprite;
}
void CNihilanthHVR::HoverThink( void )
{
SetNextThink( gpGlobals->curtime + 0.1 );
if ( GetTarget() != NULL )
{
CircleTarget( GetTarget()->GetAbsOrigin() + Vector( 0, 0, 16 * N_SCALE ) );
}
else
{
UTIL_Remove( GetSprite() );
UTIL_Remove( this );
}
}
void CNihilanthHVR::BounceTouch( CBaseEntity *pOther )
{
Vector vecDir = m_vecIdeal;
VectorNormalize( vecDir );
trace_t tr = GetTouchTrace();
float n = -DotProduct(tr.plane.normal, vecDir);
vecDir = 2.0 * tr.plane.normal * n + vecDir;
m_vecIdeal = vecDir * m_vecIdeal.Length();
}
bool CNihilanthHVR::CircleTarget( Vector vecTarget )
{
bool fClose = false;
vecTarget = vecTarget + Vector( 0, 0, 64 );
Vector vecDest = vecTarget;
Vector vecEst = GetAbsOrigin() + GetAbsVelocity() * 0.5;
Vector vecSrc = GetAbsOrigin();
vecDest.z = 0;
vecEst.z = 0;
vecSrc.z = 0;
float d1 = (vecDest - vecSrc).Length() - 24 * N_SCALE;
float d2 = (vecDest - vecEst).Length() - 24 * N_SCALE;
if ( m_vecIdeal == vec3_origin )
{
m_vecIdeal = GetAbsVelocity();
}
if (d1 < 0 && d2 <= d1)
{
// ALERT( at_console, "too close\n");
Vector vTemp = (vecDest - vecSrc);
VectorNormalize( vTemp );
m_vecIdeal = m_vecIdeal - vTemp * 50;
}
else if (d1 > 0 && d2 >= d1)
{
Vector vTemp = (vecDest - vecSrc);
VectorNormalize( vTemp );
m_vecIdeal = m_vecIdeal + vTemp * 50;
}
SetLocalAngularVelocity( QAngle( GetLocalAngularVelocity().x, GetLocalAngularVelocity().y, d1 * 20 ) );
if (d1 < 32)
{
fClose = true;
}
m_vecIdeal = m_vecIdeal + Vector( random->RandomFloat( -2, 2 ), random->RandomFloat( -2, 2 ), random->RandomFloat( -2, 2 ));
float flIdealZ = m_vecIdeal.z;
m_vecIdeal = Vector( m_vecIdeal.x, m_vecIdeal.y, 0 );
VectorNormalize( m_vecIdeal );
m_vecIdeal = (m_vecIdeal * 200) + Vector( 0, 0, flIdealZ );
// move up/down
d1 = vecTarget.z - GetAbsOrigin().z;
if (d1 > 0 && m_vecIdeal.z < 200)
m_vecIdeal.z += 20;
else if (d1 < 0 && m_vecIdeal.z > -200)
m_vecIdeal.z -= 20;
SetAbsVelocity( m_vecIdeal );
// ALERT( at_console, "%.0f %.0f %.0f\n", m_vecIdeal.x, m_vecIdeal.y, m_vecIdeal.z );
return fClose;
}
void CNihilanthHVR::ZapInit( CBaseEntity *pEnemy )
{
SetMoveType( MOVETYPE_FLY );
SetSolid( SOLID_BBOX );
CSprite *pSprite = SpriteInit( "sprites/nhth1.vmt", this );
if ( pSprite )
{
m_flBallScale = 2.0f;
pSprite->SetScale( 2.0 );
pSprite->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxNone );
}
Vector vVelocity = pEnemy->GetAbsOrigin() - GetAbsOrigin();
VectorNormalize( vVelocity );
SetAbsVelocity ( vVelocity * 300 );
SetEnemy( pEnemy );
SetThink( &CNihilanthHVR::ZapThink );
SetTouch( &CNihilanthHVR::ZapTouch );
SetNextThink( gpGlobals->curtime + 0.1 );
CPASAttenuationFilter filter( this );
enginesound->EmitSound( filter, entindex(), CHAN_WEAPON, "debris/zap4.wav", 1, ATTN_NORM, 0, 100 );
}
void CNihilanthHVR :: ZapThink( void )
{
SetNextThink( gpGlobals->curtime + 0.05 );
// check world boundaries
if ( GetEnemy() == NULL || GetAbsOrigin().x < -4096 || GetAbsOrigin().x > 4096 || GetAbsOrigin().y < -4096 || GetAbsOrigin().y > 4096 || GetAbsOrigin().z < -4096 || GetAbsOrigin().z > 4096)
{
SetTouch( NULL );
UTIL_Remove( GetSprite() );
UTIL_Remove( this );
return;
}
if ( GetAbsVelocity().Length() < 2000)
{
SetAbsVelocity( GetAbsVelocity() * 1.2 );
}
if (( GetEnemy()->WorldSpaceCenter() - GetAbsOrigin()).Length() < 256)
{
trace_t tr;
UTIL_TraceLine( GetAbsOrigin(), GetEnemy()->WorldSpaceCenter(), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );
CBaseEntity *pEntity = tr.m_pEnt;
if (pEntity != NULL && pEntity->m_takedamage )
{
ClearMultiDamage( );
CTakeDamageInfo info( this, this, sk_nihilanth_zap.GetFloat(), DMG_SHOCK );
CalculateMeleeDamageForce( &info, (tr.endpos - tr.startpos), tr.endpos );
pEntity->DispatchTraceAttack( info, GetAbsVelocity(), &tr );
ApplyMultiDamage();
}
CBeam *pBeam = CBeam::BeamCreate( "sprites/laserbeam.vmt", 2.0f );
if ( pBeam == NULL )
return;
pBeam->PointEntInit( tr.endpos, this );
pBeam->SetColor( 64, 196, 255 );
pBeam->SetBrightness( 255 );
pBeam->SetNoise( 7.2 );
pBeam->SetScrollRate( 10 );
pBeam->LiveForTime( 0.1 );
UTIL_EmitAmbientSound( this, tr.endpos, "weapons/electro4.wav", 0.5, SNDLVL_NORM, 0, random->RandomInt( 140, 160 ) );
SetTouch( NULL );
GetSprite()->SetThink( SUB_Remove );
SetThink( SUB_Remove );
SetNextThink( gpGlobals->curtime + 0.2 );
GetSprite()->SetNextThink( gpGlobals->curtime + 0.2 );
return;
}
CBroadcastRecipientFilter filterlight;
te->DynamicLight( filterlight, 0.0, &GetAbsOrigin(), 128, 128, 255, 0, 128, 10, 128 );
}
void CNihilanthHVR::ZapTouch( CBaseEntity *pOther )
{
UTIL_EmitAmbientSound( this, GetAbsOrigin(), "weapons/electro4.wav", 1.0, SNDLVL_NORM, 0, random->RandomInt( 90, 95 ) );
RadiusDamage( CTakeDamageInfo( this, this, 50, DMG_SHOCK ), GetAbsOrigin(), 125, CLASS_NONE );
SetAbsVelocity( GetAbsVelocity() * 0 );
SetTouch( NULL );
UTIL_Remove( GetSprite() );
UTIL_Remove( this );
SetNextThink( gpGlobals->curtime + 0.2 );
}
void CNihilanthHVR::AbsorbInit( void )
{
CBroadcastRecipientFilter filter;
SetThink( &CNihilanthHVR::DissipateThink );
SetRenderColorA( 255 );
SetBeam( CBeam::BeamCreate( "sprites/laserbeam.vmt", 8.0f ) );
CBeam *pBeam = (CBeam*)GetBeam();
if ( pBeam == NULL )
return;
pBeam->EntsInit( this, GetTarget() );
pBeam->SetEndAttachment( 1 );
pBeam->SetColor( 255, 128, 64 );
pBeam->SetBrightness( 255 );
pBeam->SetNoise( 18 );
}
void CNihilanthHVR::DissipateThink( void )
{
CSprite *pSprite = (CSprite*)GetSprite();
SetNextThink ( gpGlobals->curtime + 0.1 );
if ( m_flBallScale > 5.0)
{
UTIL_Remove( this );
UTIL_Remove( GetSprite() );
UTIL_Remove( GetBeam() );
}
pSprite->SetBrightness( pSprite->GetBrightness() - 7, 0 );
m_flBallScale += 0.1;
pSprite->SetScale( m_flBallScale );
if ( GetTarget() != NULL)
{
CircleTarget( GetTarget()->GetAbsOrigin() + Vector( 0, 0, 4096 ) );
}
else
{
UTIL_Remove( this );
UTIL_Remove( GetSprite() );
UTIL_Remove( GetBeam() );
}
/* MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
WRITE_BYTE( TE_ELIGHT );
WRITE_SHORT( entindex( ) ); // entity, attachment
WRITE_COORD( pev->origin.x ); // origin
WRITE_COORD( pev->origin.y );
WRITE_COORD( pev->origin.z );
WRITE_COORD( pev->renderamt ); // radius
WRITE_BYTE( 255 ); // R
WRITE_BYTE( 192 ); // G
WRITE_BYTE( 64 ); // B
WRITE_BYTE( 2 ); // life * 10
WRITE_COORD( 0 ); // decay
MESSAGE_END();*/
}
void CNihilanthHVR::TeleportInit( CNPC_Nihilanth *pOwner, CBaseEntity *pEnemy, CBaseEntity *pTarget, CBaseEntity *pTouch )
{
SetMoveType( MOVETYPE_FLY );
SetSolid( SOLID_BBOX );
SetModel( "" );
CSprite *pSprite = SpriteInit( "sprites/exit1.vmt", this );
if ( pSprite )
{
m_flBallScale = 2.0f;
pSprite->SetScale( 2.0 );
pSprite->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxNone );
}
m_pNihilanth = pOwner;
SetEnemy( pEnemy );
SetTarget( pTarget );
m_hTouch = pTouch;
SetThink( &CNihilanthHVR::TeleportThink );
SetTouch( &CNihilanthHVR::TeleportTouch );
SetNextThink( gpGlobals->curtime + 0.1 );
CPASAttenuationFilter filter( this );
enginesound->EmitSound( filter, entindex(), CHAN_WEAPON, "x/x_teleattack1.wav", 1.0, 0.2 );
}
void CNihilanthHVR::MovetoTarget( Vector vecTarget )
{
if ( m_vecIdeal == vec3_origin )
{
m_vecIdeal = GetAbsVelocity();
}
// accelerate
float flSpeed = m_vecIdeal.Length();
if (flSpeed > 300)
{
VectorNormalize( m_vecIdeal );
m_vecIdeal= m_vecIdeal * 300;
}
Vector vTemp = vecTarget - GetAbsOrigin();
VectorNormalize( vTemp );
m_vecIdeal = m_vecIdeal + vTemp * 300;
SetAbsVelocity( m_vecIdeal );
}
void CNihilanthHVR::TeleportThink( void )
{
SetNextThink( gpGlobals->curtime + 0.1 );
// check world boundaries
if ( GetEnemy() == NULL || !GetEnemy()->IsAlive() || GetAbsOrigin().x < -4096 || GetAbsOrigin().x > 4096 || GetAbsOrigin().y < -4096 || GetAbsOrigin().y > 4096 || GetAbsOrigin().z < -4096 || GetAbsOrigin().z > 4096)
{
StopSound( entindex(), CHAN_WEAPON, "x/x_teleattack1.wav" );
UTIL_Remove( this );
UTIL_Remove( GetSprite() );
return;
}
if (( GetEnemy()->WorldSpaceCenter() - GetAbsOrigin() ).Length() < 128)
{
StopSound( entindex(), CHAN_WEAPON, "x/x_teleattack1.wav" );
UTIL_Remove( this );
UTIL_Remove( GetSprite() );
if ( GetTarget() != NULL)
{
CLogicRelay *pRelay = (CLogicRelay*)GetTarget();
pRelay->m_OnTrigger.FireOutput( this, this );
}
if ( m_hTouch != NULL && GetEnemy() != NULL )
m_hTouch->Touch( GetEnemy() );
}
else
{
MovetoTarget( GetEnemy()->WorldSpaceCenter( ) );
}
CBroadcastRecipientFilter filterlight;
te->DynamicLight( filterlight, 0.0, &GetAbsOrigin(), 0, 255, 0, 0, 256, 1.0, 256 );
}
void CNihilanthHVR::TeleportTouch( CBaseEntity *pOther )
{
CBaseEntity *pEnemy = GetEnemy();
if (pOther == pEnemy)
{
if (GetTarget() != NULL)
{
if ( GetTarget() != NULL)
{
CLogicRelay *pRelay = (CLogicRelay*)GetTarget();
pRelay->m_OnTrigger.FireOutput( this, this );
}
}
if (m_hTouch != NULL && pEnemy != NULL )
m_hTouch->Touch( pEnemy );
}
else
{
m_pNihilanth->MakeFriend( GetAbsOrigin() );
}
SetTouch( NULL );
StopSound( entindex(), CHAN_WEAPON, "x/x_teleattack1.wav" );
UTIL_Remove( this );
UTIL_Remove( GetSprite() );
}
void CNihilanthHVR :: GreenBallInit( )
{
SetMoveType( MOVETYPE_FLY );
SetSolid( SOLID_BBOX );
SetModel( "" );
CSprite *pSprite = SpriteInit( "sprites/exit1.spr", this );
if ( pSprite )
{
pSprite->SetScale( 1.0 );
pSprite->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxNone );
}
SetTouch( &CNihilanthHVR::RemoveTouch );
}
void CNihilanthHVR::RemoveTouch( CBaseEntity *pOther )
{
StopSound( entindex(), CHAN_WEAPON, "x/x_teleattack1.wav" );
UTIL_Remove( this );
UTIL_Remove( GetSprite() );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -