📄 hl1_npc_gargantua.cpp
字号:
PRECACHE_SOUND_ARRAY(pFootSounds);
PRECACHE_SOUND_ARRAY(pIdleSounds);
PRECACHE_SOUND_ARRAY(pAlertSounds);
PRECACHE_SOUND_ARRAY(pPainSounds);
PRECACHE_SOUND_ARRAY(pAttackSounds);
PRECACHE_SOUND_ARRAY(pStompSounds);
PRECACHE_SOUND_ARRAY(pBreatheSounds);
}
Class_T CNPC_Gargantua::Classify ( void )
{
return CLASS_ALIEN_MONSTER;
}
void CNPC_Gargantua :: PrescheduleThink( void )
{
if ( !HasCondition( COND_SEE_ENEMY ) )
{
m_seeTime = gpGlobals->curtime + 5;
EyeOff();
}
else
{
EyeOn( 200 );
}
EyeUpdate();
}
float CNPC_Gargantua::MaxYawSpeed ( void )
{
float ys = 60;
switch ( GetActivity() )
{
case ACT_IDLE:
ys = 60;
break;
case ACT_TURN_LEFT:
case ACT_TURN_RIGHT:
ys = 180;
break;
case ACT_WALK:
case ACT_RUN:
ys = 60;
break;
default:
ys = 60;
break;
}
return ys;
}
int CNPC_Gargantua::MeleeAttack1Conditions( float flDot, float flDist )
{
if (flDot >= 0.7)
{
if ( flDist <= GARG_ATTACKDIST )
{
return COND_CAN_MELEE_ATTACK1;
}
}
return COND_NONE;
}
// Flame thrower madness!
int CNPC_Gargantua::MeleeAttack2Conditions( float flDot, float flDist )
{
if ( gpGlobals->curtime > m_flameTime )
{
if ( flDot >= 0.8 )
{
if ( flDist > GARG_ATTACKDIST )
{
if ( flDist <= GARG_FLAME_LENGTH )
return COND_CAN_MELEE_ATTACK2;
}
}
}
return COND_NONE;
}
//=========================================================
// CheckRangeAttack1
// flDot is the cos of the angle of the cone within which
// the attack can occur.
//=========================================================
//
// Stomp attack
//
//=========================================================
int CNPC_Gargantua::RangeAttack1Conditions( float flDot, float flDist )
{
if ( gpGlobals->curtime > m_seeTime )
{
if ( flDot >= 0.7 )
{
if ( flDist > GARG_ATTACKDIST )
{
return COND_CAN_RANGE_ATTACK1;
}
}
}
return COND_NONE;
}
//=========================================================
// CheckTraceHullAttack - expects a length to trace, amount
// of damage to do, and damage type. Returns a pointer to
// the damaged entity in case the monster wishes to do
// other stuff to the victim (punchangle, etc)
// Used for many contact-range melee attacks. Bites, claws, etc.
// Overridden for Gargantua because his swing starts lower as
// a percentage of his height (otherwise he swings over the
// players head)
//=========================================================
CBaseEntity* CNPC_Gargantua::GargantuaCheckTraceHullAttack(float flDist, int iDamage, int iDmgType)
{
trace_t tr;
Vector vForward, vUp;
AngleVectors( GetAbsAngles(), &vForward, NULL, &vUp );
Vector vecStart = GetAbsOrigin();
vecStart.z += 64;
Vector vecEnd = vecStart + ( vForward * flDist) - ( vUp * flDist * 0.3);
//UTIL_TraceHull( vecStart, vecEnd, dont_ignore_monsters, head_hull, ENT(pev), &tr );
UTIL_TraceEntity( this, GetAbsOrigin(), vecEnd, MASK_SOLID, &tr );
if ( tr.m_pEnt )
{
CBaseEntity *pEntity = tr.m_pEnt;
if ( iDamage > 0 )
{
CTakeDamageInfo info( this, this, iDamage, iDmgType );
CalculateMeleeDamageForce( &info, vForward, tr.endpos );
pEntity->TakeDamage( info );
}
return pEntity;
}
return NULL;
}
void CNPC_Gargantua::HandleAnimEvent( animevent_t *pEvent )
{
CPASAttenuationFilter filter( this );
switch( pEvent->event )
{
case GARG_AE_SLASH_LEFT:
{
// HACKHACK!!!
CBaseEntity *pHurt = GargantuaCheckTraceHullAttack( GARG_ATTACKDIST + 10.0, sk_gargantua_dmg_slash.GetFloat(), DMG_SLASH );
if (pHurt)
{
if ( pHurt->GetFlags() & ( FL_NPC | FL_CLIENT ) )
{
pHurt->ViewPunch( QAngle( -30, -30, 30 ) );
Vector vRight;
AngleVectors( GetAbsAngles(), NULL, &vRight, NULL );
pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() - vRight * 100 );
}
enginesound->EmitSound( filter, entindex(), CHAN_WEAPON, pAttackHitSounds[ random->RandomInt(0,ARRAYSIZE(pAttackHitSounds)-1) ], 1.0, ATTN_NORM, 0, 50 + random->RandomInt(0,15) );
}
else // Play a random attack miss sound
enginesound->EmitSound( filter, entindex(), CHAN_WEAPON, pAttackMissSounds[ random->RandomInt(0,ARRAYSIZE(pAttackMissSounds)-1) ], 1.0, ATTN_NORM, 0, 50 + random->RandomInt(0,15) );
}
break;
case GARG_AE_RIGHT_FOOT:
case GARG_AE_LEFT_FOOT:
UTIL_ScreenShake( GetAbsOrigin(), 4.0, 3.0, 1.0, 1500, SHAKE_START );
enginesound->EmitSound( filter, entindex(), CHAN_BODY, pFootSounds[ random->RandomInt(0,ARRAYSIZE(pFootSounds)-1) ], 1.0, ATTN_GARG, 0, PITCH_NORM + random->RandomInt(-10,10) );
break;
case GARG_AE_STOMP:
StompAttack();
m_seeTime = gpGlobals->curtime + 12;
break;
case GARG_AE_BREATHE:
enginesound->EmitSound( filter, entindex(), CHAN_VOICE, pBreatheSounds[ random->RandomInt(0,ARRAYSIZE(pBreatheSounds)-1) ], 1.0, ATTN_GARG, 0, PITCH_NORM + random->RandomInt(-10,10) );
break;
default:
BaseClass::HandleAnimEvent(pEvent);
break;
}
}
int CNPC_Gargantua::TranslateSchedule( int scheduleType )
{
//TEMP TEMP
if ( FlameIsOn() )
FlameDestroy();
switch( scheduleType )
{
case SCHED_MELEE_ATTACK2:
return SCHED_GARG_FLAME;
case SCHED_MELEE_ATTACK1:
return SCHED_GARG_SWIPE;
case SCHED_CHASE_ENEMY_FAILED:
case SCHED_ALERT_STAND:
return SCHED_CHASE_ENEMY;
break;
}
return BaseClass::TranslateSchedule( scheduleType );
}
void CNPC_Gargantua::StartTask( const Task_t *pTask )
{
switch ( pTask->iTask )
{
case TASK_FLAME_SWEEP:
//TEMP TEMP
FlameCreate();
m_flWaitFinished = gpGlobals->curtime + pTask->flTaskData;
m_flameTime = gpGlobals->curtime + 6;
m_flameX = 0;
m_flameY = 0;
break;
case TASK_SOUND_ATTACK:
if ( random->RandomInt(0,100) < 30 )
{
CPASAttenuationFilter filter( this );
enginesound->EmitSound( filter, entindex(), CHAN_VOICE, pAttackSounds[ random->RandomInt(0,ARRAYSIZE(pAttackSounds)-1) ], 1.0, ATTN_GARG, 0, PITCH_NORM );
}
TaskComplete();
break;
case TASK_DIE:
m_flWaitFinished = gpGlobals->curtime + 1.6;
DeathEffect();
// FALL THROUGH
default:
BaseClass::StartTask( pTask );
break;
}
}
bool CNPC_Gargantua::ShouldGib( const CTakeDamageInfo &info )
{
return false;
}
//=========================================================
// RunTask
//=========================================================
void CNPC_Gargantua::RunTask( const Task_t *pTask )
{
switch ( pTask->iTask )
{
case TASK_DIE:
if ( gpGlobals->curtime > m_flWaitFinished )
{
//TEMP TEMP
m_nRenderFX = kRenderFxExplode;
SetRenderColor( 255, 0, 0 , 255 );
StopAnimation();
SetNextThink( gpGlobals->curtime + 0.15 );
SetThink( SUB_Remove );
int i;
int parts = modelinfo->GetModelFrameCount( modelinfo->GetModel( gGargGibModel ) );
for ( i = 0; i < 10; i++ )
{
CGib *pGib = CREATE_ENTITY( CGib, "gib" );
pGib->Spawn( GARG_GIB_MODEL);
int bodyPart = 0;
if ( parts > 1 )
bodyPart = random->RandomInt( 0, parts-1 );
pGib->SetBodygroup( 0, bodyPart );
pGib->SetBloodColor( BLOOD_COLOR_YELLOW );
pGib->m_material = matNone;
pGib->SetAbsOrigin( GetAbsOrigin() );
pGib->SetAbsVelocity( UTIL_RandomBloodVector() * random->RandomFloat( 300, 500 ) );
pGib->SetNextThink( gpGlobals->curtime + 1.25 );
pGib->SetThink( SUB_FadeOut );
pGib->m_flModelScale = 10;
}
Vector vecSize = Vector( 200, 200, 128 );
CPVSFilter filter( GetAbsOrigin() );
te->BreakModel( filter, 0.0, &GetAbsOrigin(), &vecSize, &vec3_origin, gGargGibModel, 200, 50, 3.0, BREAK_FLESH );
return;
}
else
BaseClass::RunTask( pTask );
break;
case TASK_FLAME_SWEEP:
if ( gpGlobals->curtime > m_flWaitFinished )
{
//TEMP TEMP
FlameDestroy();
TaskComplete();
FlameControls( 0, 0 );
SetBoneController( 0, 0 );
SetBoneController( 1, 0 );
}
else
{
bool cancel = false;
QAngle angles = QAngle( 0, 0, 0 );
//TEMP TEMP
FlameUpdate();
CBaseEntity *pEnemy = GetEnemy();
if ( pEnemy )
{
Vector org = GetAbsOrigin();
org.z += 64;
Vector dir = pEnemy->BodyTarget(org) - org;
VectorAngles( dir, angles );
angles.x = -angles.x;
angles.y -= GetAbsAngles().y;
if ( dir.Length() > 400 )
cancel = true;
}
if ( fabs(angles.y) > 60 )
cancel = true;
if ( cancel )
{
m_flWaitFinished -= 0.5;
m_flameTime -= 0.5;
}
//TEMP TEMP
//FlameControls( angles.x + 2 * sin(gpGlobals->curtime*8), angles.y + 28 * sin(gpGlobals->curtime*8.5) );
FlameControls( angles.x, angles.y );
}
break;
default:
BaseClass::RunTask( pTask );
break;
}
}
void CNPC_Gargantua::FlameCreate( void )
{
int i;
Vector posGun;
QAngle angleGun;
trace_t trace;
Vector vForward;
AngleVectors( GetAbsAngles(), &vForward );
for ( i = 0; i < 4; i++ )
{
if ( i < 2 )
m_pFlame[i] = CBeam::BeamCreate( GARG_BEAM_SPRITE_NAME, 24.0 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -