📄 hl1_npc_scientist.cpp
字号:
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 + -