⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hl1_npc_nihilanth.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#include	"cbase.h"
#include	"AI_Default.h"
#include	"AI_Task.h"
#include	"AI_Schedule.h"
#include	"AI_Node.h"
#include	"AI_Hull.h"
#include	"AI_Hint.h"
#include	"AI_Route.h"
#include	"soundent.h"
#include	"game.h"
#include	"NPCEvent.h"
#include	"EntityList.h"
#include	"activitylist.h"
#include	"animation.h"
#include	"basecombatweapon.h"
#include	"IEffects.h"
#include	"vstdlib/random.h"
#include	"engine/IEngineSound.h"
#include	"ammodef.h"
#include	"Sprite.h"
#include	"hl1_ai_basenpc.h"
#include	"ai_senses.h"
#include	"Sprite.h"
#include	"beam_shared.h"
#include	"logicrelay.h"
#include	"AI_Navigator.h"


#define N_SCALE		15
#define N_SPHERES	20

ConVar sk_nihilanth_health( "sk_nihilanth_health", "800" );
ConVar sk_nihilanth_zap( "sk_nihilanth_zap", "30" );

class CNPC_Nihilanth : public CHL1BaseNPC
{
	DECLARE_CLASS( CNPC_Nihilanth, CHL1BaseNPC );
public:
	void Spawn( void );
	void Precache( void );

	Class_T Classify( void ) { return CLASS_ALIEN_MILITARY; };

	void SetObjectCollisionBox( void )
	{
		SetAbsMins( GetAbsOrigin() + Vector( -16 * N_SCALE, -16 * N_SCALE, -48 * N_SCALE ) );
		SetAbsMaxs( GetAbsOrigin() + Vector( 16 * N_SCALE, 16 * N_SCALE, 28 * N_SCALE ) );
	}

	/*	void Killed( entvars_t *pevAttacker, int iGib );
	void GibMonster( void );

	void TargetSphere( USE_TYPE useType, float value );
	CBaseEntity *RandomTargetname( const char *szName );
	void MakeFriend( Vector vecPos );
	
	int  TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType );
	void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType);
	

	// x_teleattack1.wav	the looping sound of the teleport attack ball.*/

	int	OnTakeDamage_Alive( const CTakeDamageInfo &info );
	void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr );

	void PainSound( void );
	void DeathSound( void );
	
	void StartupThink( void );
	void NullThink( void );

	void HuntThink( void );
	void DyingThink( void );

	void Flight( void );
	void NextActivity( void );
	void FloatSequence( void );
	void HandleAnimEvent( animevent_t *pEvent );
	bool EmitSphere( void );

	void ShootBalls( void );
	bool AbsorbSphere( void );

	void MakeFriend( Vector vecStart );

	static const char *pAttackSounds[];	// vocalization: play sometimes when he launches an attack
	static const char *pBallSounds[];	// the sound of the lightening ball launch
	static const char *pShootSounds[];	// grunting vocalization: play sometimes when he launches an attack
	static const char *pRechargeSounds[];	// vocalization: play when he recharges
	static const char *pLaughSounds[];	// vocalization: play sometimes when hit and still has lots of health
	static const char *pPainSounds[];	// vocalization: play sometimes when hit and has much less health and no more chargers
	static const char *pDeathSounds[];	// vocalization: play as he dies

	void InputTurnBabyOn( inputdata_t &inputdata );
	void InputTurnBabyOff( inputdata_t &inputdata );

	float m_flForce;

	float m_flNextPainSound;

	Vector m_velocity;
	Vector m_avelocity;

	Vector m_vecTarget;
	Vector m_posTarget;

	Vector m_vecDesired;
	Vector m_posDesired;

	float  m_flMinZ;
	float  m_flMaxZ;

	Vector m_vecGoal;

	float m_flLastSeen;
	float m_flPrevSeen;

	int m_irritation;

	int m_iLevel;
	int m_iTeleport;

	EHANDLE m_hRecharger;

	EHANDLE m_hSphere[N_SPHERES];
	int	m_iActiveSpheres;

	float m_flAdj;

	CSprite *m_pBall;

	char m_szRechargerTarget[64];
	char m_szDrawUse[64];
	char m_szTeleportUse[64];
	char m_szTeleportTouch[64];
	char m_szDeadUse[64];
	char m_szDeadTouch[64];

	float m_flShootEnd;
	float m_flShootTime;

	EHANDLE m_hFriend[3];

	DECLARE_DATADESC();
};

LINK_ENTITY_TO_CLASS( monster_nihilanth, CNPC_Nihilanth );

BEGIN_DATADESC( CNPC_Nihilanth )
	DEFINE_FIELD( CNPC_Nihilanth, m_flForce, FIELD_FLOAT ),
	DEFINE_FIELD( CNPC_Nihilanth, m_flNextPainSound, FIELD_TIME ),
	DEFINE_FIELD( CNPC_Nihilanth, m_velocity, FIELD_VECTOR ),
	DEFINE_FIELD( CNPC_Nihilanth, m_avelocity, FIELD_VECTOR ),
	DEFINE_FIELD( CNPC_Nihilanth, m_vecTarget, FIELD_VECTOR ),
	DEFINE_FIELD( CNPC_Nihilanth, m_posTarget, FIELD_POSITION_VECTOR ),
	DEFINE_FIELD( CNPC_Nihilanth, m_vecDesired, FIELD_VECTOR ),
	DEFINE_FIELD( CNPC_Nihilanth, m_posDesired, FIELD_POSITION_VECTOR ),
	DEFINE_FIELD( CNPC_Nihilanth, m_flMinZ, FIELD_FLOAT ),
	DEFINE_FIELD( CNPC_Nihilanth, m_flMaxZ, FIELD_FLOAT ),
	DEFINE_FIELD( CNPC_Nihilanth, m_vecGoal, FIELD_VECTOR ),
	DEFINE_FIELD( CNPC_Nihilanth, m_flLastSeen, FIELD_TIME ),
	DEFINE_FIELD( CNPC_Nihilanth, m_flPrevSeen, FIELD_TIME ),
	DEFINE_FIELD( CNPC_Nihilanth, m_irritation, FIELD_INTEGER ),
	DEFINE_FIELD( CNPC_Nihilanth, m_iLevel, FIELD_INTEGER ),
	DEFINE_FIELD( CNPC_Nihilanth, m_iTeleport, FIELD_INTEGER ),
	DEFINE_FIELD( CNPC_Nihilanth, m_hRecharger, FIELD_EHANDLE ),
	DEFINE_ARRAY( CNPC_Nihilanth, m_hSphere, FIELD_EHANDLE, N_SPHERES ),
	DEFINE_FIELD( CNPC_Nihilanth, m_iActiveSpheres, FIELD_INTEGER ),
	DEFINE_FIELD( CNPC_Nihilanth, m_flAdj, FIELD_FLOAT ),
	DEFINE_FIELD( CNPC_Nihilanth, m_pBall, FIELD_CLASSPTR ),
	DEFINE_ARRAY( CNPC_Nihilanth, m_szRechargerTarget, FIELD_CHARACTER, 64 ),
	DEFINE_ARRAY( CNPC_Nihilanth, m_szDrawUse, FIELD_CHARACTER, 64 ),
	DEFINE_ARRAY( CNPC_Nihilanth, m_szTeleportUse, FIELD_CHARACTER, 64 ),
	DEFINE_ARRAY( CNPC_Nihilanth, m_szTeleportTouch, FIELD_CHARACTER, 64 ),
	DEFINE_ARRAY( CNPC_Nihilanth, m_szDeadUse, FIELD_CHARACTER, 64 ),
	DEFINE_ARRAY( CNPC_Nihilanth, m_szDeadTouch, FIELD_CHARACTER, 64 ),
	DEFINE_FIELD( CNPC_Nihilanth, m_flShootEnd, FIELD_TIME ),
	DEFINE_FIELD( CNPC_Nihilanth, m_flShootTime, FIELD_TIME ),
	DEFINE_ARRAY( CNPC_Nihilanth, m_hFriend, FIELD_EHANDLE, 3 ),
	DEFINE_THINKFUNC( CNPC_Nihilanth, NullThink ),
	DEFINE_THINKFUNC( CNPC_Nihilanth, StartupThink ),
	DEFINE_THINKFUNC( CNPC_Nihilanth, HuntThink ),
	DEFINE_THINKFUNC( CNPC_Nihilanth, DyingThink ),

	DEFINE_INPUTFUNC( CNPC_Nihilanth, FIELD_VOID, "TurnBabyOn", InputTurnBabyOn ),
	DEFINE_INPUTFUNC( CNPC_Nihilanth, FIELD_VOID, "TurnBabyOff", InputTurnBabyOff ),

END_DATADESC()

class CNihilanthHVR : public CAI_BaseNPC
{
	DECLARE_CLASS( CNihilanthHVR, CBaseEntity );
public:
	void Spawn( void );
	void Precache( void );

	void CircleInit( CBaseEntity *pTarget );
	void AbsorbInit( void );
	void GreenBallInit( void );
	

	void RemoveTouch( CBaseEntity *pOther );
	
	/*void Zap( void );
	void Teleport( void );*/
	
	void HoverThink( void );
	bool CircleTarget( Vector vecTarget );
	void BounceTouch( CBaseEntity *pOther );

	void ZapThink( void );
	void ZapInit( CBaseEntity *pEnemy );
	void ZapTouch( CBaseEntity *pOther );

	void TeleportThink( void );
	void TeleportTouch( CBaseEntity *pOther );

	void MovetoTarget( Vector vecTarget );

	void DissipateThink( void );

	CSprite *SpriteInit( const char *pSpriteName, CNihilanthHVR *pOwner );

	void TeleportInit( CNPC_Nihilanth *pOwner, CBaseEntity *pEnemy, CBaseEntity *pTarget, CBaseEntity *pTouch );

	float m_flIdealVel;
	Vector m_vecIdeal;
	CNPC_Nihilanth *m_pNihilanth;
	EHANDLE m_hTouch;
	
	
	float m_flBallScale;

	void SetSprite( CBaseEntity *pSprite )
	{
		m_hSprite = pSprite;	
	}

	CBaseEntity *GetSprite( void )
	{
		return m_hSprite.Get();
	}

	void SetBeam( CBaseEntity *pBeam )
	{
		m_hBeam = pBeam;	
	}

	CBaseEntity *GetBeam( void )
	{
		return m_hBeam.Get();
	}

private:
		
	EHANDLE m_hSprite;
	EHANDLE m_hBeam;


	DECLARE_DATADESC();
};

LINK_ENTITY_TO_CLASS( nihilanth_energy_ball, CNihilanthHVR );


BEGIN_DATADESC( CNihilanthHVR )
	DEFINE_FIELD( CNihilanthHVR, m_flIdealVel, FIELD_FLOAT ),
	DEFINE_FIELD( CNihilanthHVR, m_flBallScale, FIELD_FLOAT ),
	DEFINE_FIELD( CNihilanthHVR, m_vecIdeal, FIELD_VECTOR ),
	DEFINE_FIELD( CNihilanthHVR, m_pNihilanth, FIELD_CLASSPTR ),
	DEFINE_FIELD( CNihilanthHVR, m_hTouch, FIELD_EHANDLE ),
	DEFINE_FIELD( CNihilanthHVR, m_hSprite, FIELD_EHANDLE ),
	DEFINE_THINKFUNC( CNihilanthHVR, HoverThink ),
	DEFINE_ENTITYFUNC( CNihilanthHVR, BounceTouch ),
	DEFINE_THINKFUNC( CNihilanthHVR, ZapThink ),
	DEFINE_ENTITYFUNC( CNihilanthHVR, ZapTouch ),
	DEFINE_THINKFUNC( CNihilanthHVR, DissipateThink ),
	DEFINE_THINKFUNC( CNihilanthHVR, TeleportThink ),
	DEFINE_ENTITYFUNC( CNihilanthHVR, TeleportTouch ),
	DEFINE_ENTITYFUNC( CNihilanthHVR, RemoveTouch ),
END_DATADESC()


//=========================================================
// Nihilanth, final Boss monster
//=========================================================

const char *CNPC_Nihilanth::pAttackSounds[] = 
{
	"X/x_attack1.wav",
	"X/x_attack2.wav",
	"X/x_attack3.wav",
};

const char *CNPC_Nihilanth::pBallSounds[] = 
{
	"X/x_ballattack1.wav",
};

const char *CNPC_Nihilanth::pShootSounds[] = 
{
	"X/x_shoot1.wav",
};

const char *CNPC_Nihilanth::pRechargeSounds[] = 
{
	"X/x_recharge1.wav",
	"X/x_recharge2.wav",
	"X/x_recharge3.wav",
};

const char *CNPC_Nihilanth::pLaughSounds[] = 
{
	"X/x_laugh1.wav",
	"X/x_laugh2.wav",
};

const char *CNPC_Nihilanth::pPainSounds[] = 
{
	"X/x_pain1.wav",
	"X/x_pain2.wav",
};

const char *CNPC_Nihilanth::pDeathSounds[] = 
{
	"X/x_die1.wav",
};


void CNPC_Nihilanth::Spawn( void )
{
	Precache( );
	// motor
	SetMoveType( MOVETYPE_FLY );
	SetSolid( SOLID_BBOX );

	SetModel( "models/nihilanth.mdl" );
	//UTIL_SetSize( this, Vector( -300, -300, 0), Vector(300, 300, 512));
	//UTIL_SetSize(this, Vector( -32, -32, 0), Vector(32, 32, 64 ));

	UTIL_SetSize(this, Vector( -16 * N_SCALE, -16 * N_SCALE, -48 * N_SCALE ), Vector( 16 * N_SCALE, 16 * N_SCALE, 28 * N_SCALE ) );
	
	UTIL_SetOrigin( this, GetAbsOrigin() - Vector( 0, 0, 64 ) );

	AddFlag( FL_NPC );
	m_takedamage		= DAMAGE_AIM;
	m_iHealth			= sk_nihilanth_health.GetFloat();
	SetViewOffset ( Vector( 0, 0, 300 ) );

	m_flFieldOfView = -1; // 360 degrees

	SetSequence( 0 );
	ResetSequenceInfo( );

	InitBoneControllers();

	SetThink( &CNPC_Nihilanth::StartupThink );
	SetNextThink( gpGlobals->curtime + 0.1 );

	m_vecDesired = Vector( 1, 0, 0 );
	m_posDesired = Vector( GetAbsOrigin().x, GetAbsOrigin().y, 512 );

	m_iLevel = 1; 
	m_iTeleport = 1;

	if (m_szRechargerTarget[0] == '\0')	strcpy( m_szRechargerTarget, "n_recharger" );
	if (m_szDrawUse[0] == '\0')			strcpy( m_szDrawUse, "n_draw" );
	if (m_szTeleportUse[0] == '\0')		strcpy( m_szTeleportUse, "n_leaving" );
	if (m_szTeleportTouch[0] == '\0')	strcpy( m_szTeleportTouch, "n_teleport" );
	if (m_szDeadUse[0] == '\0')			strcpy( m_szDeadUse, "n_dead" );
	if (m_szDeadTouch[0] == '\0')		strcpy( m_szDeadTouch, "n_ending" );

	SetBloodColor( BLOOD_COLOR_YELLOW );
}


void CNPC_Nihilanth::Precache( void )
{
	engine->PrecacheModel("models/nihilanth.mdl");
	engine->PrecacheModel("sprites/lgtning.vmt");
	UTIL_PrecacheOther( "nihilanth_energy_ball" );
	UTIL_PrecacheOther( "monster_alien_controller" );
	UTIL_PrecacheOther( "monster_alien_slave" );

	PRECACHE_SOUND_ARRAY( pAttackSounds );
	PRECACHE_SOUND_ARRAY( pBallSounds );
	PRECACHE_SOUND_ARRAY( pShootSounds );
	PRECACHE_SOUND_ARRAY( pRechargeSounds );
	PRECACHE_SOUND_ARRAY( pLaughSounds );
	PRECACHE_SOUND_ARRAY( pPainSounds );
	PRECACHE_SOUND_ARRAY( pDeathSounds );
	enginesound->PrecacheSound("debris/beamstart7.wav");
}

void CNPC_Nihilanth::PainSound( void )
{
	if (m_flNextPainSound > gpGlobals->curtime)
		return;
	
	m_flNextPainSound = gpGlobals->curtime + random->RandomFloat( 2, 5 );

	if ( m_iHealth > sk_nihilanth_health.GetFloat() / 2)
	{
		CPASAttenuationFilter filter( this );
		enginesound->EmitSound( filter, entindex(), CHAN_VOICE, RANDOM_SOUND_ARRAY( pLaughSounds ), 1, 0.2 ); 
	}
	else if (m_irritation >= 2)
	{
		CPASAttenuationFilter filter( this );
		enginesound->EmitSound( filter, entindex(), CHAN_VOICE, RANDOM_SOUND_ARRAY( pPainSounds ), 1, 0.2 ); 
	}
}	

void CNPC_Nihilanth::DeathSound( void )
{
	CPASAttenuationFilter filter( this );
	enginesound->EmitSound( filter, entindex(), CHAN_VOICE, RANDOM_SOUND_ARRAY( pDeathSounds ), 1, 0.1 ); 
}

int	CNPC_Nihilanth::OnTakeDamage_Alive( const CTakeDamageInfo &info )
{
	if ( info.GetInflictor() == this )
		 return 0;

	if ( info.GetDamage() >= m_iHealth )
	{
		m_iHealth = 1;
		if ( m_irritation != 3 )
			 return 0;
	}
	
	PainSound( );

	m_iHealth -= info.GetDamage();

	return 0;
}

void CNPC_Nihilanth::TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr )
{
	if (m_irritation == 3)
		m_irritation = 2;

	if (m_irritation == 2 && ptr->hitbox == 3 && info.GetDamage() > 2)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -