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

📄 hl1_npc_hassassin.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				m_iFrustration = 0;
				return SCHED_RANGE_ATTACK1;
			}

			if ( HasCondition ( COND_SEE_ENEMY ) )
			{
				//Msg( "face\n");
				return SCHED_COMBAT_FACE;
			}

			// new enemy
			if ( HasCondition ( COND_NEW_ENEMY ) )
			{
				//Msg( "take cover\n");
				return SCHED_TAKE_COVER_FROM_ENEMY;
			}

			// ALERT( at_console, "stand\n");
			return SCHED_ALERT_STAND;
		}
		break;
	}

	return BaseClass::SelectSchedule();
}

//=========================================================
// HandleAnimEvent - catches the monster-specific messages
// that occur when tagged animation frames are played.
//
// Returns number of events handled, 0 if none.
//=========================================================
void CNPC_HAssassin::HandleAnimEvent( animevent_t *pEvent )
{
	switch( pEvent->event )
	{
	case ASSASSIN_AE_SHOOT1:
		Shoot( );
		break;
	case ASSASSIN_AE_TOSS1:
		{
			Vector vTossPos;
			QAngle vAngles;

			GetAttachment( "grenadehand", vTossPos, vAngles );

			CHL1BaseGrenade *pGrenade = (CHL1BaseGrenade*)CreateNoSpawn( "npc_handgrenade", vTossPos, vec3_angle, this );
			pGrenade->SetAbsVelocity( m_vecTossVelocity );
			pGrenade->m_flDetonateTime = gpGlobals->curtime + 2.0;
			pGrenade->Spawn( );
			pGrenade->SetOwner( this );
			pGrenade->SetOwnerEntity( this );
			pGrenade->SetGravity( 0.5 );

			m_flNextGrenadeCheck = gpGlobals->curtime + 6;// wait six seconds before even looking again to see if a grenade can be thrown.
			m_fThrowGrenade = FALSE;
			// !!!LATER - when in a group, only try to throw grenade if ordered.
		}
		break;
	case ASSASSIN_AE_JUMP:
		{
			SetMoveType( MOVETYPE_FLYGRAVITY );
			RemoveFlag( FL_ONGROUND );
			SetAbsVelocity( m_vecJumpVelocity );
			m_flNextJump = gpGlobals->curtime + 3.0;
		}
		return;
	default:
		BaseClass::HandleAnimEvent( pEvent );
		break;
	}
}



//=========================================================
// Shoot
//=========================================================
void CNPC_HAssassin::Shoot ( void )
{
	Vector vForward, vRight, vUp;
	Vector vecShootOrigin;
	QAngle vAngles;

	if ( GetEnemy() == NULL)
	{
		return;
	}

	GetAttachment( "guntip", vecShootOrigin, vAngles );
	
	Vector vecShootDir = GetShootEnemyDir( vecShootOrigin );

	if (m_flLastShot + 2 < gpGlobals->curtime)
	{
		m_flDiviation = 0.10;
	}
	else
	{
		m_flDiviation -= 0.01;
		if (m_flDiviation < 0.02)
			m_flDiviation = 0.02;
	}
	m_flLastShot = gpGlobals->curtime;

	AngleVectors( GetAbsAngles(), &vForward, &vRight, &vUp );

	Vector	vecShellVelocity = vRight * random->RandomFloat(40,90) + vUp * random->RandomFloat(75,200) + vForward * random->RandomFloat(-40, 40);
	//EjectBrass ( pev->origin + gpGlobals->v_up * 32 + gpGlobals->v_forward * 12, vecShellVelocity, pev->angles.y, m_iShell, TE_BOUNCE_SHELL); 
	FireBullets( 1, vecShootOrigin, vecShootDir, Vector( m_flDiviation, m_flDiviation, m_flDiviation ), 2048, m_iAmmoType ); // shoot +-8 degrees

	//NDebugOverlay::Line( vecShootOrigin, vecShootOrigin + vecShootDir * 2048, 255, 0, 0, true, 2.0 );

	CPASAttenuationFilter filter( this );

	switch( random->RandomInt( 0, 1 ))
	{
	case 0:
		enginesound->EmitSound( filter, entindex(), CHAN_WEAPON, "weapons/pl_gun1.wav", random->RandomFloat(0.6, 0.8), ATTN_NORM );
		break;
	case 1:
		enginesound->EmitSound( filter, entindex(), CHAN_WEAPON, "weapons/pl_gun2.wav", random->RandomFloat(0.6, 0.8), ATTN_NORM );
		break;
	}

	m_fEffects |= EF_MUZZLEFLASH;

	VectorAngles( vecShootDir, vAngles );
	SetPoseParameter( "shoot", vecShootDir.x );

	m_cAmmoLoaded--;
}

//=========================================================
//=========================================================
int CNPC_HAssassin::TranslateSchedule ( int scheduleType ) 
{
//	Msg( "%d\n", m_iFrustration );
	switch	( scheduleType )
	{
	case SCHED_TAKE_COVER_FROM_ENEMY:

		if ( m_iHealth > 30 )
			return SCHED_ASSASSIN_TAKE_COVER_FROM_ENEMY1;
		else
			return SCHED_ASSASSIN_TAKE_COVER_FROM_ENEMY2;

	case SCHED_TAKE_COVER_FROM_BEST_SOUND:
		return SCHED_ASSASSIN_TAKE_COVER_FROM_BEST_SOUND;
	case SCHED_FAIL:

		if ( m_NPCState == NPC_STATE_COMBAT )
			return SCHED_ASSASSIN_FAIL;

		break;
	case SCHED_ALERT_STAND:

		if ( m_NPCState == NPC_STATE_COMBAT )
			return SCHED_ASSASSIN_HIDE;

		break;
	//case SCHED_CHASE_ENEMY:
	//	return SCHED_ASSASSIN_HUNT;

	case SCHED_MELEE_ATTACK1:

		if ( GetFlags() & FL_ONGROUND)
		{
			if (m_flNextJump > gpGlobals->curtime)
			{
				// can't jump yet, go ahead and fail
				return SCHED_ASSASSIN_FAIL;
			}
			else
			{
				return SCHED_ASSASSIN_JUMP;
			}
		}
		else
		{
			return SCHED_ASSASSIN_JUMP_ATTACK;
		}
	}

	return BaseClass::TranslateSchedule( scheduleType );
}

//=========================================================
// RunAI
//=========================================================
void CNPC_HAssassin::RunAI( void )
{
	BaseClass::RunAI();

	// always visible if moving
	// always visible is not on hard
	if (g_iSkillLevel != SKILL_HARD || GetEnemy() == NULL || m_lifeState == LIFE_DEAD || GetActivity() == ACT_RUN || GetActivity() == ACT_WALK || !(GetFlags() & FL_ONGROUND))
		m_iTargetRanderamt = 255;
	else
		m_iTargetRanderamt = 20;

	CPASAttenuationFilter filter( this );

	if ( GetRenderColor().a > m_iTargetRanderamt)
	{
		if ( GetRenderColor().a == 255)
		{
			enginesound->EmitSound( filter, entindex(), CHAN_BODY, "debris/beamstart1.wav", 0.2, ATTN_NORM );
		}

		SetRenderColorA( max( GetRenderColor().a - 50, m_iTargetRanderamt ) );
		m_nRenderMode = kRenderTransTexture;
	}
	else if ( GetRenderColor().a < m_iTargetRanderamt)
	{
		SetRenderColorA ( min( GetRenderColor().a + 50, m_iTargetRanderamt ) );
		if (GetRenderColor().a == 255)
			m_nRenderMode = kRenderNormal;
	}

	if ( GetActivity() == ACT_RUN || GetActivity() == ACT_WALK)
	{
		static int iStep = 0;
		iStep = ! iStep;
		if (iStep)
		{
			switch( random->RandomInt( 0, 3 ) )
			{
			case 0:	enginesound->EmitSound( filter, entindex(), CHAN_BODY, "player/pl_step1.wav", 0.5, ATTN_NORM );	break;
			case 1:	enginesound->EmitSound( filter, entindex(), CHAN_BODY, "player/pl_step3.wav", 0.5, ATTN_NORM );	break;
			case 2:	enginesound->EmitSound( filter, entindex(), CHAN_BODY, "player/pl_step2.wav", 0.5, ATTN_NORM );	break;
			case 3:	enginesound->EmitSound( filter, entindex(), CHAN_BODY, "player/pl_step4.wav", 0.5, ATTN_NORM );	break;
			}
		}
	}
}

AI_BEGIN_CUSTOM_NPC( monster_human_assassin, CNPC_HAssassin )

	DECLARE_TASK( TASK_ASSASSIN_FALL_TO_GROUND )

	DECLARE_ACTIVITY( ACT_ASSASSIN_FLY_UP )
	DECLARE_ACTIVITY( ACT_ASSASSIN_FLY_ATTACK )
	DECLARE_ACTIVITY( ACT_ASSASSIN_FLY_DOWN )

	//=========================================================
	// AI Schedules Specific to this monster
	//=========================================================

	//=========================================================
	// Enemy exposed assasin's cover
	//=========================================================

	//=========================================================
	// > SCHED_ASSASSIN_EXPOSED
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_ASSASSIN_EXPOSED,
	
		"	Tasks"
		"		TASK_STOP_MOVING		0"
		"		TASK_RANGE_ATTACK1		0"
		"		TASK_SET_FAIL_SCHEDULE	SCHEDULE:SCHED_ASSASSIN_JUMP"
		"		TASK_SET_SCHEDULE		SCHEDULE:SCHED_TAKE_COVER_FROM_ENEMY"
		"	"
		"	Interrupts"
		"	COND_CAN_MELEE_ATTACK1"
		
	)

	//=========================================================
	// > SCHED_ASSASSIN_JUMP
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_ASSASSIN_JUMP,
	
		"	Tasks"
		"		TASK_STOP_MOVING		0"
		"		TASK_PLAY_SEQUENCE		ACTIVITY:ACT_HOP"
		"		TASK_SET_SCHEDULE		SCHEDULE:SCHED_ASSASSIN_JUMP_ATTACK"
		"	"
		"	Interrupts"
	)

	//=========================================================
	// > SCHED_ASSASSIN_JUMP_ATTACK
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_ASSASSIN_JUMP_ATTACK,
	
		"	Tasks"
		"		TASK_SET_FAIL_SCHEDULE		SCHEDULE:SCHED_ASSASSIN_JUMP_LAND"
		"		TASK_ASSASSIN_FALL_TO_GROUND	0"
		"	"
		"	Interrupts"
	)

	//=========================================================
	// > SCHED_ASSASSIN_JUMP_LAND
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_ASSASSIN_JUMP_LAND,
	
		"	Tasks"
		"		TASK_SET_FAIL_SCHEDULE		SCHEDULE:SCHED_ASSASSIN_EXPOSED"
		"		TASK_SET_ACTIVITY			ACTIVITY:ACT_IDLE"
		"		TASK_REMEMBER				MEMORY:CUSTOM1"
		"		TASK_FIND_NODE_COVER_FROM_ENEMY		0"
		"		TASK_RUN_PATH						0"
		"		TASK_FORGET					MEMORY:CUSTOM1"
		"		TASK_WAIT_FOR_MOVEMENT				0"
		"		TASK_REMEMBER				MEMORY:INCOVER"
		"		TASK_FACE_ENEMY				0"
		"		TASK_SET_FAIL_SCHEDULE		SCHEDULE:SCHED_RANGE_ATTACK1"

		"	"
		"	Interrupts"
	)

	//=========================================================
	// Fail Schedule
	//=========================================================

	//=========================================================
	// > SCHED_ASSASSIN_FAIL
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_ASSASSIN_FAIL,
	
		"	Tasks"
		"		TASK_STOP_MOVING		0"
		"		TASK_SET_ACTIVITY		ACTIVITY:ACT_IDLE"
		"		TASK_WAIT_FACE_ENEMY	2"
		"		TASK_SET_SCHEDULE		SCHEDULE:SCHED_CHASE_ENEMY"
		"	"
		"	Interrupts"
		"		COND_LIGHT_DAMAGE"
		"		COND_HEAVY_DAMAGE"
		"		COND_CAN_RANGE_ATTACK1"
		"		COND_CAN_RANGE_ATTACK2"
		"		COND_CAN_MELEE_ATTACK1"
		"		COND_HEAR_DANGER"
		"		COND_HEAR_PLAYER"
	)


	

	//=========================================================
	// > SCHED_ASSASSIN_TAKE_COVER_FROM_ENEMY1
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_ASSASSIN_TAKE_COVER_FROM_ENEMY1,
	
		"	Tasks"
		"		TASK_STOP_MOVING		0"
		"		TASK_WAIT				0.2"
		"		TASK_SET_FAIL_SCHEDULE	SCHEDULE:SCHED_RANGE_ATTACK1"
		"		TASK_FIND_COVER_FROM_ENEMY 0"
		"		TASK_RUN_PATH 0"
		"		TASK_WAIT_FOR_MOVEMENT 0"
		"		TASK_REMEMBER			MEMORY:INCOVER"
		"		TASK_FACE_ENEMY			0"
		"	"
		"	Interrupts"
		"	COND_CAN_MELEE_ATTACK1"
		"	COND_NEW_ENEMY"
		"	COND_HEAR_DANGER"
		
	)

	//=========================================================
	// > SCHED_ASSASSIN_TAKE_COVER_FROM_ENEMY2
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_ASSASSIN_TAKE_COVER_FROM_ENEMY2,
	
		"	Tasks"
		"		TASK_STOP_MOVING		0"
		"		TASK_WAIT				0.2"
		"		TASK_FACE_ENEMY			0"
		"		TASK_RANGE_ATTACK1		0"
		"		TASK_SET_FAIL_SCHEDULE	SCHEDULE:SCHED_RANGE_ATTACK1"
		"		TASK_FIND_COVER_FROM_ENEMY 0"
		"		TASK_RUN_PATH 0"
		"		TASK_WAIT_FOR_MOVEMENT 0"
		"		TASK_REMEMBER			MEMORY:INCOVER"
		"		TASK_FACE_ENEMY			0"
		"	"
		"	Interrupts"
		"	COND_CAN_MELEE_ATTACK1"
		"	COND_NEW_ENEMY"
		"	COND_HEAR_DANGER"
		
	)



	//=========================================================
	// hide from the loudest sound source
	//=========================================================

	//=========================================================
	// > SCHED_ASSASSIN_TAKE_COVER_FROM_BEST_SOUND
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_ASSASSIN_TAKE_COVER_FROM_BEST_SOUND,
	
		"	Tasks"
		"		TASK_SET_FAIL_SCHEDULE	SCHEDULE:SCHED_MELEE_ATTACK1"
		"		TASK_STOP_MOVING		0"
		"		TASK_FIND_COVER_FROM_BEST_SOUND	0"
		"		TASK_RUN_PATH			0"
		"		TASK_WAIT_FOR_MOVEMENT	0"
		"		TASK_REMEMBER			MEMORY:INCOVER"
		"		TASK_TURN_LEFT			179"
		"	"
		"	Interrupts"
		"	COND_NEW_ENEMY"
		
	)

	//=========================================================
	// > SCHED_ASSASSIN_HIDE
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_ASSASSIN_HIDE,
	
		"	Tasks"
		"		TASK_STOP_MOVING		0"
		"		TASK_SET_ACTIVITY		ACTIVITY:ACT_IDLE"
		"		TASK_WAIT				2.0"
		"		TASK_SET_SCHEDULE		SCHEDULE:SCHED_CHASE_ENEMY"
	
		"	Interrupts"
		"		COND_NEW_ENEMY"
		"		COND_SEE_ENEMY"
		"		COND_SEE_FEAR"
		"		COND_LIGHT_DAMAGE"
		"		COND_HEAVY_DAMAGE"
		"		COND_PROVOKED"
		"		COND_HEAR_DANGER"
	)

	//=========================================================
	// > SCHED_ASSASSIN_HUNT
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_ASSASSIN_HUNT,
	
		"	Tasks"
		"		TASK_STOP_MOVING			0"
		"		TASK_SET_FAIL_SCHEDULE		SCHEDULE:SCHED_ASSASSIN_TAKE_COVER_FROM_ENEMY2"
		"		TASK_GET_PATH_TO_ENEMY		0"
		"		TASK_RUN_PATH				0"
		"		TASK_WAIT_FOR_MOVEMENT		0"
		
		"	Interrupts"
		"		COND_NEW_ENEMY"
		"		COND_CAN_RANGE_ATTACK1"
		"		COND_HEAR_DANGER"
	)

AI_END_CUSTOM_NPC()

⌨️ 快捷键说明

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