source-engine/game/server/hl2/npc_manhack.h

282 lines
8.2 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef NPC_MANHACK_H
#define NPC_MANHACK_H
#ifdef _WIN32
#pragma once
#endif
#include "ai_basenpc_physicsflyer.h"
#include "Sprite.h"
#include "SpriteTrail.h"
#include "player_pickup.h"
// Start with the engine off and folded up.
#define SF_MANHACK_PACKED_UP (1 << 16)
#define SF_MANHACK_NO_DAMAGE_EFFECTS (1 << 17)
#define SF_MANHACK_USE_AIR_NODES (1 << 18)
#define SF_MANHACK_CARRIED (1 << 19) // Being carried by a metrocop
#define SF_MANHACK_NO_DANGER_SOUNDS (1 << 20)
enum
{
MANHACK_EYE_STATE_IDLE,
MANHACK_EYE_STATE_CHASE,
MANHACK_EYE_STATE_CHARGE,
MANHACK_EYE_STATE_STUNNED,
};
//-----------------------------------------------------------------------------
// Attachment points.
//-----------------------------------------------------------------------------
#define MANHACK_GIB_HEALTH 30
#define MANHACK_INACTIVE_HEALTH 25
#define MANHACK_MAX_SPEED 500
#define MANHACK_BURST_SPEED 650
#define MANHACK_NPC_BURST_SPEED 800
//-----------------------------------------------------------------------------
// Movement parameters.
//-----------------------------------------------------------------------------
#define MANHACK_WAYPOINT_DISTANCE 25 // Distance from waypoint that counts as arrival.
class CSprite;
class SmokeTrail;
class CSoundPatch;
//-----------------------------------------------------------------------------
// Manhack
//-----------------------------------------------------------------------------
class CNPC_Manhack : public CNPCBaseInteractive<CAI_BasePhysicsFlyingBot>, public CDefaultPlayerPickupVPhysics
{
DECLARE_CLASS( CNPC_Manhack, CNPCBaseInteractive<CAI_BasePhysicsFlyingBot> );
DECLARE_SERVERCLASS();
public:
CNPC_Manhack();
~CNPC_Manhack();
Class_T Classify(void);
bool CorpseGib( const CTakeDamageInfo &info );
void Event_Dying(void);
void Event_Killed( const CTakeDamageInfo &info );
int OnTakeDamage_Alive( const CTakeDamageInfo &info );
int OnTakeDamage_Dying( const CTakeDamageInfo &info );
void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator );
void TranslateNavGoal( CBaseEntity *pEnemy, Vector &chasePosition );
float GetDefaultNavGoalTolerance();
void UpdateOnRemove( void );
void KillSprites( float flDelay );
void OnStateChange( NPC_STATE OldState, NPC_STATE NewState );
virtual bool CreateVPhysics( void );
virtual void DeathSound( const CTakeDamageInfo &info );
virtual bool ShouldGib( const CTakeDamageInfo &info );
Activity NPC_TranslateActivity( Activity baseAct );
virtual int TranslateSchedule( int scheduleType );
int MeleeAttack1Conditions ( float flDot, float flDist );
void HandleAnimEvent( animevent_t *pEvent );
bool OverrideMove(float flInterval);
void MoveToTarget(float flInterval, const Vector &MoveTarget);
void MoveExecute_Alive(float flInterval);
void MoveExecute_Dead(float flInterval);
int MoveCollisionMask(void);
void TurnHeadRandomly( float flInterval );
void CrashTouch( CBaseEntity *pOther );
void StartEngine( bool fStartSound );
virtual Vector BodyTarget( const Vector &posSrc, bool bNoisy = true ) { return WorldSpaceCenter(); }
virtual float GetHeadTurnRate( void ) { return 45.0f; } // Degrees per second
void CheckCollisions(float flInterval);
virtual void GatherEnemyConditions( CBaseEntity *pEnemy );
void PlayFlySound(void);
virtual void StopLoopingSounds(void);
void Precache(void);
void RunTask( const Task_t *pTask );
void Spawn(void);
void Activate();
void StartTask( const Task_t *pTask );
void BladesInit();
void SoundInit( void );
void StartEye( void );
bool HandleInteraction(int interactionType, void* data, CBaseCombatCharacter* sourceEnt);
void PostNPCInit( void );
void GatherConditions();
void PrescheduleThink( void );
void SpinBlades(float flInterval);
void Slice( CBaseEntity *pHitEntity, float flInterval, trace_t &tr );
void Bump( CBaseEntity *pHitEntity, float flInterval, trace_t &tr );
void Splash( const Vector &vecSplashPos );
float ManhackMaxSpeed( void );
virtual void VPhysicsShadowCollision( int index, gamevcollisionevent_t *pEvent );
void VPhysicsCollision( int index, gamevcollisionevent_t *pEvent );
void HitPhysicsObject( CBaseEntity *pOther );
virtual void ClampMotorForces( Vector &linear, AngularImpulse &angular );
unsigned int PhysicsSolidMaskForEntity( void ) const;
// Create smoke trail!
void CreateSmokeTrail();
void DestroySmokeTrail();
void Ignite( float flFlameLifetime, bool bNPCOnly, float flSize, bool bCalledByLevelDesigner ) { return; }
void InputDisableSwarm( inputdata_t &inputdata );
void InputUnpack( inputdata_t &inputdata );
// CDefaultPlayerPickupVPhysics
virtual void OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason );
virtual void OnPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t Reason );
CBasePlayer *HasPhysicsAttacker( float dt );
float GetMaxEnginePower();
// INPCInteractive Functions
virtual bool CanInteractWith( CAI_BaseNPC *pUser ) { return false; } // Disabled for now (sjb)
virtual bool HasBeenInteractedWith() { return m_bHackedByAlyx; }
virtual void NotifyInteraction( CAI_BaseNPC *pUser )
{
// Turn the sprites off and on again so their colors will change.
KillSprites(0.0f);
m_bHackedByAlyx = true;
StartEye();
}
virtual void InputPowerdown( inputdata_t &inputdata )
{
m_iHealth = 0;
}
DEFINE_CUSTOM_AI;
DECLARE_DATADESC();
private:
bool IsInEffectiveTargetZone( CBaseEntity *pTarget );
void MaintainGroundHeight( void );
void StartBurst( const Vector &vecDirection );
void StopBurst( bool bInterruptSchedule = false );
void UpdatePanels( void );
void SetEyeState( int state );
void ShowHostile( bool hostile = true );
bool IsFlyingActivity( Activity baseAct );
// Computes the slice bounce velocity
void ComputeSliceBounceVelocity( CBaseEntity *pHitEntity, trace_t &tr );
// Take damage from being thrown by a physcannon
void TakeDamageFromPhyscannon( CBasePlayer *pPlayer );
// Take damage from a vehicle:
void TakeDamageFromVehicle( int index, gamevcollisionevent_t *pEvent );
// Take damage from physics impacts
void TakeDamageFromPhysicsImpact( int index, gamevcollisionevent_t *pEvent );
// Are we being held by the physcannon?
bool IsHeldByPhyscannon( );
void StartLoitering( const Vector &vecLoiterPosition );
void StopLoitering() { m_vecLoiterPosition = vec3_invalid; m_fTimeNextLoiterPulse = gpGlobals->curtime; }
bool IsLoitering() { return m_vecLoiterPosition != vec3_invalid; }
void Loiter();
//
// Movement variables.
//
Vector m_vForceVelocity; // Someone forced me to move
Vector m_vTargetBanking;
Vector m_vForceMoveTarget; // Will fly here
float m_fForceMoveTime; // If time is less than this
Vector m_vSwarmMoveTarget; // Will fly here
float m_fSwarmMoveTime; // If time is less than this
float m_fEnginePowerScale; // scale all thrust by this amount (usually 1.0!)
float m_flNextEngineSoundTime;
float m_flEngineStallTime;
float m_flNextBurstTime;
float m_flBurstDuration;
Vector m_vecBurstDirection;
float m_flWaterSuspendTime;
int m_nLastSpinSound;
// physics influence
CHandle<CBasePlayer> m_hPhysicsAttacker;
float m_flLastPhysicsInfluenceTime;
// Death
float m_fSparkTime;
float m_fSmokeTime;
bool m_bDirtyPitch; // indicates whether we want the sound pitch updated.(sjb)
bool m_bShowingHostile;
bool m_bBladesActive;
bool m_bIgnoreClipbrushes;
float m_flBladeSpeed;
CSprite *m_pEyeGlow;
CSprite *m_pLightGlow;
CHandle<SmokeTrail> m_hSmokeTrail;
CHandle<CBaseEntity> m_pPrevOwner;
int m_iPanel1;
int m_iPanel2;
int m_iPanel3;
int m_iPanel4;
int m_nLastWaterLevel;
bool m_bDoSwarmBehavior;
bool m_bGib;
bool m_bHeld;
bool m_bHackedByAlyx;
Vector m_vecLoiterPosition;
float m_fTimeNextLoiterPulse;
float m_flBumpSuppressTime;
CNetworkVar( int, m_nEnginePitch1 );
CNetworkVar( int, m_nEnginePitch2 );
CNetworkVar( float, m_flEnginePitch1Time );
CNetworkVar( float, m_flEnginePitch2Time );
};
#endif //NPC_MANHACK_H