void CGMan::RunTask(Task_t *pTask) { switch(pTask->iTask) { case TASK_WAIT: // look at who I'm talking to if(m_flTalkTime > gpGlobals->time && m_hTalkTarget != NULL) { float yaw = VecToYaw(m_hTalkTarget->pev->origin - pev->origin) - pev->angles.y; if(yaw > 180) yaw -= 360; if(yaw < -180) yaw += 360; // turn towards vector SetBoneController(0, yaw); } // look at player, but only if playing a "safe" idle animation else if(m_hPlayer != NULL && pev->sequence == 0) { float yaw = VecToYaw(m_hPlayer->pev->origin - pev->origin) - pev->angles.y; if(yaw > 180) yaw -= 360; if(yaw < -180) yaw += 360; // turn towards vector SetBoneController(0, yaw); } else { SetBoneController(0, 0); } CBaseMonster::RunTask(pTask); break; default: SetBoneController(0, 0); CBaseMonster::RunTask(pTask); break; } }
void CNPC_GMan :: RunTask( const Task_t *pTask ) { switch( pTask->iTask ) { case TASK_WAIT: // look at who I'm talking to if (m_flTalkTime > gpGlobals->curtime && m_hTalkTarget != NULL) { float yaw = VecToYaw(m_hTalkTarget->GetAbsOrigin() - GetAbsOrigin()) - GetAbsAngles().y; if (yaw > 180) yaw -= 360; if (yaw < -180) yaw += 360; // turn towards vector SetBoneController( 0, yaw ); } // look at player, but only if playing a "safe" idle animation else if (m_hPlayer != NULL && GetSequence() == 0) { float yaw = VecToYaw(m_hPlayer->GetAbsOrigin() - GetAbsOrigin()) - GetAbsAngles().y; if (yaw > 180) yaw -= 360; if (yaw < -180) yaw += 360; // turn towards vector SetBoneController( 0, yaw ); } else { SetBoneController( 0, 0 ); } BaseClass::RunTask( pTask ); break; } SetBoneController( 0, 0 ); BaseClass::RunTask( pTask ); }
// turn head towards supplied origin void CTalkMonster :: IdleHeadTurn( const Vector &vecFriend ) { // turn head in desired direction only if ent has a turnable head if (m_afCapability & bits_CAP_TURN_HEAD) { float yaw = VecToYaw(vecFriend - GetAbsOrigin()) - GetAbsAngles().y; if (yaw > 180) yaw -= 360; if (yaw < -180) yaw += 360; // turn towards vector SetBoneController( 0, yaw ); } }
//----------------------------------------------------------------------------- // Purpose: // Input : // Output : //----------------------------------------------------------------------------- void CAI_BaseFlyingBot::TurnHeadToTarget(float flInterval, const Vector &MoveTarget ) { float flDestYaw = VecToYaw( MoveTarget - GetLocalOrigin() ); float newYaw = AI_ClampYaw( GetHeadTurnRate() * 10.0f, m_fHeadYaw, flDestYaw, gpGlobals->curtime - GetLastThink() ); if ( newYaw != m_fHeadYaw ) { m_fHeadYaw = newYaw; } // Set us to face that way SetBoneController( 0, m_fHeadYaw ); }
//----------------------------------------------------------------------------- // Purpose: // Input : // Output : //----------------------------------------------------------------------------- void CAI_BasePhysicsFlyingBot::TurnHeadToTarget(float flInterval, const Vector &MoveTarget ) { float desYaw = UTIL_AngleDiff(VecToYaw(MoveTarget - GetLocalOrigin()), 0 ); m_fHeadYaw = desYaw; return; // If I've flipped completely around, reverse angles float fYawDiff = m_fHeadYaw - desYaw; if (fYawDiff > 180) { m_fHeadYaw -= 360; } else if (fYawDiff < -180) { m_fHeadYaw += 360; } // RIGHT NOW, this affects every flying bot. This rate should be member data that individuals // can manipulate. THIS change for MANHACKS E3 2003 (sjb) float iRate = 0.8; // Make frame rate independent float timeToUse = flInterval; while (timeToUse > 0) { m_fHeadYaw = (iRate * m_fHeadYaw) + (1-iRate)*desYaw; timeToUse -= 0.1; } while( m_fHeadYaw > 360 ) { m_fHeadYaw -= 360.0f; } while( m_fHeadYaw < 0 ) { m_fHeadYaw += 360.f; } // SetBoneController( 0, m_fHeadYaw ); }
void CTalkMonster :: StartTask( const Task_t& task ) { switch ( task.iTask ) { case TASK_TLK_SPEAK: // ask question or make statement FIdleSpeak(); TaskComplete(); break; case TASK_TLK_RESPOND: // respond to question IdleRespond(); TaskComplete(); break; case TASK_TLK_HELLO: // greet player FIdleHello(); TaskComplete(); break; case TASK_TLK_STARE: // let the player know I know he's staring at me. FIdleStare(); TaskComplete(); break; case TASK_FACE_PLAYER: case TASK_TLK_LOOK_AT_CLIENT: case TASK_TLK_CLIENT_STARE: // track head to the client for a while. m_flWaitFinished = gpGlobals->time + task.flData; break; case TASK_TLK_EYECONTACT: break; case TASK_TLK_IDEALYAW: if (m_hTalkTarget != NULL) { SetYawSpeed( 60 ); float yaw = VecToYaw(m_hTalkTarget->GetAbsOrigin() - GetAbsOrigin()) - GetAbsAngles().y; if (yaw > 180) yaw -= 360; if (yaw < -180) yaw += 360; if (yaw < 0) { SetIdealYaw( min( yaw + 45, 0.0f ) + GetAbsAngles().y ); } else { SetIdealYaw( max( yaw - 45, 0.0f ) + GetAbsAngles().y ); } } TaskComplete(); break; case TASK_TLK_HEADRESET: // reset head position after looking at something m_hTalkTarget = NULL; TaskComplete(); break; case TASK_TLK_STOPSHOOTING: // tell player to stop shooting PlaySentence( m_szGrp[TLK_NOSHOOT], RANDOM_FLOAT(2.8, 3.2), VOL_NORM, ATTN_NORM ); TaskComplete(); break; case TASK_CANT_FOLLOW: StopFollowing( false ); PlaySentence( m_szGrp[TLK_STOP], RANDOM_FLOAT(2, 2.5), VOL_NORM, ATTN_NORM ); TaskComplete(); break; case TASK_WALK_PATH_FOR_UNITS: m_movementActivity = ACT_WALK; break; case TASK_MOVE_AWAY_PATH: { Vector dir = GetAbsAngles(); dir.y = GetIdealYaw() + 180; Vector move; UTIL_MakeVectorsPrivate( dir, &move, nullptr, nullptr ); dir = GetAbsOrigin() + move * task.flData; if ( MoveToLocation( ACT_WALK, 2, dir ) ) { TaskComplete(); } else if ( FindCover( GetAbsOrigin(), GetViewOffset(), 0, CoverRadius() ) ) { // then try for plain ole cover m_flMoveWaitFinished = gpGlobals->time + 2; TaskComplete(); } else { // nowhere to go? TaskFail(); } } break; case TASK_PLAY_SCRIPT: m_hTalkTarget = NULL; CBaseMonster::StartTask( task ); break; default: CBaseMonster::StartTask( task ); } }
void CMTalkMonster :: StartTask( Task_t *pTask ) { switch ( pTask->iTask ) { case TASK_TLK_SPEAK: // ask question or make statement FIdleSpeak(); TaskComplete(); break; case TASK_TLK_RESPOND: // respond to question IdleRespond(); TaskComplete(); break; case TASK_TLK_HELLO: // greet player FIdleHello(); TaskComplete(); break; case TASK_TLK_STARE: // let the player know I know he's staring at me. FIdleStare(); TaskComplete(); break; case TASK_FACE_PLAYER: case TASK_TLK_LOOK_AT_CLIENT: case TASK_TLK_CLIENT_STARE: // track head to the client for a while. m_flWaitFinished = gpGlobals->time + pTask->flData; break; case TASK_TLK_EYECONTACT: break; case TASK_TLK_IDEALYAW: if (m_hTalkTarget != NULL) { pev->yaw_speed = 60; float yaw = VecToYaw(m_hTalkTarget->v.origin - pev->origin) - pev->angles.y; if (yaw > 180) yaw -= 360; if (yaw < -180) yaw += 360; if (yaw < 0) { pev->ideal_yaw = min( yaw + 45.0f, 0.0f ) + pev->angles.y; } else { pev->ideal_yaw = max( yaw - 45.0f, 0.0f ) + pev->angles.y; } } TaskComplete(); break; case TASK_TLK_HEADRESET: // reset head position after looking at something m_hTalkTarget = NULL; TaskComplete(); break; case TASK_TLK_STOPSHOOTING: // tell player to stop shooting PlaySentence( m_szGrp[TLK_NOSHOOT], RANDOM_FLOAT(2.8, 3.2), VOL_NORM, ATTN_NORM ); TaskComplete(); break; case TASK_CANT_FOLLOW: StopFollowing( FALSE ); PlaySentence( m_szGrp[TLK_STOP], RANDOM_FLOAT(2, 2.5), VOL_NORM, ATTN_NORM ); TaskComplete(); break; case TASK_WALK_PATH_FOR_UNITS: m_movementActivity = ACT_WALK; break; case TASK_MOVE_AWAY_PATH: { Vector dir = pev->angles; dir.y = pev->ideal_yaw + 180; Vector move; UTIL_MakeVectorsPrivate( dir, move, NULL, NULL ); dir = pev->origin + move * pTask->flData; if ( MoveToLocation( ACT_WALK, 2, dir ) ) { TaskComplete(); } else if ( FindCover( pev->origin, pev->view_ofs, 0, CoverRadius() ) ) { // then try for plain ole cover m_flMoveWaitFinished = gpGlobals->time + 2; TaskComplete(); } else { // nowhere to go? TaskFail(); } } break; case TASK_PLAY_SCRIPT: m_hTalkTarget = NULL; CMBaseMonster::StartTask( pTask ); break; default: CMBaseMonster::StartTask( pTask ); } }
//========================================================= // sit, do stuff //========================================================= void CSittingScientist :: SittingThink( void ) { CBaseEntity *pent; StudioFrameAdvance( ); // try to greet player if (FIdleHello()) { pent = FindNearestFriend(TRUE); if (pent) { float yaw = VecToYaw(pent->pev->origin - pev->origin) - pev->angles.y; if (yaw > 180) yaw -= 360; if (yaw < -180) yaw += 360; if (yaw > 0) pev->sequence = m_baseSequence + SITTING_ANIM_sitlookleft; else pev->sequence = m_baseSequence + SITTING_ANIM_sitlookright; ResetSequenceInfo( ); pev->frame = 0; SetBoneController( 0, 0 ); } } else if (m_fSequenceFinished) { int i = RANDOM_LONG(0,99); m_headTurn = 0; if (m_flResponseDelay && gpGlobals->time > m_flResponseDelay) { // respond to question IdleRespond(); pev->sequence = m_baseSequence + SITTING_ANIM_sitscared; m_flResponseDelay = 0; } else if (i < 30) { pev->sequence = m_baseSequence + SITTING_ANIM_sitting3; // turn towards player or nearest friend and speak if (!FBitSet(m_bitsSaid, bit_saidHelloPlayer)) pent = FindNearestFriend(TRUE); else pent = FindNearestFriend(FALSE); if (!FIdleSpeak() || !pent) { m_headTurn = RANDOM_LONG(0,8) * 10 - 40; pev->sequence = m_baseSequence + SITTING_ANIM_sitting3; } else { // only turn head if we spoke float yaw = VecToYaw(pent->pev->origin - pev->origin) - pev->angles.y; if (yaw > 180) yaw -= 360; if (yaw < -180) yaw += 360; if (yaw > 0) pev->sequence = m_baseSequence + SITTING_ANIM_sitlookleft; else pev->sequence = m_baseSequence + SITTING_ANIM_sitlookright; //ALERT(at_console, "sitting speak\n"); } } else if (i < 60) { pev->sequence = m_baseSequence + SITTING_ANIM_sitting3; m_headTurn = RANDOM_LONG(0,8) * 10 - 40; if (RANDOM_LONG(0,99) < 5) { //ALERT(at_console, "sitting speak2\n"); FIdleSpeak(); } } else if (i < 80) { pev->sequence = m_baseSequence + SITTING_ANIM_sitting2; } else if (i < 100) { pev->sequence = m_baseSequence + SITTING_ANIM_sitscared; } ResetSequenceInfo( ); pev->frame = 0; SetBoneController( 0, m_headTurn ); } SetNextThink( 0.1 ); }
void CNPC_Tentacle::Cycle( void ) { //NDebugOverlay::Cross3D( EarPosition(), 32, 255, 0, 0, false, 0.1 ); // ALERT( at_console, "%s %.2f %d %d\n", STRING( pev->targetname ), pev->origin.z, m_MonsterState, m_IdealMonsterState ); SetNextThink( gpGlobals->curtime + 0.1 ); // ALERT( at_console, "%s %d %d %d %f %f\n", STRING( pev->targetname ), pev->sequence, m_iGoalAnim, m_iDir, pev->framerate, pev->health ); if ( m_NPCState == NPC_STATE_SCRIPT || GetIdealState() == NPC_STATE_SCRIPT) { SetAbsAngles( QAngle( GetAbsAngles().x, m_flInitialYaw, GetAbsAngles().z ) ); GetMotor()->SetIdealYaw( m_flInitialYaw ); RemoveIgnoredConditions(); NPCThink( ); m_iGoalAnim = TENTACLE_ANIM_Pit_Idle; return; } StudioFrameAdvance(); DispatchAnimEvents( this ); GetMotor()->UpdateYaw( MaxYawSpeed() ); CSound *pSound = NULL; GetSenses()->Listen(); m_BoneFollowerManager.UpdateBoneFollowers(this); // Listen will set this if there's something in my sound list if ( HeardAnything() ) pSound = GetSenses()->GetClosestSound( false, (SOUND_DANGER|SOUND_COMBAT|SOUND_WORLD|SOUND_PLAYER) ); else pSound = NULL; if ( pSound ) { //NDebugOverlay::Line( EarPosition(), pSound->GetSoundOrigin(), 0, 255, 0, false, 0.2 ); Vector vecDir; if ( gpGlobals->curtime - m_flPrevSoundTime < 0.5 ) { float dt = gpGlobals->curtime - m_flPrevSoundTime; vecDir = pSound->GetSoundOrigin() + (pSound->GetSoundOrigin() - m_vecPrevSound) / dt - GetAbsOrigin(); } else { vecDir = pSound->GetSoundOrigin() - GetAbsOrigin(); } m_flPrevSoundTime = gpGlobals->curtime; m_vecPrevSound = pSound->GetSoundOrigin(); m_flSoundYaw = VecToYaw ( vecDir ) - m_flInitialYaw; m_iSoundLevel = Level( vecDir.z ); if (m_flSoundYaw < -180) m_flSoundYaw += 360; if (m_flSoundYaw > 180) m_flSoundYaw -= 360; // ALERT( at_console, "sound %d %.0f\n", m_iSoundLevel, m_flSoundYaw ); if (m_flSoundTime < gpGlobals->curtime) { // play "I hear new something" sound UTIL_EmitAmbientSound( GetSoundSourceIndex(), GetAbsOrigin() + Vector( 0, 0, MyHeight()), "Tentacle.Alert", 1.0, SNDLVL_GUNFIRE, 0, 100); } m_flSoundTime = gpGlobals->curtime + random->RandomFloat( 5.0, 10.0 ); } // clip ideal_yaw float dy = m_flSoundYaw; switch( GetSequence() ) { case TENTACLE_ANIM_Floor_Rear: case TENTACLE_ANIM_Floor_Rear_Idle: case TENTACLE_ANIM_Lev1_Rear: case TENTACLE_ANIM_Lev1_Rear_Idle: case TENTACLE_ANIM_Lev2_Rear: case TENTACLE_ANIM_Lev2_Rear_Idle: case TENTACLE_ANIM_Lev3_Rear: case TENTACLE_ANIM_Lev3_Rear_Idle: if (dy < 0 && dy > -m_flMaxYaw) dy = -m_flMaxYaw; if (dy > 0 && dy < m_flMaxYaw) dy = m_flMaxYaw; break; default: if (dy < -m_flMaxYaw) dy = -m_flMaxYaw; if (dy > m_flMaxYaw) dy = m_flMaxYaw; } GetMotor()->SetIdealYaw( m_flInitialYaw + dy ); if ( IsSequenceFinished() ) { // ALERT( at_console, "%s done %d %d\n", STRING( pev->targetname ), pev->sequence, m_iGoalAnim ); if ( m_iHealth <= 1) { m_iGoalAnim = TENTACLE_ANIM_Pit_Idle; if ( GetSequence() == TENTACLE_ANIM_Pit_Idle) { m_iHealth = 75; } } else if ( m_flSoundTime > gpGlobals->curtime ) { if (m_flSoundYaw >= -(m_flMaxYaw + 30) && m_flSoundYaw <= (m_flMaxYaw + 30)) { // strike switch ( m_iSoundLevel ) { case 0: m_iGoalAnim = SelectWeightedSequence ( ACT_1030 ); break; case 1: m_iGoalAnim = SelectWeightedSequence ( ACT_1031 ); break; case 2: m_iGoalAnim = SelectWeightedSequence ( ACT_1032 ); break; case 3: m_iGoalAnim = SelectWeightedSequence ( ACT_1033 ); break; } } else if (m_flSoundYaw >= -m_flMaxYaw * 2 && m_flSoundYaw <= m_flMaxYaw * 2) { // tap switch ( m_iSoundLevel ) { case 0: m_iGoalAnim = SelectWeightedSequence ( ACT_1020 ); break; case 1: m_iGoalAnim = SelectWeightedSequence ( ACT_1021 ); break; case 2: m_iGoalAnim = SelectWeightedSequence ( ACT_1022 ); break; case 3: m_iGoalAnim = SelectWeightedSequence ( ACT_1023 ); break; } } else { // go into rear idle switch ( m_iSoundLevel ) { case 0: m_iGoalAnim = SelectWeightedSequence ( ACT_1040 ); break; case 1: m_iGoalAnim = SelectWeightedSequence ( ACT_1041 ); break; case 2: m_iGoalAnim = SelectWeightedSequence ( ACT_1042 ); break; case 3: m_iGoalAnim = SelectWeightedSequence ( ACT_1043 ); break; case 4: m_iGoalAnim = SelectWeightedSequence ( ACT_1044 ); break; } } } else if ( GetSequence() == TENTACLE_ANIM_Pit_Idle) { // stay in pit until hear noise m_iGoalAnim = TENTACLE_ANIM_Pit_Idle; } else if ( GetSequence() == m_iGoalAnim) { if ( MyLevel() >= 0 && gpGlobals->curtime < m_flSoundTime) { if ( random->RandomInt(0,9) < m_flSoundTime - gpGlobals->curtime ) { // continue stike switch ( m_iSoundLevel ) { case 0: m_iGoalAnim = SelectWeightedSequence ( ACT_1030 ); break; case 1: m_iGoalAnim = SelectWeightedSequence ( ACT_1031 ); break; case 2: m_iGoalAnim = SelectWeightedSequence ( ACT_1032 ); break; case 3: m_iGoalAnim = SelectWeightedSequence ( ACT_1033 ); break; } } else { // tap switch ( m_iSoundLevel ) { case 0: m_iGoalAnim = SelectWeightedSequence ( ACT_1020 ); break; case 1: m_iGoalAnim = SelectWeightedSequence ( ACT_1021 ); break; case 2: m_iGoalAnim = SelectWeightedSequence ( ACT_1022 ); break; case 3: m_iGoalAnim = SelectWeightedSequence ( ACT_1023 ); break; } } } else if ( MyLevel( ) < 0 ) { m_iGoalAnim = SelectWeightedSequence( ACT_1010 ); } else { if (m_flNextSong < gpGlobals->curtime) { // play "I hear new something" sound CPASAttenuationFilter filter( this ); EmitSound( filter, entindex(), "Tentacle.Sing" ); m_flNextSong = gpGlobals->curtime + random->RandomFloat( 10, 20 ); } if (random->RandomInt(0,15) == 0) { // idle on new level switch ( random->RandomInt( 0, 3 ) ) { case 0: m_iGoalAnim = SelectWeightedSequence ( ACT_1010 ); break; case 1: m_iGoalAnim = SelectWeightedSequence ( ACT_1011 ); break; case 2: m_iGoalAnim = SelectWeightedSequence ( ACT_1012 ); break; case 3: m_iGoalAnim = SelectWeightedSequence ( ACT_1013 ); break; } } else if ( random->RandomInt( 0, 3 ) == 0 ) { // tap switch ( MyLevel() ) { case 0: m_iGoalAnim = SelectWeightedSequence ( ACT_1020 ); break; case 1: m_iGoalAnim = SelectWeightedSequence ( ACT_1021 ); break; case 2: m_iGoalAnim = SelectWeightedSequence ( ACT_1022 ); break; case 3: m_iGoalAnim = SelectWeightedSequence ( ACT_1023 ); break; } } else { // idle switch ( MyLevel() ) { case 0: m_iGoalAnim = SelectWeightedSequence ( ACT_1010 ); break; case 1: m_iGoalAnim = SelectWeightedSequence ( ACT_1011 ); break; case 2: m_iGoalAnim = SelectWeightedSequence ( ACT_1012 ); break; case 3: m_iGoalAnim = SelectWeightedSequence ( ACT_1013 ); break; } } } if (m_flSoundYaw < 0) m_flSoundYaw += random->RandomFloat( 2, 8 ); else m_flSoundYaw -= random->RandomFloat( 2, 8 ); } SetSequence( FindTransitionSequence( GetSequence(), m_iGoalAnim, &m_iDir ) ); if (m_iDir > 0) { SetCycle( 0 ); } else { m_iDir = -1; // just to safe SetCycle( 1.0f ); } ResetSequenceInfo( ); m_flFramerateAdj = random->RandomFloat( -0.2, 0.2 ); m_flPlaybackRate = m_iDir * 1.0 + m_flFramerateAdj; switch( GetSequence() ) { case TENTACLE_ANIM_Floor_Tap: case TENTACLE_ANIM_Lev1_Tap: case TENTACLE_ANIM_Lev2_Tap: case TENTACLE_ANIM_Lev3_Tap: { Vector vecSrc, v_forward; AngleVectors( GetAbsAngles(), &v_forward ); trace_t tr1, tr2; vecSrc = GetAbsOrigin() + Vector( 0, 0, MyHeight() - 4); UTIL_TraceLine( vecSrc, vecSrc + v_forward * 512, MASK_NPCSOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr1 ); vecSrc = GetAbsOrigin() + Vector( 0, 0, MyHeight() + 8); UTIL_TraceLine( vecSrc, vecSrc + v_forward * 512, MASK_NPCSOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr2 ); // ALERT( at_console, "%f %f\n", tr1.flFraction * 512, tr2.flFraction * 512 ); m_flTapRadius = SetPoseParameter( 0, random->RandomFloat( tr1.fraction * 512, tr2.fraction * 512 ) ); } break; default: m_flTapRadius = 336; // 400 - 64 break; } SetViewOffset( Vector( 0, 0, MyHeight() ) ); // ALERT( at_console, "seq %d\n", pev->sequence ); } if (m_flPrevSoundTime + 2.0 > gpGlobals->curtime) { // 1.5 normal speed if hears sounds m_flPlaybackRate = m_iDir * 1.5 + m_flFramerateAdj; } else if (m_flPrevSoundTime + 5.0 > gpGlobals->curtime) { // slowdown to normal m_flPlaybackRate = m_iDir + m_iDir * (5 - (gpGlobals->curtime - m_flPrevSoundTime)) / 2 + m_flFramerateAdj; } }