source-engine/game/server/props.h
2022-03-01 23:00:42 +03:00

440 lines
15 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef PROPS_H
#define PROPS_H
#ifdef _WIN32
#pragma once
#endif
#include "props_shared.h"
#include "baseanimating.h"
#include "physics_bone_follower.h"
#include "player_pickup.h"
#include "positionwatcher.h"
//=============================================================================================================
// PROP TYPES
//=============================================================================================================
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CBaseProp : public CBaseAnimating
{
DECLARE_CLASS( CBaseProp, CBaseAnimating );
public:
void Spawn( void );
void Precache( void );
void Activate( void );
bool KeyValue( const char *szKeyName, const char *szValue );
void CalculateBlockLOS( void );
int ParsePropData( void );
void DrawDebugGeometryOverlays( void );
// Don't treat as a live target
virtual bool IsAlive( void ) { return false; }
virtual bool OverridePropdata() { return true; }
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CBreakableProp : public CBaseProp, public IBreakableWithPropData, public CDefaultPlayerPickupVPhysics
{
public:
CBreakableProp();
DECLARE_CLASS( CBreakableProp, CBaseProp );
DECLARE_SERVERCLASS();
DECLARE_DATADESC();
virtual void Spawn();
virtual void Precache();
virtual float GetAutoAimRadius() { return 24.0f; }
void BreakablePropTouch( CBaseEntity *pOther );
virtual int OnTakeDamage( const CTakeDamageInfo &info );
void Event_Killed( const CTakeDamageInfo &info );
void Break( CBaseEntity *pBreaker, const CTakeDamageInfo &info );
void BreakThink( void );
void AnimateThink( void );
virtual void PlayPuntSound();
void InputBreak( inputdata_t &inputdata );
void InputAddHealth( inputdata_t &inputdata );
void InputRemoveHealth( inputdata_t &inputdata );
void InputSetHealth( inputdata_t &inputdata );
int GetNumBreakableChunks( void ) { return m_iNumBreakableChunks; }
virtual bool OverridePropdata() { return false; }
virtual IPhysicsObject *GetRootPhysicsObjectForBreak();
bool PropDataOverrodeBlockLOS( void ) { return m_bBlockLOSSetByPropData; }
bool PropDataOverrodeAIWalkable( void ) { return m_bIsWalkableSetByPropData; }
virtual bool HasPreferredCarryAnglesForPlayer( CBasePlayer *pPlayer )
{
if ( HasInteraction( PROPINTER_PHYSGUN_LAUNCH_SPIN_Z ) )
return true;
return false;
}
virtual QAngle PreferredCarryAngles( void ) { return m_preferredCarryAngles; }
virtual void Ignite( float flFlameLifetime, bool bNPCOnly, float flSize = 0.0f, bool bCalledByLevelDesigner = false );
// Specific interactions
void HandleFirstCollisionInteractions( int index, gamevcollisionevent_t *pEvent );
void HandleInteractionStick( int index, gamevcollisionevent_t *pEvent );
void StickAtPosition( const Vector &stickPosition, const Vector &savePosition, const QAngle &saveAngles );
// Disable auto fading under dx7 or when level fades are specified
void DisableAutoFade();
public:
COutputEvent m_OnBreak;
COutputFloat m_OnHealthChanged;
COutputEvent m_OnTakeDamage;
float m_impactEnergyScale;
int m_iMinHealthDmg;
QAngle m_preferredCarryAngles;
public:
// IBreakableWithPropData
void SetDmgModBullet( float flDmgMod ) { m_flDmgModBullet = flDmgMod; }
void SetDmgModClub( float flDmgMod ) { m_flDmgModClub = flDmgMod; }
void SetDmgModExplosive( float flDmgMod ) { m_flDmgModExplosive = flDmgMod; }
float GetDmgModBullet( void ) { return m_flDmgModBullet; }
float GetDmgModClub( void ) { return m_flDmgModClub; }
float GetDmgModExplosive( void ) { return m_flDmgModExplosive; }
void SetExplosiveRadius( float flRadius ) { m_explodeRadius = flRadius; }
void SetExplosiveDamage( float flDamage ) { m_explodeDamage = flDamage; }
float GetExplosiveRadius( void ) { return m_explodeRadius; }
float GetExplosiveDamage( void ) { return m_explodeDamage; }
void SetPhysicsDamageTable( string_t iszTableName ) { m_iszPhysicsDamageTableName = iszTableName; }
string_t GetPhysicsDamageTable( void ) { return m_iszPhysicsDamageTableName; }
void SetBreakableModel( string_t iszModel ) { m_iszBreakableModel = iszModel; }
string_t GetBreakableModel( void ) { return m_iszBreakableModel; }
void SetBreakableSkin( int iSkin ) { m_iBreakableSkin = iSkin; }
int GetBreakableSkin( void ) { return m_iBreakableSkin; }
void SetBreakableCount( int iCount ) { m_iBreakableCount = iCount; }
int GetBreakableCount( void ) { return m_iBreakableCount; }
void SetMaxBreakableSize( int iSize ) { m_iMaxBreakableSize = iSize; }
int GetMaxBreakableSize( void ) { return m_iMaxBreakableSize; }
void SetPropDataBlocksLOS( bool bBlocksLOS ) { m_bBlockLOSSetByPropData = true; SetBlocksLOS( bBlocksLOS ); }
void SetPropDataIsAIWalkable( bool b ) { m_bIsWalkableSetByPropData = true; SetAIWalkable( b ); }
void SetBasePropData( string_t iszBase ) { m_iszBasePropData = iszBase; }
string_t GetBasePropData( void ) { return m_iszBasePropData; }
void SetInteraction( propdata_interactions_t Interaction ) { m_iInteractions |= (1 << Interaction); }
void RemoveInteraction( propdata_interactions_t Interaction ) { m_iInteractions &= ~(1 << Interaction); }
bool HasInteraction( propdata_interactions_t Interaction ) { return ( m_iInteractions & (1 << Interaction) ) != 0; }
void SetMultiplayerBreakMode( mp_break_t mode ) { m_mpBreakMode = mode; }
mp_break_t GetMultiplayerBreakMode( void ) const { return m_mpBreakMode; }
// derived by multiplayer phys props:
virtual void SetPhysicsMode(int iMode) {}
virtual int GetPhysicsMode() { return PHYSICS_MULTIPLAYER_SOLID; }
// Copy fade from another breakable prop
void CopyFadeFrom( CBreakableProp *pSource );
protected:
bool UpdateHealth( int iNewHealth, CBaseEntity *pActivator );
virtual void OnBreak( const Vector &vecVelocity, const AngularImpulse &angVel, CBaseEntity *pBreaker ) {}
protected:
unsigned int m_createTick;
float m_flPressureDelay;
EHANDLE m_hBreaker;
PerformanceMode_t m_PerformanceMode;
// Prop data storage
float m_flDmgModBullet;
float m_flDmgModClub;
float m_flDmgModExplosive;
string_t m_iszPhysicsDamageTableName;
string_t m_iszBreakableModel;
int m_iBreakableSkin;
int m_iBreakableCount;
int m_iMaxBreakableSize;
string_t m_iszBasePropData;
int m_iInteractions;
float m_explodeDamage;
float m_explodeRadius;
string_t m_iszBreakModelMessage;
// Count of how many pieces we'll break into, custom or generic
int m_iNumBreakableChunks;
void SetEnableMotionPosition( const Vector &position, const QAngle &angles );
bool GetEnableMotionPosition( Vector *pPosition, QAngle *pAngles );
void ClearEnableMotionPosition();
private:
CBaseEntity *FindEnableMotionFixup();
public:
virtual bool OnAttemptPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason );
virtual void OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason );
virtual void OnPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t reason );
virtual AngularImpulse PhysGunLaunchAngularImpulse();
virtual CBasePlayer *HasPhysicsAttacker( float dt );
#ifdef HL2_EPISODIC
void CreateFlare( float flLifetime );
#endif //HL2_EPISODIC
protected:
void SetPhysicsAttacker( CBasePlayer *pEntity, float flTime );
void CheckRemoveRagdolls();
private:
void InputEnablePhyscannonPickup( inputdata_t &inputdata );
void InputDisablePhyscannonPickup( inputdata_t &inputdata );
void InputEnablePuntSound( inputdata_t &inputdata ) { m_bUsePuntSound = true; }
void InputDisablePuntSound( inputdata_t &inputdata ) { m_bUsePuntSound = false; }
// Prevents fade scale from happening
void ForceFadeScaleToAlwaysVisible();
void RampToDefaultFadeScale();
private:
enum PhysgunState_t
{
PHYSGUN_MUST_BE_DETACHED = 0,
PHYSGUN_IS_DETACHING,
PHYSGUN_CAN_BE_GRABBED,
PHYSGUN_ANIMATE_ON_PULL,
PHYSGUN_ANIMATE_IS_ANIMATING,
PHYSGUN_ANIMATE_FINISHED,
PHYSGUN_ANIMATE_IS_PRE_ANIMATING,
PHYSGUN_ANIMATE_IS_POST_ANIMATING,
};
CHandle<CBasePlayer> m_hPhysicsAttacker;
float m_flLastPhysicsInfluenceTime;
bool m_bBlockLOSSetByPropData;
bool m_bIsWalkableSetByPropData;
bool m_bOriginalBlockLOS; // BlockLOS state before physgun pickup
char m_nPhysgunState; // Ripped-off state
COutputEvent m_OnPhysCannonDetach; // We've ripped it off!
COutputEvent m_OnPhysCannonAnimatePreStarted; // Started playing the pre-pull animation
COutputEvent m_OnPhysCannonAnimatePullStarted; // Player started the pull anim
COutputEvent m_OnPhysCannonAnimatePostStarted; // Started playing the post-pull animation
COutputEvent m_OnPhysCannonPullAnimFinished; // We've had our pull anim finished, or the post-pull has finished if there is one
float m_flDefaultFadeScale; // Things may temporarily change the fade scale, but this is its steady-state condition
mp_break_t m_mpBreakMode;
EHANDLE m_hLastAttacker; // Last attacker that harmed me.
EHANDLE m_hFlareEnt;
string_t m_iszPuntSound;
bool m_bUsePuntSound;
};
// Spawnflags
#define SF_DYNAMICPROP_USEHITBOX_FOR_RENDERBOX 64
#define SF_DYNAMICPROP_NO_VPHYSICS 128
#define SF_DYNAMICPROP_DISABLE_COLLISION 256
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CDynamicProp : public CBreakableProp, public IPositionWatcher
{
DECLARE_CLASS( CDynamicProp, CBreakableProp );
public:
DECLARE_SERVERCLASS();
DECLARE_DATADESC();
CDynamicProp();
void Spawn( void );
bool CreateVPhysics( void );
void CreateBoneFollowers();
void UpdateOnRemove( void );
void AnimThink( void );
void PropSetSequence( int nSequence );
void OnRestore( void );
bool OverridePropdata( void );
void HandleAnimEvent( animevent_t *pEvent );
// baseentity - watch dynamic hierarchy updates
virtual void SetParent( CBaseEntity* pNewParent, int iAttachment = -1 );
bool TestCollision( const Ray_t &ray, unsigned int mask, trace_t& trace );
// breakable prop
virtual IPhysicsObject *GetRootPhysicsObjectForBreak();
// IPositionWatcher
virtual void NotifyPositionChanged( CBaseEntity *pEntity );
// Input handlers
void InputSetAnimation( inputdata_t &inputdata );
void InputSetDefaultAnimation( inputdata_t &inputdata );
void InputTurnOn( inputdata_t &inputdata );
void InputTurnOff( inputdata_t &inputdata );
void InputDisableCollision( inputdata_t &inputdata );
void InputEnableCollision( inputdata_t &inputdata );
void InputSetPlaybackRate( inputdata_t &inputdata );
COutputEvent m_pOutputAnimBegun;
COutputEvent m_pOutputAnimOver;
string_t m_iszDefaultAnim;
int m_iGoalSequence;
int m_iTransitionDirection;
// Random animations
bool m_bRandomAnimator;
float m_flNextRandAnim;
float m_flMinRandAnimTime;
float m_flMaxRandAnimTime;
short m_nPendingSequence;
bool m_bStartDisabled;
bool m_bDisableBoneFollowers;
CNetworkVar( bool, m_bUseHitboxesForRenderBox );
protected:
void FinishSetSequence( int nSequence );
void PropSetAnim( const char *szAnim );
void BoneFollowerHierarchyChanged();
// Contained Bone Follower manager
CBoneFollowerManager m_BoneFollowerManager;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CPhysicsProp : public CBreakableProp
{
DECLARE_CLASS( CPhysicsProp, CBreakableProp );
DECLARE_SERVERCLASS();
public:
~CPhysicsProp();
CPhysicsProp( void )
{
}
void Spawn( void );
void Precache();
bool CreateVPhysics( void );
bool OverridePropdata( void );
virtual void VPhysicsUpdate( IPhysicsObject *pPhysics );
virtual void VPhysicsCollision( int index, gamevcollisionevent_t *pEvent );
void InputWake( inputdata_t &inputdata );
void InputSleep( inputdata_t &inputdata );
void InputEnableMotion( inputdata_t &inputdata );
void InputDisableMotion( inputdata_t &inputdata );
void InputDisableFloating( inputdata_t &inputdata );
void EnableMotion( void );
bool CanBePickedUpByPhyscannon( void );
void OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason );
void OnPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t reason );
bool GetPropDataAngles( const char *pKeyName, QAngle &vecAngles );
float GetCarryDistanceOffset( void );
int ObjectCaps();
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void GetMassCenter( Vector *pMassCenter );
float GetMass() const;
void ClearFlagsThink( void );
virtual int OnTakeDamage( const CTakeDamageInfo &info );
int DrawDebugTextOverlays(void);
bool IsGib();
DECLARE_DATADESC();
// Specific interactions
void HandleAnyCollisionInteractions( int index, gamevcollisionevent_t *pEvent );
string_t GetPhysOverrideScript( void ) { return m_iszOverrideScript; }
float GetMassScale( void ) { return m_massScale; }
private:
// Compute impulse to apply to the enabled entity.
void ComputeEnablingImpulse( int index, gamevcollisionevent_t *pEvent );
COutputEvent m_MotionEnabled;
COutputEvent m_OnAwakened;
COutputEvent m_OnPhysGunPickup;
COutputEvent m_OnPhysGunPunt;
COutputEvent m_OnPhysGunOnlyPickup;
COutputEvent m_OnPhysGunDrop;
COutputEvent m_OnPlayerUse;
COutputEvent m_OnPlayerPickup;
COutputEvent m_OnOutOfWorld;
float m_massScale;
float m_inertiaScale;
int m_damageType;
string_t m_iszOverrideScript;
int m_damageToEnableMotion;
float m_flForceToEnableMotion;
bool m_bThrownByPlayer;
bool m_bFirstCollisionAfterLaunch;
protected:
CNetworkVar( bool, m_bAwake );
};
// An interface so that objects parented to props can receive collision interaction events.
enum parentCollisionInteraction_t
{
COLLISIONINTER_PARENT_FIRST_IMPACT = 1,
};
abstract_class IParentPropInteraction
{
public:
virtual void OnParentCollisionInteraction( parentCollisionInteraction_t eType, int index, gamevcollisionevent_t *pEvent ) = 0;
virtual void OnParentPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t Reason ) = 0;
};
// Used by prop_physics_create and the server benchmark.
// pModelName should not include the "models/" prefix.
CPhysicsProp* CreatePhysicsProp( const char *pModelName, const Vector &vTraceStart, const Vector &vTraceEnd, const IHandleEntity *pTraceIgnore, bool bRequireVCollide, const char *pClassName="physics_prop" );
bool UTIL_CreateScaledPhysObject( CBaseAnimating *pInstance, float flScale );
float GetBreakableDamage( const CTakeDamageInfo &inputInfo, IBreakableWithPropData *pProp = NULL );
int PropBreakablePrecacheAll( string_t modelName );
extern ConVar func_breakdmg_bullet;
extern ConVar func_breakdmg_club;
extern ConVar func_breakdmg_explosive;
#endif // PROPS_H