void CNPC_Dog::CreateBeams( void ) { if ( m_bBeamEffects == false ) { ClearBeams(); return; } CreateSprites(); for ( int i = 0; i < EFFECT_COUNT; i++ ) { if ( m_hBeams[i] ) continue; const char *attachNames[] = { "physgun", "thumb", "pinky", "index", }; m_hBeams[i] = CBeam::BeamCreate( "sprites/physcannon_bluelight2.vmt", 5.0 ); m_hBeams[i]->EntsInit( m_hPhysicsEnt, this ); m_hBeams[i]->SetEndAttachment( LookupAttachment( attachNames[i] ) ); m_hBeams[i]->SetBrightness( 255 ); m_hBeams[i]->SetColor( 255, 255, 255 ); m_hBeams[i]->SetNoise( 5.5 ); m_hBeams[i]->SetRenderMode( kRenderTransAdd ); } }
//========================================================= // IdleSound //========================================================= void CISlave::IdleSound(void) { if(RANDOM_LONG(0, 2) == 0) { SENTENCEG_PlayRndSz(ENT(pev), "SLV_IDLE", 0.85, ATTN_NORM, 0, m_voicePitch); } #if 0 int side = RANDOM_LONG( 0, 1 ) * 2 - 1; ClearBeams( ); ArmBeam( side ); UTIL_MakeAimVectors( pev->angles ); Vector vecSrc = pev->origin + gpGlobals->v_right * 2 * side; MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecSrc ); WRITE_BYTE(TE_DLIGHT); WRITE_COORD(vecSrc.x); // X WRITE_COORD(vecSrc.y); // Y WRITE_COORD(vecSrc.z); // Z WRITE_BYTE( 8 ); // radius * 0.1 WRITE_BYTE( 255 ); // r WRITE_BYTE( 180 ); // g WRITE_BYTE( 96 ); // b WRITE_BYTE( 10 ); // time * 10 WRITE_BYTE( 0 ); // decay * 0.1 MESSAGE_END( ); EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON, "debris/zap1.wav", 1, ATTN_NORM, 0, 100 ); #endif }
//========================================================= //========================================================= int CNPC_Vortigaunt::SelectSchedule( void ) { ClearBeams(); switch ( m_NPCState ) { case NPC_STATE_COMBAT: // dead enemy if ( HasCondition( COND_ENEMY_DEAD ) ) { // call base class, all code to handle dead enemies is centralized there. return BaseClass::SelectSchedule(); } if ( HasCondition( COND_CAN_RANGE_ATTACK1 ) ) return SCHED_RANGE_ATTACK1; if ( m_iHealth < 20 || m_iBravery < 0) { if ( !HasCondition( COND_CAN_MELEE_ATTACK1 ) ) { SetDefaultFailSchedule( SCHED_CHASE_ENEMY ); if ( HasCondition( COND_LIGHT_DAMAGE ) || HasCondition( COND_HEAVY_DAMAGE ) ) return SCHED_TAKE_COVER_FROM_ENEMY; if ( HasCondition ( COND_SEE_ENEMY ) && HasCondition ( COND_ENEMY_FACING_ME ) ) return SCHED_TAKE_COVER_FROM_ENEMY; } } break; } return BaseClass::SelectSchedule( ); }
//========================================================= //========================================================= Schedule_t *CISlave :: GetSchedule( void ) { ClearBeams( ); /* if (pev->spawnflags) { pev->spawnflags = 0; return GetScheduleOfType( SCHED_RELOAD ); } */ if ( HasConditions( bits_COND_HEAR_SOUND ) ) { CSound *pSound; pSound = PBestSound(); ASSERT( pSound != NULL ); if ( pSound && (pSound->m_iType & bits_SOUND_DANGER) ) return GetScheduleOfType( SCHED_TAKE_COVER_FROM_BEST_SOUND ); if ( pSound->m_iType & bits_SOUND_COMBAT ) m_afMemory |= bits_MEMORY_PROVOKED; } switch (m_MonsterState) { case MONSTERSTATE_COMBAT: // dead enemy if ( HasConditions( bits_COND_ENEMY_DEAD ) ) { // call base class, all code to handle dead enemies is centralized there. return CBaseMonster :: GetSchedule(); } if (pev->health < 20 || m_iBravery < 0) { if (!HasConditions( bits_COND_CAN_MELEE_ATTACK1 )) { m_failSchedule = SCHED_CHASE_ENEMY; if (HasConditions( bits_COND_LIGHT_DAMAGE | bits_COND_HEAVY_DAMAGE)) { return GetScheduleOfType( SCHED_TAKE_COVER_FROM_ENEMY ); } if ( HasConditions ( bits_COND_SEE_ENEMY ) && HasConditions ( bits_COND_ENEMY_FACING_ME ) ) { // ALERT( at_console, "exposed\n"); return GetScheduleOfType( SCHED_TAKE_COVER_FROM_ENEMY ); } } } break; default: break; } return CSquadMonster::GetSchedule( ); }
void CNPC_Dog::CleanCatchAndThrow( bool bClearTimers ) { if ( m_hPhysicsEnt ) { if ( m_bHasObject == true ) { IPhysicsObject *pPhysObj = m_hPhysicsEnt->VPhysicsGetObject(); m_hPhysicsEnt->SetParent( NULL ); m_hPhysicsEnt->SetOwnerEntity( NULL ); Vector vGunPos; QAngle angGunAngles; GetAttachment( m_iPhysGunAttachment, vGunPos, angGunAngles ); if ( pPhysObj ) { pPhysObj->Wake(); pPhysObj->RemoveShadowController(); pPhysObj->SetPosition( vGunPos, angGunAngles, true ); } else { Warning( "CleanCatchAndThrow: m_hPhysicsEnt->VPhysicsGetObject == NULL!\n" ); } m_hPhysicsEnt->SetMoveType( (MoveType_t)m_iContainerMoveType ); if ( pPhysObj ) { pPhysObj->RecheckCollisionFilter(); } ClearBeams(); } m_hPhysicsEnt = NULL; } if ( bClearTimers == true ) { m_bDoCatchThrowBehavior = false; m_bDoWaitforObjectBehavior = false; m_flTimeToCatch = 0.0f; m_flNextSwat = 0.0f; SetCondition( COND_DOG_LOST_PHYSICS_ENTITY ); } }
//--------------------------------------------------------- //--------------------------------------------------------- void CNPC_Dog::NPCThink( void ) { BaseClass::NPCThink(); if ( m_hPhysicsEnt == NULL ) { ClearBeams(); m_bHasObject = false; } if ( m_bHasObject == true ) { RelaxAim(); PullObject( true ); } // update follower bones m_BoneFollowerManager.UpdateBoneFollowers(this); }
//========================================================= // StartTask //========================================================= void CISlave::StartTask(Task_t *pTask) { ClearBeams(); CSquadMonster::StartTask(pTask); }
//========================================================= // HandleAnimEvent - catches the monster-specific messages // that occur when tagged animation frames are played. // // Returns number of events handled, 0 if none. //========================================================= void CISlave::HandleAnimEvent(MonsterEvent_t *pEvent) { // ALERT( at_console, "event %d : %f\n", pEvent->event, pev->frame ); switch(pEvent->event) { case ISLAVE_AE_CLAW: { // SOUND HERE! CBaseEntity *pHurt = CheckTraceHullAttack(70, gSkillData.slaveDmgClaw, DMG_SLASH); if(pHurt) { if(pHurt->pev->flags & (FL_MONSTER | FL_CLIENT)) { pHurt->pev->punchangle.z = -18; pHurt->pev->punchangle.x = 5; } // Play a random attack hit sound EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, pAttackHitSounds[RANDOM_LONG(0, ARRAYSIZE(pAttackHitSounds) - 1)], 1.0, ATTN_NORM, 0, m_voicePitch); } else { // Play a random attack miss sound EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, pAttackMissSounds[RANDOM_LONG(0, ARRAYSIZE(pAttackMissSounds) - 1)], 1.0, ATTN_NORM, 0, m_voicePitch); } } break; case ISLAVE_AE_CLAWRAKE: { CBaseEntity *pHurt = CheckTraceHullAttack(70, gSkillData.slaveDmgClawrake, DMG_SLASH); if(pHurt) { if(pHurt->pev->flags & (FL_MONSTER | FL_CLIENT)) { pHurt->pev->punchangle.z = -18; pHurt->pev->punchangle.x = 5; } EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, pAttackHitSounds[RANDOM_LONG(0, ARRAYSIZE(pAttackHitSounds) - 1)], 1.0, ATTN_NORM, 0, m_voicePitch); } else { EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, pAttackMissSounds[RANDOM_LONG(0, ARRAYSIZE(pAttackMissSounds) - 1)], 1.0, ATTN_NORM, 0, m_voicePitch); } } break; case ISLAVE_AE_ZAP_POWERUP: { // speed up attack when on hard if(g_iSkillLevel == SKILL_HARD) pev->framerate = 1.5; UTIL_MakeAimVectors(pev->angles); if(m_iBeams == 0) { Vector vecSrc = pev->origin + gpGlobals->v_forward * 2; MESSAGE_BEGIN(MSG_PVS, SVC_TEMPENTITY, vecSrc); WRITE_BYTE(TE_DLIGHT); WRITE_COORD(vecSrc.x); // X WRITE_COORD(vecSrc.y); // Y WRITE_COORD(vecSrc.z); // Z WRITE_BYTE(12); // radius * 0.1 WRITE_BYTE(255); // r WRITE_BYTE(180); // g WRITE_BYTE(96); // b WRITE_BYTE(20 / pev->framerate); // time * 10 WRITE_BYTE(0); // decay * 0.1 MESSAGE_END(); } if(m_hDead != NULL) { WackBeam(-1, m_hDead); WackBeam(1, m_hDead); } else { ArmBeam(-1); ArmBeam(1); BeamGlow(); } EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, "debris/zap4.wav", 1, ATTN_NORM, 0, 100 + m_iBeams * 10); pev->skin = m_iBeams / 2; } break; case ISLAVE_AE_ZAP_SHOOT: { ClearBeams(); if(m_hDead != NULL) { Vector vecDest = m_hDead->pev->origin + Vector(0, 0, 38); TraceResult trace; UTIL_TraceHull(vecDest, vecDest, dont_ignore_monsters, human_hull, m_hDead->edict(), &trace); if(!trace.fStartSolid) { CBaseEntity * pNew = Create("monster_alien_slave", m_hDead->pev->origin, m_hDead->pev->angles); CBaseMonster *pNewMonster = pNew->MyMonsterPointer(); pNew->pev->spawnflags |= 1; WackBeam(-1, pNew); WackBeam(1, pNew); UTIL_Remove(m_hDead); EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, "hassault/hw_shoot1.wav", 1, ATTN_NORM, 0, RANDOM_LONG(130, 160)); /* CBaseEntity *pEffect = Create( "test_effect", pNew->Center(), pev->angles ); pEffect->Use( this, this, USE_ON, 1 ); */ break; } } ClearMultiDamage(); UTIL_MakeAimVectors(pev->angles); ZapBeam(-1); ZapBeam(1); EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, "hassault/hw_shoot1.wav", 1, ATTN_NORM, 0, RANDOM_LONG(130, 160)); // STOP_SOUND( ENT(pev), CHAN_WEAPON, "debris/zap4.wav" ); ApplyMultiDamage(pev, pev); m_flNextAttack = gpGlobals->time + RANDOM_FLOAT(0.5, 4.0); } break; case ISLAVE_AE_ZAP_DONE: { ClearBeams(); } break; default: CSquadMonster::HandleAnimEvent(pEvent); break; } }
void CISlave::Killed(entvars_t *pevAttacker, int iGib) { ClearBeams(); CSquadMonster::Killed(pevAttacker, iGib); }
void CNPC_Dog::ThrowObject( const char *pAttachmentName ) { if ( m_hPhysicsEnt ) { m_bHasObject = false; IPhysicsObject *pPhysObj = m_hPhysicsEnt->VPhysicsGetObject(); if ( pPhysObj ) { Vector vGunPos; QAngle angGunAngles; AngularImpulse angVelocity = RandomAngularImpulse( -250 , -250 ) / pPhysObj->GetMass(); InvalidateBoneCache(); int iAttachment = LookupAttachment( pAttachmentName ); if ( iAttachment == 0 ) iAttachment = m_iPhysGunAttachment; GetAttachment( iAttachment, vGunPos, angGunAngles ); pPhysObj->Wake(); if ( pPhysObj->GetShadowController() ) { m_hPhysicsEnt->SetParent( NULL ); m_hPhysicsEnt->SetMoveType( (MoveType_t)m_iContainerMoveType ); m_hPhysicsEnt->SetOwnerEntity( this ); pPhysObj->RemoveShadowController(); pPhysObj->SetPosition( m_hPhysicsEnt->GetLocalOrigin(), m_hPhysicsEnt->GetLocalAngles(), true ); pPhysObj->RecheckCollisionFilter(); pPhysObj->RecheckContactPoints(); } if ( m_hThrowTarget == NULL ) #ifdef SecobMod__Enable_Fixed_Multiplayer_AI m_hThrowTarget = UTIL_GetNearestVisiblePlayer(this); #else m_hThrowTarget = AI_GetSinglePlayer(); #endif //SecobMod__Enable_Fixed_Multiplayer_AI Vector vThrowDirection; if ( m_hThrowTarget ) { Vector vThrowOrigin = m_hThrowTarget->GetAbsOrigin(); if ( m_hThrowTarget->IsPlayer() ) vThrowOrigin = vThrowOrigin + Vector( random->RandomFloat( -128, 128 ), random->RandomFloat( -128, 128 ), 0 ); Vector vecToss = VecCheckToss( this, vGunPos, vThrowOrigin, m_flThrowArcModifier, 1.0f, true ); if( vecToss == vec3_origin ) { // Fix up an impossible throw so dog will at least toss the box in the target's general direction instead of dropping it. // Also toss it up in the air so it will fall down and break. (Just throw the box up at a 45 degree angle) Vector forward, up; GetVectors( &forward, NULL, &up ); vecToss = forward + up; VectorNormalize( vecToss ); vecToss *= pPhysObj->GetMass() * 30.0f; } vThrowDirection = vecToss + ( m_hThrowTarget->GetSmoothedVelocity() / 2 ); Vector vLinearDrag; Vector unitVel = vThrowDirection; VectorNormalize( unitVel ); float flTest = 1000 / vThrowDirection.Length(); float flDrag = pPhysObj->CalculateLinearDrag( vThrowDirection ); vThrowDirection = vThrowDirection + ( unitVel * ( flDrag * flDrag ) ) / flTest; pPhysObj->SetVelocity( &vThrowDirection, &angVelocity ); m_flTimeToCatch = gpGlobals->curtime + dog_max_wait_time.GetFloat(); //Don't start pulling until the object is away from me. //We base the time on the throw velocity. m_flTimeToPull = gpGlobals->curtime + ( 1000 / vThrowDirection.Length() ); } //Fire Output! m_OnThrow.FireOutput( this, this ); ClearBeams(); if ( m_bBeamEffects == true ) { EmitSound( "Weapon_PhysCannon.Launch" ); CBeam *pBeam = CBeam::BeamCreate( "sprites/orangelight1.vmt", 1.8 ); if ( pBeam != NULL ) { pBeam->PointEntInit( m_hPhysicsEnt->WorldSpaceCenter(), this ); pBeam->SetEndAttachment( m_iPhysGunAttachment ); pBeam->SetWidth( 6.4 ); pBeam->SetEndWidth( 12.8 ); pBeam->SetBrightness( 255 ); pBeam->SetColor( 255, 255, 255 ); pBeam->LiveForTime( 0.2f ); pBeam->RelinkBeam(); pBeam->SetNoise( 2 ); } Vector shotDir = ( m_hPhysicsEnt->WorldSpaceCenter() - vGunPos ); VectorNormalize( shotDir ); CPVSFilter filter( m_hPhysicsEnt->WorldSpaceCenter() ); te->GaussExplosion( filter, 0.0f, m_hPhysicsEnt->WorldSpaceCenter() - ( shotDir * 4.0f ), RandomVector(-1.0f, 1.0f), 0 ); } } } }
void CNPC_Dog::PullObject( bool bMantain ) { if ( m_hPhysicsEnt == NULL ) { TaskFail( "Ack! No Phys Object!"); return; } IPhysicsObject *pPhysObj = m_hPhysicsEnt->VPhysicsGetObject(); if ( pPhysObj == NULL ) { TaskFail( "Pulling object with no Phys Object?!" ); return; } if( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) { m_bHasObject = false; ClearBeams(); TaskFail("Player Grabbed Ball"); return; } CreateBeams(); Vector vGunPos; GetAttachment( m_iPhysGunAttachment, vGunPos ); float flDistance = ( vGunPos - m_hPhysicsEnt->WorldSpaceCenter() ).Length(); if ( bMantain == false ) { if ( flDistance <= DOG_CATCH_DISTANCE ) { m_hPhysicsEnt->SetOwnerEntity( this ); GetNavigator()->StopMoving(); //Fire Output! m_OnPickup.FireOutput( this, this ); m_bHasObject = true; ClearBeams(); TaskComplete(); return; } } Vector vDir = ( vGunPos - m_hPhysicsEnt->WorldSpaceCenter() ); Vector vCurrentVel; float flCurrentVel; AngularImpulse vCurrentAI; pPhysObj->GetVelocity( &vCurrentVel, &vCurrentAI ); flCurrentVel = vCurrentVel.Length(); VectorNormalize( vCurrentVel ); VectorNormalize( vDir ); float flVelMod = DOG_PULL_VELOCITY_MOD; if ( bMantain == true ) flVelMod *= 2; vCurrentVel = vCurrentVel * flCurrentVel * flVelMod; vCurrentAI = vCurrentAI * DOG_PULL_ANGULARIMP_MOD; pPhysObj->SetVelocity( &vCurrentVel, &vCurrentAI ); vDir = vDir * flDistance * (DOG_PULL_TO_GUN_VEL_MOD * 2); Vector vAngle( 0, 0, 0 ); pPhysObj->AddVelocity( &vDir, &vAngle ); }
//--------------------------------------------------------- //--------------------------------------------------------- void CNPC_Dog::RunTask( const Task_t *pTask ) { switch( pTask->iTask ) { case TASK_DOG_PICKUP_ITEM: { PullObject( false ); } break; case TASK_DOG_GET_PATH_TO_PHYSOBJ: { //Check this cause our object might have been deleted. if ( m_hPhysicsEnt == NULL ) FindPhysicsObject( NULL ); //And if we still can't find anything, then just go away. if ( m_hPhysicsEnt == NULL ) { TaskFail( "Can't find an object I like!" ); return; } IPhysicsObject *pPhysicsObject = m_hPhysicsEnt->VPhysicsGetObject(); Vector vecGoalPos; Vector vecDir; vecDir = GetLocalOrigin() - m_hPhysicsEnt->WorldSpaceCenter(); VectorNormalize(vecDir); vecDir.z = 0; if ( m_hPhysicsEnt->GetOwnerEntity() == NULL ) m_hPhysicsEnt->SetOwnerEntity( this ); if ( pPhysicsObject ) pPhysicsObject->RecheckCollisionFilter(); vecGoalPos = m_hPhysicsEnt->WorldSpaceCenter() + (vecDir * DOG_PHYSOBJ_MOVE_TO_DIST ); bool bBuiltRoute = false; //If I'm near my goal, then just walk to it. Activity aActivity = ACT_RUN; if ( ( vecGoalPos - GetLocalOrigin() ).Length() <= 128 ) aActivity = ACT_WALK; bBuiltRoute = GetNavigator()->SetGoal( AI_NavGoal_t( vecGoalPos, aActivity ), AIN_NO_PATH_TASK_FAIL ); if ( bBuiltRoute == true ) TaskComplete(); else { m_flTimeToCatch = gpGlobals->curtime + 0.1; m_flNextRouteTime = gpGlobals->curtime + 0.3; m_flNextSwat = gpGlobals->curtime + 0.1; if ( m_hUnreachableObjects.Find( m_hPhysicsEnt ) == -1 ) m_hUnreachableObjects.AddToTail( m_hPhysicsEnt ); m_hPhysicsEnt = NULL; GetNavigator()->ClearGoal(); } } break; case TASK_WAIT: { if ( IsWaitFinished() ) { TaskComplete(); } if ( m_hPhysicsEnt ) { if ( m_bHasObject == false ) { GetMotor()->SetIdealYawToTarget( m_hPhysicsEnt->GetAbsOrigin() ); GetMotor()->UpdateYaw(); } } break; } case TASK_DOG_LAUNCH_ITEM: if( IsActivityFinished() ) { if ( m_hPhysicsEnt ) { m_hPhysicsEnt->SetOwnerEntity( NULL ); } TaskComplete(); } break; case TASK_DOG_WAIT_FOR_TARGET_TO_FACE: { if ( CanTargetSeeMe() ) TaskComplete(); } break; case TASK_WAIT_FOR_MOVEMENT: { if ( GetState() == NPC_STATE_SCRIPT || IsInAScript() ) { BaseClass::RunTask( pTask ); return; } if ( m_hPhysicsEnt != NULL ) { IPhysicsObject *pPhysObj = m_hPhysicsEnt->VPhysicsGetObject(); if ( !pPhysObj ) { Warning( "npc_dog TASK_WAIT_FOR_MOVEMENT with NULL m_hPhysicsEnt->VPhysicsGetObject\n" ); } if ( pPhysObj && pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) TaskFail( "Player picked it up!" ); //If the object is moving then my old goal might not be valid //cancel the schedule and make it restart again in a bit. if ( pPhysObj && pPhysObj->IsAsleep() == false && GetNavigator()->IsGoalActive() == false ) { Vector vecGoalPos; Vector vecDir; vecDir = GetLocalOrigin() - m_hPhysicsEnt->WorldSpaceCenter(); VectorNormalize(vecDir); vecDir.z = 0; vecGoalPos = m_hPhysicsEnt->WorldSpaceCenter() + (vecDir * DOG_PHYSOBJ_MOVE_TO_DIST ); GetNavigator()->ClearGoal(); float flDistance = (vecGoalPos - GetLocalOrigin()).Length(); //If I'm near my goal, then just walk to it. Activity aActivity = ACT_RUN; if ( ( vecGoalPos - GetLocalOrigin() ).Length() <= 128 ) aActivity = ACT_WALK; GetNavigator()->SetGoal( AI_NavGoal_t( vecGoalPos, aActivity ), AIN_NO_PATH_TASK_FAIL ); if ( flDistance <= DOG_PHYSOBJ_MOVE_TO_DIST ) { TaskComplete(); GetNavigator()->StopMoving(); } } } BaseClass::RunTask( pTask ); } break; case TASK_DOG_WAIT_FOR_OBJECT: { if ( m_hPhysicsEnt != NULL ) { if ( FVisible( m_hPhysicsEnt ) == false ) { m_flTimeToCatch = 0.0f; ClearBeams(); TaskFail( "Lost sight of the object!" ); m_hPhysicsEnt->SetOwnerEntity( NULL ); return; } m_hPhysicsEnt->SetOwnerEntity( this ); Vector vForward; AngleVectors( GetAbsAngles(), &vForward ); Vector vGunPos; GetAttachment( m_iPhysGunAttachment, vGunPos ); Vector vToObject = m_hPhysicsEnt->WorldSpaceCenter() - vGunPos; float flDistance = vToObject.Length(); VectorNormalize( vToObject ); SetAim( m_hPhysicsEnt->WorldSpaceCenter() - GetAbsOrigin() ); #ifdef SecobMod__Enable_Fixed_Multiplayer_AI CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(this); #else CBasePlayer *pPlayer = AI_GetSinglePlayer(); #endif //SecobMod__Enable_Fixed_Multiplayer_AI float flDistanceToPlayer = flDistance; if ( pPlayer ) { flDistanceToPlayer = (pPlayer->GetAbsOrigin() - m_hPhysicsEnt->WorldSpaceCenter()).Length(); } IPhysicsObject *pPhysObj = m_hPhysicsEnt->VPhysicsGetObject(); if ( !pPhysObj ) { Warning( "npc_dog: TASK_DOG_WAIT_FOR_OBJECT with m_hPhysicsEnt->VPhysicsGetObject == NULL\n" ); } if ( pPhysObj && !( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) && flDistanceToPlayer > ( flDistance * 2 ) ) { if ( m_flTimeToPull <= gpGlobals->curtime ) { Vector vCurrentVel; float flCurrentVel; AngularImpulse vCurrentAI; pPhysObj->GetVelocity( &vCurrentVel, &vCurrentAI ); flCurrentVel = vCurrentVel.Length(); VectorNormalize( vCurrentVel ); if ( pPhysObj && flDistance <= DOG_PULL_DISTANCE ) { Vector vDir = ( vGunPos - m_hPhysicsEnt->WorldSpaceCenter() ); VectorNormalize( vDir ); vCurrentVel = vCurrentVel * ( flCurrentVel * DOG_PULL_VELOCITY_MOD ); vCurrentAI = vCurrentAI * DOG_PULL_ANGULARIMP_MOD; pPhysObj->SetVelocity( &vCurrentVel, &vCurrentAI ); vDir = vDir * flDistance * DOG_PULL_TO_GUN_VEL_MOD; Vector vAngle( 0, 0, 0 ); pPhysObj->AddVelocity( &vDir, &vAngle ); CreateBeams(); } float flDot = DotProduct( vCurrentVel, vForward ); if ( flDistance >= DOG_PULL_DISTANCE && flDistance <= ( DOG_PULL_DISTANCE * 2 ) && flDot > -0.3 ) { if ( pPhysObj->IsAsleep() == false && !( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) ) { Vector vecGoalPos; Vector vecDir; vecDir = GetLocalOrigin() - m_hPhysicsEnt->WorldSpaceCenter(); VectorNormalize(vecDir); vecDir.z = 0; vecGoalPos = m_hPhysicsEnt->WorldSpaceCenter() + (vecDir * DOG_PHYSOBJ_MOVE_TO_DIST ); GetNavigator()->ClearGoal(); //If I'm near my goal, then just walk to it. Activity aActivity = ACT_RUN; if ( ( vecGoalPos - GetLocalOrigin() ).Length() <= 128 ) aActivity = ACT_WALK; GetNavigator()->SetGoal( AI_NavGoal_t( vecGoalPos, aActivity ), AIN_NO_PATH_TASK_FAIL ); } } } } float flDirDot = DotProduct( vToObject, vForward ); if ( flDirDot < 0.2 ) { GetMotor()->SetIdealYawToTarget( m_hPhysicsEnt->GetAbsOrigin() ); GetMotor()->UpdateYaw(); } if ( m_flTimeToCatch < gpGlobals->curtime && m_bDoWaitforObjectBehavior == false ) { m_hPhysicsEnt->SetOwnerEntity( NULL ); m_flTimeToCatch = 0.0f; ClearBeams(); TaskFail( "Done waiting!" ); } else if ( pPhysObj && ( flDistance <= DOG_CATCH_DISTANCE && !( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) ) ) { AngularImpulse vZero( 0, 0, 0 ); pPhysObj->SetVelocity( &vec3_origin, &vZero ); GetNavigator()->StopMoving(); //Fire Output! m_OnCatch.FireOutput( this, this ); m_bHasObject = true; ClearBeams(); TaskComplete(); } } else { GetNavigator()->StopMoving(); ClearBeams(); TaskFail("No Physics Object!"); } } break; case TASK_DOG_CATCH_OBJECT: if( IsActivityFinished() ) { m_flTimeToCatch = 0.0f; TaskComplete(); } break; default: BaseClass::RunTask( pTask ); break; } }
void CNPC_Vortigaunt::StartTask( const Task_t *pTask ) { ClearBeams(); BaseClass::StartTask( pTask ); }
//========================================================= // HandleAnimEvent - catches the monster-specific messages // that occur when tagged animation frames are played. // // Returns number of events handled, 0 if none. //========================================================= void CNPC_Vortigaunt::HandleAnimEvent( animevent_t *pEvent ) { // ALERT( at_console, "event %d : %f\n", pEvent->event, pev->frame ); switch( pEvent->event ) { case ISLAVE_AE_CLAW: { // SOUND HERE! CBaseEntity *pHurt = CheckTraceHullAttack( 40, Vector(-10,-10,-10), Vector(10,10,10), sk_islave_dmg_claw.GetFloat(), DMG_SLASH ); CPASAttenuationFilter filter( this ); if ( pHurt ) { if ( pHurt->GetFlags() & ( FL_NPC | FL_CLIENT ) ) pHurt->ViewPunch( QAngle( 5, 0, -18 ) ); // Play a random attack hit sound enginesound->EmitSound( filter, entindex(), CHAN_WEAPON, pAttackHitSounds[ random->RandomInt(0,ARRAYSIZE(pAttackHitSounds)-1) ], 1.0, ATTN_NORM, 0, m_iVoicePitch ); } else // Play a random attack miss sound enginesound->EmitSound( filter, entindex(), CHAN_WEAPON, pAttackMissSounds[ random->RandomInt(0,ARRAYSIZE(pAttackMissSounds)-1) ], 1.0, ATTN_NORM, 0, m_iVoicePitch ); } break; case ISLAVE_AE_CLAWRAKE: { CBaseEntity *pHurt = CheckTraceHullAttack( 40, Vector(-10,-10,-10), Vector(10,10,10), sk_islave_dmg_clawrake.GetFloat(), DMG_SLASH ); CPASAttenuationFilter filter2( this ); if ( pHurt ) { if ( pHurt->GetFlags() & ( FL_NPC | FL_CLIENT ) ) pHurt->ViewPunch( QAngle( 5, 0, 18 ) ); enginesound->EmitSound( filter2, entindex(), CHAN_WEAPON, pAttackHitSounds[ random->RandomInt(0,ARRAYSIZE(pAttackHitSounds)-1) ], 1.0, ATTN_NORM, 0, m_iVoicePitch ); } else enginesound->EmitSound( filter2, entindex(), CHAN_WEAPON, pAttackMissSounds[ random->RandomInt(0,ARRAYSIZE(pAttackMissSounds)-1) ], 1.0, ATTN_NORM, 0, m_iVoicePitch ); } break; case ISLAVE_AE_ZAP_POWERUP: { // speed up attack when on hard if ( g_iSkillLevel == SKILL_HARD ) m_flPlaybackRate = 1.5; Vector v_forward; GetVectors( &v_forward, NULL, NULL ); CBroadcastRecipientFilter filter; te->DynamicLight( filter, 0.0, &GetAbsOrigin(), 125, 200, 100, 2, 120, 0.2 / m_flPlaybackRate, 0 ); if ( m_hDead != NULL ) { WackBeam( -1, m_hDead ); WackBeam( 1, m_hDead ); } else { ArmBeam( -1 ); ArmBeam( 1 ); BeamGlow( ); } CPASAttenuationFilter filter3( this ); enginesound->EmitSound( filter3, entindex(), CHAN_WEAPON, "debris/zap4.wav", 1, ATTN_NORM, 0, 100 + m_iBeams * 10 ); // Huh? Model doesn't have multiple texturegroups, commented this out. -LH // m_nSkin = m_iBeams / 2; } break; case ISLAVE_AE_ZAP_SHOOT: { ClearBeams( ); if ( m_hDead != NULL ) { Vector vecDest = m_hDead->GetAbsOrigin() + Vector( 0, 0, 38 ); trace_t trace; UTIL_TraceHull( vecDest, vecDest, GetHullMins(), GetHullMaxs(),MASK_SOLID, m_hDead, COLLISION_GROUP_NONE, &trace ); if ( !trace.startsolid ) { CBaseEntity *pNew = Create( "monster_alien_slave", m_hDead->GetAbsOrigin(), m_hDead->GetAbsAngles() ); pNew->AddSpawnFlags( 1 ); WackBeam( -1, pNew ); WackBeam( 1, pNew ); UTIL_Remove( m_hDead ); break; } } ClearMultiDamage(); ZapBeam( -1 ); ZapBeam( 1 ); CPASAttenuationFilter filter4( this ); enginesound->EmitSound( filter4, entindex(), CHAN_WEAPON, "hassault/hw_shoot1.wav", 1, ATTN_NORM, 0, random->RandomInt( 130, 160 ) ); ApplyMultiDamage(); m_flNextAttack = gpGlobals->curtime + random->RandomFloat( 0.5, 4.0 ); } break; case ISLAVE_AE_ZAP_DONE: { ClearBeams(); } break; default: BaseClass::HandleAnimEvent( pEvent ); break; } }
void CNPC_Vortigaunt::Event_Killed( const CTakeDamageInfo &info ) { ClearBeams( ); BaseClass::Event_Killed( info ); }
void CISlave::Killed( entvars_t *pevAttacker, GibAction gibAction ) { ClearBeams( ); CSquadMonster::Killed( pevAttacker, gibAction ); }