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

📄 hl1_npc_scientist.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 3 页
字号:

	m_NPCState			= NPC_STATE_NONE;

	CapabilitiesClear();
	CapabilitiesAdd( bits_CAP_TURN_HEAD );

	m_spawnflags |= SF_NPC_PREDISASTER; // predisaster only!

	if ( m_nBody == -1 )
	{// -1 chooses a random head
		m_nBody = random->RandomInt( 0, NUM_SCIENTIST_HEADS-1 );// pick a head, any head
	}
	// Luther is black, make his hands black
	if ( m_nBody == HEAD_LUTHER )
		 m_nBody = 1;
	
	m_baseSequence = LookupSequence( "sitlookleft" );
	SetSequence( m_baseSequence + random->RandomInt(0,4) );

	UTIL_DropToFloor( this,MASK_SOLID );

	ResetSequenceInfo( );

	NPCInit();
	
	SetThink (SittingThink);
	SetNextThink( gpGlobals->curtime + 0.1f );
}

void CNPC_SittingScientist :: Precache( void )
{
	m_baseSequence = LookupSequence( "sitlookleft" );
	TalkInit();
}


int CNPC_SittingScientist::FriendNumber( int arrayNumber )
{
	static int array[3] = { 2, 1, 0 };
	if ( arrayNumber < 3 )
		return array[ arrayNumber ];
	return arrayNumber;
}

//=========================================================
// sit, do stuff
//=========================================================
void CNPC_SittingScientist :: SittingThink( void )
{
	CBaseEntity *pent;	

	StudioFrameAdvance( );

	// try to greet player
	//FIXMEFIXME
	if ( GetExpresser()->CanSpeakConcept( TLK_HELLO ) )
	{
		pent = FindNamedEntity( "!nearestfriend" );
		if (pent)
		{
			float yaw = VecToYaw(pent->GetAbsOrigin() - GetAbsOrigin()) - GetAbsAngles().y;

			if (yaw > 180) yaw -= 360;
			if (yaw < -180) yaw += 360;
				
			if (yaw > 0)
				SetSequence( m_baseSequence + SITTING_ANIM_sitlookleft );
			else
				SetSequence ( m_baseSequence + SITTING_ANIM_sitlookright );
		
			ResetSequenceInfo( );
			m_flCycle = 0;
			SetBoneController( 0, 0 );

			GetExpresser()->Speak( TLK_HELLO );
		}
	}
	else if ( IsSequenceFinished() )
	{
		int i = random->RandomInt(0,99);
		m_iHeadTurn = 0;
		
		if (m_flResponseDelay && gpGlobals->curtime > m_flResponseDelay)
		{
			// respond to question
			GetExpresser()->Speak( TLK_QUESTION );
			SetSequence( m_baseSequence + SITTING_ANIM_sitscared );
			m_flResponseDelay = 0;
		}
		else if (i < 30)
		{
			SetSequence( m_baseSequence + SITTING_ANIM_sitting3 );

			// turn towards player or nearest friend and speak

			//FIXME
		/*/	if (!FBitSet(m_nSpeak, bit_saidHelloPlayer))
				pent = FindNearestFriend(TRUE);
			else*/
				pent = FindNamedEntity( "!nearestfriend" );

			if (!FIdleSpeak() || !pent)
			{	
				m_iHeadTurn = random->RandomInt(0,8) * 10 - 40;
				SetSequence( m_baseSequence + SITTING_ANIM_sitting3 );
			}
			else
			{
				// only turn head if we spoke
				float yaw = VecToYaw(pent->GetAbsOrigin() - GetAbsOrigin()) - GetAbsAngles().y;

				if (yaw > 180) yaw -= 360;
				if (yaw < -180) yaw += 360;
				
				if (yaw > 0)
					SetSequence( m_baseSequence + SITTING_ANIM_sitlookleft );
				else
					SetSequence( m_baseSequence + SITTING_ANIM_sitlookright );

				//ALERT(at_console, "sitting speak\n");
			}
		}
		else if (i < 60)
		{
			SetSequence( m_baseSequence + SITTING_ANIM_sitting3 );
			m_iHeadTurn = random->RandomInt(0,8) * 10 - 40;
			if ( random->RandomInt(0,99) < 5)
			{
				//ALERT(at_console, "sitting speak2\n");
				FIdleSpeak();
			}
		}
		else if (i < 80)
		{
			SetSequence( m_baseSequence + SITTING_ANIM_sitting2 );
		}
		else if (i < 100)
		{
			SetSequence( m_baseSequence + SITTING_ANIM_sitscared );
		}

		ResetSequenceInfo( );
		m_flCycle = 0;
		SetBoneController( 0, m_iHeadTurn );
	}

	SetNextThink( gpGlobals->curtime + 0.1f );
}

// prepare sitting scientist to answer a question
void CNPC_SittingScientist :: SetAnswerQuestion( CNPCSimpleTalker *pSpeaker )
{
	m_flResponseDelay = gpGlobals->curtime + random->RandomFloat(3, 4);
	SetSpeechTarget( (CNPCSimpleTalker *)pSpeaker );
}


//=========================================================
// FIdleSpeak
// ask question of nearby friend, or make statement
//=========================================================
int CNPC_SittingScientist :: FIdleSpeak ( void )
{ 
	// try to start a conversation, or make statement
	int pitch;
	
	if (!IsOkToSpeak())
		return FALSE;

	// set global min delay for next conversation
	GetExpresser()->BlockSpeechUntil( gpGlobals->curtime + random->RandomFloat(4.8, 5.2) );

	pitch = GetExpresser()->GetVoicePitch();
		
	// if there is a friend nearby to speak to, play sentence, set friend's response time, return

	// try to talk to any standing or sitting scientists nearby
	CBaseEntity *pentFriend = FindNamedEntity( "!nearestfriend" );

	if (pentFriend && random->RandomInt(0,1))
	{
//		CNPCSimpleTalker *pTalkMonster = (CNPCSimpleTalker *)pentFriend;
		//pTalkMonster->SetAnswerQuestion( this );

		SetSchedule( SCHED_TALKER_IDLE_RESPONSE );
		SetSpeechTarget( this );
		
		Msg( "Asking some question!\n" );
		
		IdleHeadTurn( pentFriend->GetAbsOrigin());
		SENTENCEG_PlayRndSz( edict(), TLK_PQUESTION, 1.0, SNDLVL_TALKING, 0, pitch );
		// set global min delay for next conversation
		GetExpresser()->BlockSpeechUntil( gpGlobals->curtime + random->RandomFloat(4.8, 5.2) );
		return TRUE;
	}

	// otherwise, play an idle statement
	if ( random->RandomInt(0,1))
	{
		Msg( "Making idle statement!\n" );

		SENTENCEG_PlayRndSz( edict(), TLK_PIDLE, 1.0, SNDLVL_TALKING, 0, pitch );
		// set global min delay for next conversation
		GetExpresser()->BlockSpeechUntil( gpGlobals->curtime + random->RandomFloat(4.8, 5.2) );
		return TRUE;
	}

	// never spoke
	GetExpresser()->BlockSpeechUntil( 0 );
	return FALSE;
}

//------------------------------------------------------------------------------
//
// Schedules
//
//------------------------------------------------------------------------------

AI_BEGIN_CUSTOM_NPC( monster_scientist, CNPC_Scientist )

	DECLARE_TASK( TASK_SAY_HEAL )
	DECLARE_TASK( TASK_HEAL )
	DECLARE_TASK( TASK_SAY_FEAR )
	DECLARE_TASK( TASK_RUN_PATH_SCARED )
	DECLARE_TASK( TASK_SCREAM )
	DECLARE_TASK( TASK_RANDOM_SCREAM )
	DECLARE_TASK( TASK_MOVE_TO_TARGET_RANGE_SCARED )
	
	DECLARE_ACTIVITY( ACT_EXCITED )

	//=========================================================
	// > SCHED_SCI_HEAL
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_SCI_HEAL,

		"	Tasks"
		"		TASK_GET_PATH_TO_TARGET				0"
		"		TASK_MOVE_TO_TARGET_RANGE			50"
		"		TASK_SET_FAIL_SCHEDULE				SCHEDULE:SCHED_SCI_FOLLOWTARGET"
		"		TASK_FACE_IDEAL						0"
		"		TASK_SAY_HEAL						0"
		"		TASK_PLAY_SEQUENCE_FACE_TARGET		ACTIVITY:ACT_ARM"
		"		TASK_HEAL							0"
		"		TASK_PLAY_SEQUENCE_FACE_TARGET		ACTIVITY:ACT_DISARM"
		"	"
		"	Interrupts"
	)

	//=========================================================
	// > SCHED_SCI_FOLLOWTARGET
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_SCI_FOLLOWTARGET,

		"	Tasks"
//		"		TASK_SET_FAIL_SCHEDULE			SCHEDULE:SCHED_SCI_STOPFOLLOWING"
		"		TASK_GET_PATH_TO_TARGET			0"
		"		TASK_MOVE_TO_TARGET_RANGE		128"
		"		TASK_SET_SCHEDULE				SCHEDULE:SCHED_TARGET_FACE"	
		"	"
		"	Interrupts"
		"		COND_NEW_ENEMY"
		"		COND_LIGHT_DAMAGE"
		"		COND_HEAVY_DAMAGE"
		"		COND_HEAR_DANGER"
		"		COND_HEAR_COMBAT"
	)

	//=========================================================
	// > SCHED_SCI_STOPFOLLOWING
	//=========================================================
//	DEFINE_SCHEDULE
//	(
//		SCHED_SCI_STOPFOLLOWING,
//
//		"	Tasks"
//		"		TASK_TALKER_CANT_FOLLOW			0"
//		"	"
//		"	Interrupts"
//	)

	//=========================================================
	// > SCHED_SCI_FACETARGET
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_SCI_FACETARGET,

		"	Tasks"
		"		TASK_STOP_MOVING			0"
		"		TASK_FACE_TARGET			0"
		"		TASK_SET_ACTIVITY			ACTIVITY:ACT_IDLE"
		"		TASK_SET_SCHEDULE			SCHEDULE:SCHED_SCI_FOLLOWTARGET"
		"	"
		"	Interrupts"
		"		COND_NEW_ENEMY"
		"		COND_HEAR_DANGER"
		"		COND_HEAR_COMBAT"
		"		COND_GIVE_WAY"
	)

	//=========================================================
	// > SCHED_SCI_COVER
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_SCI_COVER,

		"	Tasks"
		"		TASK_SET_FAIL_SCHEDULE			SCHEDULE:SCHED_SCI_PANIC"
		"		TASK_STOP_MOVING				0"
		"		TASK_FIND_COVER_FROM_ENEMY		0"
		"		TASK_RUN_PATH_SCARED			0"
		"		TASK_TURN_LEFT					179"
		"		TASK_SET_SCHEDULE				SCHEDULE:SCHED_SCI_HIDE"
		"	"
		"	Interrupts"
		"		COND_NEW_ENEMY"
	)

	//=========================================================
	// > SCHED_SCI_HIDE
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_SCI_HIDE,

		"	Tasks"
		"		TASK_SET_FAIL_SCHEDULE		SCHEDULE:SCHED_SCI_PANIC"
		"		TASK_STOP_MOVING			0"
		"		TASK_PLAY_SEQUENCE			ACTIVITY:ACT_CROUCHIDLE"
		"		TASK_SET_ACTIVITY			ACTIVITY:ACT_CROUCHIDLE"
		"		TASK_WAIT_RANDOM			10"
		"	"
		"	Interrupts"
		"		COND_NEW_ENEMY"
		"		COND_SEE_ENEMY"
		"		COND_SEE_HATE"
		"		COND_SEE_FEAR"
		"		COND_SEE_DISLIKE"
		"		COND_HEAR_DANGER"
	)

	//=========================================================
	// > SCHED_SCI_IDLESTAND
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_SCI_IDLESTAND,

		"	Tasks"
		"		TASK_STOP_MOVING			0"
		"		TASK_SET_ACTIVITY			ACTIVITY:ACT_IDLE"
		"		TASK_WAIT					2"
		"		TASK_TALKER_HEADRESET		0"
		"	"
		"	Interrupts"
		"		COND_NEW_ENEMY"
		"		COND_LIGHT_DAMAGE"
		"		COND_HEAVY_DAMAGE"
		"		COND_SMELL"
		"		COND_PROVOKED"
		"		COND_HEAR_COMBAT"
		"		COND_GIVE_WAY"
	)

	//=========================================================
	// > SCHED_SCI_PANIC
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_SCI_PANIC,

		"	Tasks"
		"		TASK_STOP_MOVING					0"
		"		TASK_FACE_ENEMY						0"
		"		TASK_SCREAM							0"
		"		TASK_PLAY_SEQUENCE_FACE_ENEMY		ACTIVITY:ACT_EXCITED"
		"		TASK_SET_ACTIVITY					ACTIVITY:ACT_IDLE"
		"	"
		"	Interrupts"
	)

	//=========================================================
	// > SCHED_SCI_FOLLOWSCARED
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_SCI_FOLLOWSCARED,

		"	Tasks"
		"		TASK_GET_PATH_TO_TARGET				0"
		"		TASK_SET_FAIL_SCHEDULE				SCHEDULE:SCHED_SCI_FOLLOWTARGET"	
		"		TASK_MOVE_TO_TARGET_RANGE_SCARED	128"
		"	"
		"	Interrupts"
		"		COND_NEW_ENEMY"
		"		COND_LIGHT_DAMAGE"
		"		COND_HEAVY_DAMAGE"
		"		COND_HEAR_DANGER"
	)

	//=========================================================
	// > SCHED_SCI_FACETARGETSCARED
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_SCI_FACETARGETSCARED,

		"	Tasks"
		"	TASK_FACE_TARGET				0"
		"		TASK_SET_ACTIVITY			ACTIVITY:ACT_CROUCHIDLE"
		"		TASK_SET_SCHEDULE			SCHEDULE:SCHED_SCI_FOLLOWSCARED"
		"	"
		"	Interrupts"
		"		COND_NEW_ENEMY"
		"		COND_HEAR_DANGER"
	)

	//=========================================================
	// > SCHED_FEAR
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_SCI_FEAR,

		"	Tasks"
		"		TASK_STOP_MOVING			0"
		"		TASK_FACE_ENEMY				0"
		"		TASK_SAY_FEAR				0"
		"	"
		"	Interrupts"
		"		COND_NEW_ENEMY"
	)

	//=========================================================
	// > SCHED_SCI_STARTLE
	//=========================================================
	DEFINE_SCHEDULE
	(
		SCHED_SCI_STARTLE,

		"	Tasks"
		"		TASK_SET_FAIL_SCHEDULE				SCHEDULE:SCHED_SCI_PANIC"
		"		TASK_RANDOM_SCREAM					0.3"
		"		TASK_STOP_MOVING					0"
		"		TASK_PLAY_SEQUENCE_FACE_ENEMY		ACTIVITY:ACT_CROUCH"
		"		TASK_RANDOM_SCREAM					0.1"
		"		TASK_PLAY_SEQUENCE_FACE_ENEMY		ACTIVITY:ACT_CROUCHIDLE"
		"		TASK_WAIT_RANDOM					1"
		"	"
		"	Interrupts"
		"		COND_NEW_ENEMY"
		"		COND_SEE_ENEMY"
		"		COND_SEE_HATE"
		"		COND_SEE_FEAR"
		"		COND_SEE_DISLIKE"
	)

AI_END_CUSTOM_NPC()

⌨️ 快捷键说明

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