aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/server/hl2/npc_apcdriver.cpp
diff options
context:
space:
mode:
authorJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
committerJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
commit39ed87570bdb2f86969d4be821c94b722dc71179 (patch)
treeabc53757f75f40c80278e87650ea92808274aa59 /mp/src/game/server/hl2/npc_apcdriver.cpp
downloadsource-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz
source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/game/server/hl2/npc_apcdriver.cpp')
-rw-r--r--mp/src/game/server/hl2/npc_apcdriver.cpp298
1 files changed, 298 insertions, 0 deletions
diff --git a/mp/src/game/server/hl2/npc_apcdriver.cpp b/mp/src/game/server/hl2/npc_apcdriver.cpp
new file mode 100644
index 00000000..d8d1b1b8
--- /dev/null
+++ b/mp/src/game/server/hl2/npc_apcdriver.cpp
@@ -0,0 +1,298 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "npc_vehicledriver.h"
+#include "vehicle_apc.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+#define SF_APCDRIVER_NO_ROCKET_ATTACK 0x10000
+#define SF_APCDRIVER_NO_GUN_ATTACK 0x20000
+
+#define NPC_APCDRIVER_REMEMBER_TIME 4
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class CNPC_APCDriver : public CNPC_VehicleDriver
+{
+ DECLARE_CLASS( CNPC_APCDriver, CNPC_VehicleDriver );
+public:
+ DECLARE_DATADESC();
+ DEFINE_CUSTOM_AI;
+
+ virtual void Spawn( void );
+ virtual void Activate( void );
+
+ virtual bool FVisible( CBaseEntity *pTarget, int traceMask, CBaseEntity **ppBlocker );
+ virtual bool WeaponLOSCondition( const Vector &ownerPos, const Vector &targetPos, bool bSetConditions );
+ virtual Class_T Classify ( void ) { return CLASS_COMBINE; }
+ virtual void PrescheduleThink( );
+ virtual Disposition_t IRelationType(CBaseEntity *pTarget);
+
+ // AI
+ virtual int RangeAttack1Conditions( float flDot, float flDist );
+ virtual int RangeAttack2Conditions( float flDot, float flDist );
+
+private:
+ // Are we being carried by a dropship?
+ bool IsBeingCarried();
+
+ // Enable, disable firing
+ void InputEnableFiring( inputdata_t &inputdata );
+ void InputDisableFiring( inputdata_t &inputdata );
+
+ CHandle<CPropAPC> m_hAPC;
+ float m_flTimeLastSeenEnemy;
+ bool m_bFiringDisabled;
+};
+
+
+BEGIN_DATADESC( CNPC_APCDriver )
+
+ //DEFINE_FIELD( m_hAPC, FIELD_EHANDLE ),
+ DEFINE_FIELD( m_bFiringDisabled, FIELD_BOOLEAN ),
+ DEFINE_FIELD( m_flTimeLastSeenEnemy, FIELD_TIME ),
+
+ DEFINE_INPUTFUNC( FIELD_VOID, "EnableFiring", InputEnableFiring ),
+ DEFINE_INPUTFUNC( FIELD_VOID, "DisableFiring", InputDisableFiring ),
+
+END_DATADESC()
+
+LINK_ENTITY_TO_CLASS( npc_apcdriver, CNPC_APCDriver );
+
+
+//------------------------------------------------------------------------------
+// Purpose :
+//------------------------------------------------------------------------------
+void CNPC_APCDriver::Spawn( void )
+{
+ BaseClass::Spawn();
+
+ m_flTimeLastSeenEnemy = -NPC_APCDRIVER_REMEMBER_TIME;
+ CapabilitiesClear();
+ CapabilitiesAdd( bits_CAP_INNATE_RANGE_ATTACK1 | bits_CAP_INNATE_RANGE_ATTACK2 );
+ m_bFiringDisabled = false;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CNPC_APCDriver::Activate( void )
+{
+ BaseClass::Activate();
+
+ m_hAPC = dynamic_cast<CPropAPC*>((CBaseEntity*)m_hVehicleEntity);
+ if ( !m_hAPC )
+ {
+ Warning( "npc_apcdriver %s couldn't find his apc named %s.\n", STRING(GetEntityName()), STRING(m_iszVehicleName) );
+ UTIL_Remove( this );
+ return;
+ }
+ SetParent( m_hAPC );
+ SetAbsOrigin( m_hAPC->WorldSpaceCenter() );
+ SetLocalAngles( vec3_angle );
+
+ m_flDistTooFar = m_hAPC->MaxAttackRange();
+ SetDistLook( m_hAPC->MaxAttackRange() );
+}
+
+
+//-----------------------------------------------------------------------------
+// Enable, disable firing
+//-----------------------------------------------------------------------------
+void CNPC_APCDriver::InputEnableFiring( inputdata_t &inputdata )
+{
+ m_bFiringDisabled = false;
+}
+
+void CNPC_APCDriver::InputDisableFiring( inputdata_t &inputdata )
+{
+ m_bFiringDisabled = true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Let's not hate things the APC makes
+//-----------------------------------------------------------------------------
+Disposition_t CNPC_APCDriver::IRelationType(CBaseEntity *pTarget)
+{
+ if ( pTarget == m_hAPC || (pTarget->GetOwnerEntity() == m_hAPC) )
+ return D_LI;
+
+ return BaseClass::IRelationType(pTarget);
+}
+
+
+//------------------------------------------------------------------------------
+// Are we being carried by a dropship?
+//------------------------------------------------------------------------------
+bool CNPC_APCDriver::IsBeingCarried()
+{
+ // Inert if we're carried...
+ Vector vecVelocity;
+ m_hAPC->GetVelocity( &vecVelocity, NULL );
+ return ( m_hAPC->GetMoveParent() != NULL ) || (fabs(vecVelocity.z) >= 15);
+}
+
+
+
+//------------------------------------------------------------------------------
+// Is the enemy visible?
+//------------------------------------------------------------------------------
+bool CNPC_APCDriver::WeaponLOSCondition(const Vector &ownerPos, const Vector &targetPos, bool bSetConditions)
+{
+ if ( m_hAPC->m_lifeState != LIFE_ALIVE )
+ return false;
+
+ if ( IsBeingCarried() || m_bFiringDisabled )
+ return false;
+
+ float flTargetDist = ownerPos.DistTo( targetPos );
+ if (flTargetDist > m_hAPC->MaxAttackRange())
+ return false;
+
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Is the enemy visible?
+//-----------------------------------------------------------------------------
+bool CNPC_APCDriver::FVisible( CBaseEntity *pTarget, int traceMask, CBaseEntity **ppBlocker )
+{
+ if ( m_hAPC->m_lifeState != LIFE_ALIVE )
+ return false;
+
+ if ( IsBeingCarried() || m_bFiringDisabled )
+ return false;
+
+ float flTargetDist = GetAbsOrigin().DistTo( pTarget->GetAbsOrigin() );
+ if (flTargetDist > m_hAPC->MaxAttackRange())
+ return false;
+
+ bool bVisible = m_hAPC->FVisible( pTarget, traceMask, ppBlocker );
+ if ( bVisible && (pTarget == GetEnemy()) )
+ {
+ m_flTimeLastSeenEnemy = gpGlobals->curtime;
+ }
+
+ if ( pTarget->IsPlayer() || pTarget->Classify() == CLASS_BULLSEYE )
+ {
+ if (!bVisible)
+ {
+ if ( ( gpGlobals->curtime - m_flTimeLastSeenEnemy ) <= NPC_APCDRIVER_REMEMBER_TIME )
+ return true;
+ }
+ }
+
+ return bVisible;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input :
+// Output :
+//-----------------------------------------------------------------------------
+int CNPC_APCDriver::RangeAttack1Conditions( float flDot, float flDist )
+{
+ if ( HasSpawnFlags(SF_APCDRIVER_NO_GUN_ATTACK) )
+ return COND_NONE;
+
+ if ( m_hAPC->m_lifeState != LIFE_ALIVE )
+ return COND_NONE;
+
+ if ( IsBeingCarried() || m_bFiringDisabled )
+ return COND_NONE;
+
+ if ( !HasCondition( COND_SEE_ENEMY ) )
+ return COND_NONE;
+
+ if ( !m_hAPC->IsInPrimaryFiringCone() )
+ return COND_NONE;
+
+ // Vehicle not ready to fire again yet?
+ if ( m_pVehicleInterface->Weapon_PrimaryCanFireAt() > gpGlobals->curtime + 0.1f )
+ return COND_NONE;
+
+ float flMinDist, flMaxDist;
+ m_pVehicleInterface->Weapon_PrimaryRanges( &flMinDist, &flMaxDist );
+
+ if (flDist < flMinDist)
+ return COND_NONE;
+
+ if (flDist > flMaxDist)
+ return COND_NONE;
+
+ return COND_CAN_RANGE_ATTACK1;
+}
+
+int CNPC_APCDriver::RangeAttack2Conditions( float flDot, float flDist )
+{
+ if ( HasSpawnFlags(SF_APCDRIVER_NO_ROCKET_ATTACK) )
+ return COND_NONE;
+
+ if ( m_hAPC->m_lifeState != LIFE_ALIVE )
+ return COND_NONE;
+
+ if ( IsBeingCarried() || m_bFiringDisabled )
+ return COND_NONE;
+
+ if ( !HasCondition( COND_SEE_ENEMY ) )
+ return COND_NONE;
+
+ // Vehicle not ready to fire again yet?
+ if ( m_pVehicleInterface->Weapon_SecondaryCanFireAt() > gpGlobals->curtime + 0.1f )
+ return COND_NONE;
+
+ float flMinDist, flMaxDist;
+ m_pVehicleInterface->Weapon_SecondaryRanges( &flMinDist, &flMaxDist );
+
+ if (flDist < flMinDist)
+ return COND_NONE;
+
+ if (flDist > flMaxDist)
+ return COND_NONE;
+
+ return COND_CAN_RANGE_ATTACK2;
+}
+
+
+//-----------------------------------------------------------------------------
+// Aim the laser dot!
+//-----------------------------------------------------------------------------
+void CNPC_APCDriver::PrescheduleThink( )
+{
+ BaseClass::PrescheduleThink();
+
+ if ( m_hAPC->m_lifeState == LIFE_ALIVE )
+ {
+ if ( GetEnemy() )
+ {
+ m_hAPC->AimPrimaryWeapon( GetEnemy()->BodyTarget( GetAbsOrigin(), false ) );
+ }
+ m_hAPC->AimSecondaryWeaponAt( GetEnemy() );
+ }
+ else if ( m_hAPC->m_lifeState == LIFE_DEAD )
+ {
+ UTIL_Remove( this );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+//
+// Schedules
+//
+//-----------------------------------------------------------------------------
+AI_BEGIN_CUSTOM_NPC( npc_apcdriver, CNPC_APCDriver )
+
+AI_END_CUSTOM_NPC()