From f56bb35301836e56582a575a75864392a0177875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20P=2E=20Tjern=C3=B8?= Date: Mon, 2 Dec 2013 19:31:46 -0800 Subject: Fix line endings. WHAMMY. --- mp/src/game/server/genericmonster.cpp | 944 +++++++++++++++++----------------- 1 file changed, 472 insertions(+), 472 deletions(-) (limited to 'mp/src/game/server/genericmonster.cpp') diff --git a/mp/src/game/server/genericmonster.cpp b/mp/src/game/server/genericmonster.cpp index 44c25de5..ed1be819 100644 --- a/mp/src/game/server/genericmonster.cpp +++ b/mp/src/game/server/genericmonster.cpp @@ -1,472 +1,472 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -// -//=============================================================================// -//========================================================= -// Generic NPC - purely for scripted sequence work. -//========================================================= -#include "cbase.h" -#include "npcevent.h" -#include "ai_basenpc.h" -#include "ai_hull.h" -#include "KeyValues.h" -#include "engine/IEngineSound.h" -#include "physics_bone_follower.h" -#include "ai_baseactor.h" -#include "ai_senses.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -// For holograms, make them not solid so the player can walk through them -#define SF_GENERICNPC_NOTSOLID (1 << 16) - -//========================================================= -// NPC's Anim Events Go Here -//========================================================= - -class CGenericNPC : public CAI_BaseNPC -{ -public: - DECLARE_CLASS( CGenericNPC, CAI_BaseNPC ); - - void Spawn( void ); - void Precache( void ); - float MaxYawSpeed( void ); - Class_T Classify ( void ); - void HandleAnimEvent( animevent_t *pEvent ); - int GetSoundInterests ( void ); - - void TempGunEffect( void ); -}; - -LINK_ENTITY_TO_CLASS( monster_generic, CGenericNPC ); - -//========================================================= -// Classify - indicates this NPC's place in the -// relationship table. -//========================================================= -Class_T CGenericNPC::Classify ( void ) -{ - return CLASS_NONE; -} - - -//========================================================= -// MaxYawSpeed - allows each sequence to have a different -// turn rate associated with it. -//========================================================= -float CGenericNPC::MaxYawSpeed ( void ) -{ - return 90; -} - -//--------------------------------------------------------- -// !!!TEMP -// !!!TEMP -// !!!TEMP -// !!!TEMP -// -// (sjb) -//--------------------------------------------------------- -void CGenericNPC::TempGunEffect( void ) -{ - QAngle vecAngle; - Vector vecDir, vecShot; - Vector vecMuzzle, vecButt; - - GetAttachment( 2, vecMuzzle, vecAngle ); - GetAttachment( 3, vecButt, vecAngle ); - - vecDir = vecMuzzle - vecButt; - VectorNormalize( vecDir ); - - // CPVSFilter filter( GetAbsOrigin() ); - //te->ShowLine( filter, 0.0, vecSpot, vecSpot + vecForward ); - //UTIL_Sparks( vecMuzzle ); - - bool fSound = false; - - if( random->RandomInt( 0, 3 ) == 0 ) - { - fSound = true; - } - - Vector start = vecMuzzle + vecDir * 64; - Vector end = vecMuzzle + vecDir * 4096; - UTIL_Tracer( start, end, 0, TRACER_DONT_USE_ATTACHMENT, 5500, fSound ); - CPASAttenuationFilter filter2( this, "GenericNPC.GunSound" ); - EmitSound( filter2, entindex(), "GenericNPC.GunSound" ); -} - - -//========================================================= -// HandleAnimEvent - catches the NPC-specific messages -// that occur when tagged animation frames are played. -//========================================================= -void CGenericNPC::HandleAnimEvent( animevent_t *pEvent ) -{ - switch( pEvent->event ) - { - case 1: - // TEMPORARLY. Makes the May 2001 sniper demo work (sjb) - TempGunEffect(); - break; - - default: - BaseClass::HandleAnimEvent( pEvent ); - break; - } -} - -//========================================================= -// GetSoundInterests - generic NPC can't hear. -//========================================================= -int CGenericNPC::GetSoundInterests ( void ) -{ - return NULL; -} - -//========================================================= -// Spawn -//========================================================= -void CGenericNPC::Spawn() -{ - Precache(); - - SetModel( STRING( GetModelName() ) ); - -/* - if ( FStrEq( STRING( GetModelName() ), "models/player.mdl" ) ) - UTIL_SetSize(this, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX); - else - UTIL_SetSize(this, VEC_HULL_MIN, VEC_HULL_MAX); -*/ - - if ( FStrEq( STRING( GetModelName() ), "models/player.mdl" ) || FStrEq( STRING( GetModelName() ), "models/holo.mdl" ) ) - UTIL_SetSize(this, VEC_HULL_MIN, VEC_HULL_MAX); - else - UTIL_SetSize(this, NAI_Hull::Mins(HULL_HUMAN), NAI_Hull::Maxs(HULL_HUMAN)); - - SetSolid( SOLID_BBOX ); - AddSolidFlags( FSOLID_NOT_STANDABLE ); - SetMoveType( MOVETYPE_STEP ); - m_bloodColor = BLOOD_COLOR_RED; - m_iHealth = 8; - m_flFieldOfView = 0.5;// indicates the width of this NPC's forward view cone ( as a dotproduct result ) - m_NPCState = NPC_STATE_NONE; - - CapabilitiesAdd( bits_CAP_MOVE_GROUND | bits_CAP_OPEN_DOORS ); - - NPCInit(); - if ( !HasSpawnFlags(SF_GENERICNPC_NOTSOLID) ) - { - trace_t tr; - UTIL_TraceEntity( this, GetAbsOrigin(), GetAbsOrigin(), MASK_SOLID, &tr ); - if ( tr.startsolid ) - { - Msg("Placed npc_generic in solid!!! (%s)\n", STRING(GetModelName()) ); - m_spawnflags |= SF_GENERICNPC_NOTSOLID; - } - } - - if ( HasSpawnFlags(SF_GENERICNPC_NOTSOLID) ) - { - AddSolidFlags( FSOLID_NOT_SOLID ); - m_takedamage = DAMAGE_NO; - VPhysicsDestroyObject(); - } -} - -//----------------------------------------------------------------------------- -// Purpose: precaches all resources this NPC needs -//----------------------------------------------------------------------------- -void CGenericNPC::Precache() -{ - BaseClass::Precache(); - - PrecacheModel( STRING( GetModelName() ) ); - - PrecacheScriptSound( "GenericNPC.GunSound" ); -} - -// a really large health is set to make sure these never die. -const int TOO_MUCH_HEALTH_TO_DIE = 1000; -//======================================================================================= -// Furniture: A dumb "NPC" that is uses in scripted sequences -// where an NPC needs to be frame locked with a prop. -//======================================================================================= -class CNPC_Furniture : public CAI_BaseActor -{ - DECLARE_CLASS( CNPC_Furniture, CAI_BaseActor ); - DECLARE_DATADESC(); -public: - void Spawn( void ); - void Precache( void ); - void Die( void ); - void UpdateEfficiency( bool bInPVS ) { SetEfficiency( ( GetSleepState() != AISS_AWAKE ) ? AIE_DORMANT : AIE_NORMAL ); SetMoveEfficiency( AIME_NORMAL ); } - Class_T Classify ( void ); - float MaxYawSpeed( void ){ return 0; } - virtual int ObjectCaps( void ); - bool CreateVPhysics( void ); - void NPCThink( void ); - void UpdateOnRemove( void ); - int SelectSchedule( void ); - void OnRestore( void ); - int OnTakeDamage( const CTakeDamageInfo &info ) - { - if ( m_iHealth <= info.GetDamage() ) - m_iHealth = info.GetDamage() + TOO_MUCH_HEALTH_TO_DIE; - return BaseClass::OnTakeDamage(info); - } - - void DrawDebugGeometryOverlays(void); - - void SetPlayerAvoidState( void ); - void InputDisablePlayerCollision( inputdata_t &inputdata ); - void InputEnablePlayerCollision( inputdata_t &inputdata ); - void UpdateBoneFollowerState( void ); - -private: - // Contained Bone Follower manager - CBoneFollowerManager m_BoneFollowerManager; -}; - -LINK_ENTITY_TO_CLASS( monster_furniture, CNPC_Furniture ); -LINK_ENTITY_TO_CLASS( npc_furniture, CNPC_Furniture ); - -//----------------------------------------------------------------------------- -// Save/load -//----------------------------------------------------------------------------- - -BEGIN_DATADESC( CNPC_Furniture ) - DEFINE_EMBEDDED( m_BoneFollowerManager ), - DEFINE_INPUTFUNC( FIELD_VOID, "DisablePlayerCollision", InputDisablePlayerCollision ), - DEFINE_INPUTFUNC( FIELD_VOID, "EnablePlayerCollision", InputEnablePlayerCollision ), - -END_DATADESC() - -//----------------------------------------------------------------------------- -// Purpose: This used to have something to do with bees flying, but -// now it only initializes moving furniture in scripted sequences -//----------------------------------------------------------------------------- -void CNPC_Furniture::Spawn( ) -{ - Precache(); - - SetModel( STRING(GetModelName()) ); - - SetMoveType( MOVETYPE_STEP ); - SetSolid( SOLID_BBOX ); - - // Our collision, if needed, will be done through bone followers - AddSolidFlags( FSOLID_NOT_SOLID ); - - SetBloodColor( DONT_BLEED ); - m_iHealth = TOO_MUCH_HEALTH_TO_DIE; //wow - m_takedamage = DAMAGE_AIM; - SetSequence( 0 ); - SetCycle( 0 ); - SetNavType( NAV_FLY ); - AddFlag( FL_FLY ); - - CapabilitiesAdd( bits_CAP_MOVE_FLY | bits_CAP_TURN_HEAD | bits_CAP_ANIMATEDFACE ); - - AddEFlags( EFL_NO_MEGAPHYSCANNON_RAGDOLL ); - -// pev->nextthink += 1.0; -// SetThink (WalkMonsterDelay); - - ResetSequenceInfo( ); - SetCycle( 0 ); - NPCInit(); - - // Furniture needs to block LOS - SetBlocksLOS( true ); - - // Furniture just wastes CPU doing sensing code, since all they do is idle and play scripts - GetSenses()->AddSensingFlags( SENSING_FLAGS_DONT_LOOK | SENSING_FLAGS_DONT_LISTEN ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CNPC_Furniture::Precache( void ) -{ - PrecacheModel( STRING( GetModelName() ) ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -int CNPC_Furniture::ObjectCaps( void ) -{ - // HL2 furniture transitions -#ifdef HL2_DLL - return CAI_BaseNPC::ObjectCaps(); -#else - return (CAI_BaseNPC::ObjectCaps() & ~FCAP_ACROSS_TRANSITION); -#endif -} - -//----------------------------------------------------------------------------- -// Purpose: Furniture is killed -//----------------------------------------------------------------------------- -void CNPC_Furniture::Die( void ) -{ - SetThink ( &CNPC_Furniture::SUB_Remove ); - SetNextThink( gpGlobals->curtime ); -} - -//----------------------------------------------------------------------------- -// Purpose: ID's Furniture as neutral (noone will attack it) -//----------------------------------------------------------------------------- -Class_T CNPC_Furniture::Classify ( void ) -{ - return CLASS_NONE; -} - -//------------------------------------------------------------------------------ -// Purpose: -//------------------------------------------------------------------------------ -bool CNPC_Furniture::CreateVPhysics( void ) -{ -#ifndef HL2_DLL - return false; -#endif - - if ( !m_BoneFollowerManager.GetNumBoneFollowers() ) - { - KeyValues *modelKeyValues = new KeyValues(""); - if ( modelKeyValues->LoadFromBuffer( modelinfo->GetModelName( GetModel() ), modelinfo->GetModelKeyValueText( GetModel() ) ) ) - { - // Do we have a bone follower section? - KeyValues *pkvBoneFollowers = modelKeyValues->FindKey("bone_followers"); - if ( pkvBoneFollowers ) - { - // Loop through the list and create the bone followers - KeyValues *pBone = pkvBoneFollowers->GetFirstSubKey(); - while ( pBone ) - { - // Add it to the list - const char *pBoneName = pBone->GetString(); - m_BoneFollowerManager.AddBoneFollower( this, pBoneName ); - - pBone = pBone->GetNextKey(); - } - } - } - modelKeyValues->deleteThis(); - } - - return true; -} - -void CNPC_Furniture::InputDisablePlayerCollision( inputdata_t &inputdata ) -{ - SetCollisionGroup( COLLISION_GROUP_NPC_ACTOR ); - UpdateBoneFollowerState(); -} - -void CNPC_Furniture::InputEnablePlayerCollision( inputdata_t &inputdata ) -{ - SetCollisionGroup( COLLISION_GROUP_NPC ); - UpdateBoneFollowerState(); -} - -void CNPC_Furniture::UpdateBoneFollowerState( void ) -{ - if ( m_BoneFollowerManager.GetNumBoneFollowers() ) - { - physfollower_t* pBone = m_BoneFollowerManager.GetBoneFollower( 0 ); - - if ( pBone && pBone->hFollower && pBone->hFollower->GetCollisionGroup() != GetCollisionGroup() ) - { - for ( int i = 0; i < m_BoneFollowerManager.GetNumBoneFollowers(); i++ ) - { - pBone = m_BoneFollowerManager.GetBoneFollower( i ); - - if ( pBone && pBone->hFollower ) - { - pBone->hFollower->SetCollisionGroup( GetCollisionGroup() ); - } - } - } - } -} - -void CNPC_Furniture::SetPlayerAvoidState( void ) -{ - -} -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CNPC_Furniture::NPCThink( void ) -{ - BaseClass::NPCThink(); - - // Update follower bones - m_BoneFollowerManager.UpdateBoneFollowers(this); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CNPC_Furniture::UpdateOnRemove( void ) -{ - m_BoneFollowerManager.DestroyBoneFollowers(); - - BaseClass::UpdateOnRemove(); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Output : int -//----------------------------------------------------------------------------- -int CNPC_Furniture::SelectSchedule( void ) -{ - switch( m_NPCState ) - { - case NPC_STATE_NONE: - case NPC_STATE_PRONE: - case NPC_STATE_IDLE: - case NPC_STATE_ALERT: - case NPC_STATE_COMBAT: - case NPC_STATE_DEAD: - return SCHED_WAIT_FOR_SCRIPT; - - case NPC_STATE_SCRIPT: - return BaseClass::SelectSchedule(); - - default: - DevWarning( 2, "Invalid State for SelectSchedule!\n" ); - break; - } - - return SCHED_FAIL; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CNPC_Furniture::OnRestore( void ) -{ - // Recreate any bone followers we have - CreateVPhysics(); - - BaseClass::OnRestore(); -} -void CNPC_Furniture::DrawDebugGeometryOverlays( void ) -{ - //ugh - if ( m_debugOverlays & OVERLAY_NPC_ZAP_BIT ) - { - m_debugOverlays &= ~OVERLAY_NPC_ZAP_BIT; - } - - BaseClass::DrawDebugGeometryOverlays(); -} +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +//========================================================= +// Generic NPC - purely for scripted sequence work. +//========================================================= +#include "cbase.h" +#include "npcevent.h" +#include "ai_basenpc.h" +#include "ai_hull.h" +#include "KeyValues.h" +#include "engine/IEngineSound.h" +#include "physics_bone_follower.h" +#include "ai_baseactor.h" +#include "ai_senses.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +// For holograms, make them not solid so the player can walk through them +#define SF_GENERICNPC_NOTSOLID (1 << 16) + +//========================================================= +// NPC's Anim Events Go Here +//========================================================= + +class CGenericNPC : public CAI_BaseNPC +{ +public: + DECLARE_CLASS( CGenericNPC, CAI_BaseNPC ); + + void Spawn( void ); + void Precache( void ); + float MaxYawSpeed( void ); + Class_T Classify ( void ); + void HandleAnimEvent( animevent_t *pEvent ); + int GetSoundInterests ( void ); + + void TempGunEffect( void ); +}; + +LINK_ENTITY_TO_CLASS( monster_generic, CGenericNPC ); + +//========================================================= +// Classify - indicates this NPC's place in the +// relationship table. +//========================================================= +Class_T CGenericNPC::Classify ( void ) +{ + return CLASS_NONE; +} + + +//========================================================= +// MaxYawSpeed - allows each sequence to have a different +// turn rate associated with it. +//========================================================= +float CGenericNPC::MaxYawSpeed ( void ) +{ + return 90; +} + +//--------------------------------------------------------- +// !!!TEMP +// !!!TEMP +// !!!TEMP +// !!!TEMP +// +// (sjb) +//--------------------------------------------------------- +void CGenericNPC::TempGunEffect( void ) +{ + QAngle vecAngle; + Vector vecDir, vecShot; + Vector vecMuzzle, vecButt; + + GetAttachment( 2, vecMuzzle, vecAngle ); + GetAttachment( 3, vecButt, vecAngle ); + + vecDir = vecMuzzle - vecButt; + VectorNormalize( vecDir ); + + // CPVSFilter filter( GetAbsOrigin() ); + //te->ShowLine( filter, 0.0, vecSpot, vecSpot + vecForward ); + //UTIL_Sparks( vecMuzzle ); + + bool fSound = false; + + if( random->RandomInt( 0, 3 ) == 0 ) + { + fSound = true; + } + + Vector start = vecMuzzle + vecDir * 64; + Vector end = vecMuzzle + vecDir * 4096; + UTIL_Tracer( start, end, 0, TRACER_DONT_USE_ATTACHMENT, 5500, fSound ); + CPASAttenuationFilter filter2( this, "GenericNPC.GunSound" ); + EmitSound( filter2, entindex(), "GenericNPC.GunSound" ); +} + + +//========================================================= +// HandleAnimEvent - catches the NPC-specific messages +// that occur when tagged animation frames are played. +//========================================================= +void CGenericNPC::HandleAnimEvent( animevent_t *pEvent ) +{ + switch( pEvent->event ) + { + case 1: + // TEMPORARLY. Makes the May 2001 sniper demo work (sjb) + TempGunEffect(); + break; + + default: + BaseClass::HandleAnimEvent( pEvent ); + break; + } +} + +//========================================================= +// GetSoundInterests - generic NPC can't hear. +//========================================================= +int CGenericNPC::GetSoundInterests ( void ) +{ + return NULL; +} + +//========================================================= +// Spawn +//========================================================= +void CGenericNPC::Spawn() +{ + Precache(); + + SetModel( STRING( GetModelName() ) ); + +/* + if ( FStrEq( STRING( GetModelName() ), "models/player.mdl" ) ) + UTIL_SetSize(this, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX); + else + UTIL_SetSize(this, VEC_HULL_MIN, VEC_HULL_MAX); +*/ + + if ( FStrEq( STRING( GetModelName() ), "models/player.mdl" ) || FStrEq( STRING( GetModelName() ), "models/holo.mdl" ) ) + UTIL_SetSize(this, VEC_HULL_MIN, VEC_HULL_MAX); + else + UTIL_SetSize(this, NAI_Hull::Mins(HULL_HUMAN), NAI_Hull::Maxs(HULL_HUMAN)); + + SetSolid( SOLID_BBOX ); + AddSolidFlags( FSOLID_NOT_STANDABLE ); + SetMoveType( MOVETYPE_STEP ); + m_bloodColor = BLOOD_COLOR_RED; + m_iHealth = 8; + m_flFieldOfView = 0.5;// indicates the width of this NPC's forward view cone ( as a dotproduct result ) + m_NPCState = NPC_STATE_NONE; + + CapabilitiesAdd( bits_CAP_MOVE_GROUND | bits_CAP_OPEN_DOORS ); + + NPCInit(); + if ( !HasSpawnFlags(SF_GENERICNPC_NOTSOLID) ) + { + trace_t tr; + UTIL_TraceEntity( this, GetAbsOrigin(), GetAbsOrigin(), MASK_SOLID, &tr ); + if ( tr.startsolid ) + { + Msg("Placed npc_generic in solid!!! (%s)\n", STRING(GetModelName()) ); + m_spawnflags |= SF_GENERICNPC_NOTSOLID; + } + } + + if ( HasSpawnFlags(SF_GENERICNPC_NOTSOLID) ) + { + AddSolidFlags( FSOLID_NOT_SOLID ); + m_takedamage = DAMAGE_NO; + VPhysicsDestroyObject(); + } +} + +//----------------------------------------------------------------------------- +// Purpose: precaches all resources this NPC needs +//----------------------------------------------------------------------------- +void CGenericNPC::Precache() +{ + BaseClass::Precache(); + + PrecacheModel( STRING( GetModelName() ) ); + + PrecacheScriptSound( "GenericNPC.GunSound" ); +} + +// a really large health is set to make sure these never die. +const int TOO_MUCH_HEALTH_TO_DIE = 1000; +//======================================================================================= +// Furniture: A dumb "NPC" that is uses in scripted sequences +// where an NPC needs to be frame locked with a prop. +//======================================================================================= +class CNPC_Furniture : public CAI_BaseActor +{ + DECLARE_CLASS( CNPC_Furniture, CAI_BaseActor ); + DECLARE_DATADESC(); +public: + void Spawn( void ); + void Precache( void ); + void Die( void ); + void UpdateEfficiency( bool bInPVS ) { SetEfficiency( ( GetSleepState() != AISS_AWAKE ) ? AIE_DORMANT : AIE_NORMAL ); SetMoveEfficiency( AIME_NORMAL ); } + Class_T Classify ( void ); + float MaxYawSpeed( void ){ return 0; } + virtual int ObjectCaps( void ); + bool CreateVPhysics( void ); + void NPCThink( void ); + void UpdateOnRemove( void ); + int SelectSchedule( void ); + void OnRestore( void ); + int OnTakeDamage( const CTakeDamageInfo &info ) + { + if ( m_iHealth <= info.GetDamage() ) + m_iHealth = info.GetDamage() + TOO_MUCH_HEALTH_TO_DIE; + return BaseClass::OnTakeDamage(info); + } + + void DrawDebugGeometryOverlays(void); + + void SetPlayerAvoidState( void ); + void InputDisablePlayerCollision( inputdata_t &inputdata ); + void InputEnablePlayerCollision( inputdata_t &inputdata ); + void UpdateBoneFollowerState( void ); + +private: + // Contained Bone Follower manager + CBoneFollowerManager m_BoneFollowerManager; +}; + +LINK_ENTITY_TO_CLASS( monster_furniture, CNPC_Furniture ); +LINK_ENTITY_TO_CLASS( npc_furniture, CNPC_Furniture ); + +//----------------------------------------------------------------------------- +// Save/load +//----------------------------------------------------------------------------- + +BEGIN_DATADESC( CNPC_Furniture ) + DEFINE_EMBEDDED( m_BoneFollowerManager ), + DEFINE_INPUTFUNC( FIELD_VOID, "DisablePlayerCollision", InputDisablePlayerCollision ), + DEFINE_INPUTFUNC( FIELD_VOID, "EnablePlayerCollision", InputEnablePlayerCollision ), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: This used to have something to do with bees flying, but +// now it only initializes moving furniture in scripted sequences +//----------------------------------------------------------------------------- +void CNPC_Furniture::Spawn( ) +{ + Precache(); + + SetModel( STRING(GetModelName()) ); + + SetMoveType( MOVETYPE_STEP ); + SetSolid( SOLID_BBOX ); + + // Our collision, if needed, will be done through bone followers + AddSolidFlags( FSOLID_NOT_SOLID ); + + SetBloodColor( DONT_BLEED ); + m_iHealth = TOO_MUCH_HEALTH_TO_DIE; //wow + m_takedamage = DAMAGE_AIM; + SetSequence( 0 ); + SetCycle( 0 ); + SetNavType( NAV_FLY ); + AddFlag( FL_FLY ); + + CapabilitiesAdd( bits_CAP_MOVE_FLY | bits_CAP_TURN_HEAD | bits_CAP_ANIMATEDFACE ); + + AddEFlags( EFL_NO_MEGAPHYSCANNON_RAGDOLL ); + +// pev->nextthink += 1.0; +// SetThink (WalkMonsterDelay); + + ResetSequenceInfo( ); + SetCycle( 0 ); + NPCInit(); + + // Furniture needs to block LOS + SetBlocksLOS( true ); + + // Furniture just wastes CPU doing sensing code, since all they do is idle and play scripts + GetSenses()->AddSensingFlags( SENSING_FLAGS_DONT_LOOK | SENSING_FLAGS_DONT_LISTEN ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CNPC_Furniture::Precache( void ) +{ + PrecacheModel( STRING( GetModelName() ) ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int CNPC_Furniture::ObjectCaps( void ) +{ + // HL2 furniture transitions +#ifdef HL2_DLL + return CAI_BaseNPC::ObjectCaps(); +#else + return (CAI_BaseNPC::ObjectCaps() & ~FCAP_ACROSS_TRANSITION); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: Furniture is killed +//----------------------------------------------------------------------------- +void CNPC_Furniture::Die( void ) +{ + SetThink ( &CNPC_Furniture::SUB_Remove ); + SetNextThink( gpGlobals->curtime ); +} + +//----------------------------------------------------------------------------- +// Purpose: ID's Furniture as neutral (noone will attack it) +//----------------------------------------------------------------------------- +Class_T CNPC_Furniture::Classify ( void ) +{ + return CLASS_NONE; +} + +//------------------------------------------------------------------------------ +// Purpose: +//------------------------------------------------------------------------------ +bool CNPC_Furniture::CreateVPhysics( void ) +{ +#ifndef HL2_DLL + return false; +#endif + + if ( !m_BoneFollowerManager.GetNumBoneFollowers() ) + { + KeyValues *modelKeyValues = new KeyValues(""); + if ( modelKeyValues->LoadFromBuffer( modelinfo->GetModelName( GetModel() ), modelinfo->GetModelKeyValueText( GetModel() ) ) ) + { + // Do we have a bone follower section? + KeyValues *pkvBoneFollowers = modelKeyValues->FindKey("bone_followers"); + if ( pkvBoneFollowers ) + { + // Loop through the list and create the bone followers + KeyValues *pBone = pkvBoneFollowers->GetFirstSubKey(); + while ( pBone ) + { + // Add it to the list + const char *pBoneName = pBone->GetString(); + m_BoneFollowerManager.AddBoneFollower( this, pBoneName ); + + pBone = pBone->GetNextKey(); + } + } + } + modelKeyValues->deleteThis(); + } + + return true; +} + +void CNPC_Furniture::InputDisablePlayerCollision( inputdata_t &inputdata ) +{ + SetCollisionGroup( COLLISION_GROUP_NPC_ACTOR ); + UpdateBoneFollowerState(); +} + +void CNPC_Furniture::InputEnablePlayerCollision( inputdata_t &inputdata ) +{ + SetCollisionGroup( COLLISION_GROUP_NPC ); + UpdateBoneFollowerState(); +} + +void CNPC_Furniture::UpdateBoneFollowerState( void ) +{ + if ( m_BoneFollowerManager.GetNumBoneFollowers() ) + { + physfollower_t* pBone = m_BoneFollowerManager.GetBoneFollower( 0 ); + + if ( pBone && pBone->hFollower && pBone->hFollower->GetCollisionGroup() != GetCollisionGroup() ) + { + for ( int i = 0; i < m_BoneFollowerManager.GetNumBoneFollowers(); i++ ) + { + pBone = m_BoneFollowerManager.GetBoneFollower( i ); + + if ( pBone && pBone->hFollower ) + { + pBone->hFollower->SetCollisionGroup( GetCollisionGroup() ); + } + } + } + } +} + +void CNPC_Furniture::SetPlayerAvoidState( void ) +{ + +} +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CNPC_Furniture::NPCThink( void ) +{ + BaseClass::NPCThink(); + + // Update follower bones + m_BoneFollowerManager.UpdateBoneFollowers(this); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CNPC_Furniture::UpdateOnRemove( void ) +{ + m_BoneFollowerManager.DestroyBoneFollowers(); + + BaseClass::UpdateOnRemove(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : int +//----------------------------------------------------------------------------- +int CNPC_Furniture::SelectSchedule( void ) +{ + switch( m_NPCState ) + { + case NPC_STATE_NONE: + case NPC_STATE_PRONE: + case NPC_STATE_IDLE: + case NPC_STATE_ALERT: + case NPC_STATE_COMBAT: + case NPC_STATE_DEAD: + return SCHED_WAIT_FOR_SCRIPT; + + case NPC_STATE_SCRIPT: + return BaseClass::SelectSchedule(); + + default: + DevWarning( 2, "Invalid State for SelectSchedule!\n" ); + break; + } + + return SCHED_FAIL; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CNPC_Furniture::OnRestore( void ) +{ + // Recreate any bone followers we have + CreateVPhysics(); + + BaseClass::OnRestore(); +} +void CNPC_Furniture::DrawDebugGeometryOverlays( void ) +{ + //ugh + if ( m_debugOverlays & OVERLAY_NPC_ZAP_BIT ) + { + m_debugOverlays &= ~OVERLAY_NPC_ZAP_BIT; + } + + BaseClass::DrawDebugGeometryOverlays(); +} -- cgit v1.2.3