mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2025-04-15 22:12:32 +03:00
More features for custom melee weapon
This commit is contained in:
parent
fa41a327e7
commit
31cd394cb7
@ -28,6 +28,15 @@
|
|||||||
IMPLEMENT_SERVERCLASS_ST( CBaseHLBludgeonWeapon, DT_BaseHLBludgeonWeapon )
|
IMPLEMENT_SERVERCLASS_ST( CBaseHLBludgeonWeapon, DT_BaseHLBludgeonWeapon )
|
||||||
END_SEND_TABLE()
|
END_SEND_TABLE()
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
BEGIN_DATADESC(CBaseHLBludgeonWeapon)
|
||||||
|
|
||||||
|
DEFINE_FIELD(m_flDelayedFire, FIELD_TIME),
|
||||||
|
DEFINE_FIELD(m_bShotDelayed, FIELD_BOOLEAN),
|
||||||
|
|
||||||
|
END_DATADESC()
|
||||||
|
#endif // MAPBASE
|
||||||
|
|
||||||
#define BLUDGEON_HULL_DIM 16
|
#define BLUDGEON_HULL_DIM 16
|
||||||
|
|
||||||
static const Vector g_bludgeonMins(-BLUDGEON_HULL_DIM,-BLUDGEON_HULL_DIM,-BLUDGEON_HULL_DIM);
|
static const Vector g_bludgeonMins(-BLUDGEON_HULL_DIM,-BLUDGEON_HULL_DIM,-BLUDGEON_HULL_DIM);
|
||||||
@ -39,6 +48,9 @@ static const Vector g_bludgeonMaxs(BLUDGEON_HULL_DIM,BLUDGEON_HULL_DIM,BLUDGEON_
|
|||||||
CBaseHLBludgeonWeapon::CBaseHLBludgeonWeapon()
|
CBaseHLBludgeonWeapon::CBaseHLBludgeonWeapon()
|
||||||
{
|
{
|
||||||
m_bFiresUnderwater = true;
|
m_bFiresUnderwater = true;
|
||||||
|
#ifdef MAPBASE
|
||||||
|
m_bShotDelayed = false;
|
||||||
|
#endif // MAPBASE
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -96,11 +108,19 @@ void CBaseHLBludgeonWeapon::ItemPostFrame( void )
|
|||||||
#ifdef MAPBASE
|
#ifdef MAPBASE
|
||||||
if (pOwner->HasSpawnFlags( SF_PLAYER_SUPPRESS_FIRING ))
|
if (pOwner->HasSpawnFlags( SF_PLAYER_SUPPRESS_FIRING ))
|
||||||
{
|
{
|
||||||
|
m_bShotDelayed = false;
|
||||||
WeaponIdle();
|
WeaponIdle();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
// See if we need to fire off our secondary round
|
||||||
|
if (m_bShotDelayed)
|
||||||
|
{
|
||||||
|
if (gpGlobals->curtime > m_flDelayedFire)
|
||||||
|
DelayedAttack();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
if ( (pOwner->m_nButtons & IN_ATTACK) && (m_flNextPrimaryAttack <= gpGlobals->curtime) )
|
if ( (pOwner->m_nButtons & IN_ATTACK) && (m_flNextPrimaryAttack <= gpGlobals->curtime) )
|
||||||
{
|
{
|
||||||
PrimaryAttack();
|
PrimaryAttack();
|
||||||
@ -239,7 +259,7 @@ Activity CBaseHLBludgeonWeapon::ChooseIntersectionPointAndActivity( trace_t &hit
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return ACT_VM_HITCENTER;
|
return GetPrimaryAttackActivity();
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -297,7 +317,6 @@ void CBaseHLBludgeonWeapon::ImpactEffect( trace_t &traceHit )
|
|||||||
UTIL_ImpactTrace( &traceHit, DMG_CLUB );
|
UTIL_ImpactTrace( &traceHit, DMG_CLUB );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Purpose : Starts the swing of the weapon and determines the animation
|
// Purpose : Starts the swing of the weapon and determines the animation
|
||||||
// Input : bIsSecondary - is this a secondary attack?
|
// Input : bIsSecondary - is this a secondary attack?
|
||||||
@ -320,10 +339,14 @@ void CBaseHLBludgeonWeapon::Swing( int bIsSecondary )
|
|||||||
|
|
||||||
Vector swingEnd = swingStart + forward * GetRange();
|
Vector swingEnd = swingStart + forward * GetRange();
|
||||||
UTIL_TraceLine( swingStart, swingEnd, MASK_SHOT_HULL, pOwner, COLLISION_GROUP_NONE, &traceHit );
|
UTIL_TraceLine( swingStart, swingEnd, MASK_SHOT_HULL, pOwner, COLLISION_GROUP_NONE, &traceHit );
|
||||||
Activity nHitActivity = ACT_VM_HITCENTER;
|
Activity nHitActivity = GetPrimaryAttackActivity();
|
||||||
|
|
||||||
// Like bullets, bludgeon traces have to trace against triggers.
|
// Like bullets, bludgeon traces have to trace against triggers.
|
||||||
CTakeDamageInfo triggerInfo( GetOwner(), GetOwner(), GetDamageForActivity( nHitActivity ), DMG_CLUB );
|
#ifdef MAPBASE
|
||||||
|
CTakeDamageInfo triggerInfo(GetOwner(), GetOwner(), GetDamageForActivity(nHitActivity), GetDamageType());
|
||||||
|
#else
|
||||||
|
CTakeDamageInfo triggerInfo(GetOwner(), GetOwner(), GetDamageForActivity(nHitActivity), DMG_CLUB);
|
||||||
|
#endif // MAPBASE
|
||||||
triggerInfo.SetDamagePosition( traceHit.startpos );
|
triggerInfo.SetDamagePosition( traceHit.startpos );
|
||||||
triggerInfo.SetDamageForce( forward );
|
triggerInfo.SetDamageForce( forward );
|
||||||
TraceAttackToTriggers( triggerInfo, traceHit.startpos, traceHit.endpos, forward );
|
TraceAttackToTriggers( triggerInfo, traceHit.startpos, traceHit.endpos, forward );
|
||||||
@ -374,31 +397,20 @@ void CBaseHLBludgeonWeapon::Swing( int bIsSecondary )
|
|||||||
{
|
{
|
||||||
nHitActivity = bIsSecondary ? ACT_VM_MISSCENTER2 : ACT_VM_MISSCENTER;
|
nHitActivity = bIsSecondary ? ACT_VM_MISSCENTER2 : ACT_VM_MISSCENTER;
|
||||||
|
|
||||||
|
#ifndef MAPBASE
|
||||||
// We want to test the first swing again
|
// We want to test the first swing again
|
||||||
Vector testEnd = swingStart + forward * GetRange();
|
Vector testEnd = swingStart + forward * GetRange();
|
||||||
|
|
||||||
#ifdef MAPBASE
|
|
||||||
// Sound has been moved here since we're using the other melee sounds now
|
|
||||||
WeaponSound( SINGLE );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// See if we happened to hit water
|
// See if we happened to hit water
|
||||||
ImpactWater( swingStart, testEnd );
|
ImpactWater(swingStart, testEnd);
|
||||||
|
#endif // !MAPBASE
|
||||||
}
|
}
|
||||||
|
#ifndef MAPBASE
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef MAPBASE
|
|
||||||
// Other melee sounds
|
|
||||||
if (traceHit.m_pEnt && traceHit.m_pEnt->IsWorld())
|
|
||||||
WeaponSound(MELEE_HIT_WORLD);
|
|
||||||
else if (traceHit.m_pEnt && !traceHit.m_pEnt->PassesDamageFilter(triggerInfo))
|
|
||||||
WeaponSound(MELEE_MISS);
|
|
||||||
else
|
|
||||||
WeaponSound(MELEE_HIT);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Hit( traceHit, nHitActivity, bIsSecondary ? true : false );
|
Hit( traceHit, nHitActivity, bIsSecondary ? true : false );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Send the anim
|
// Send the anim
|
||||||
SendWeaponAnim( nHitActivity );
|
SendWeaponAnim( nHitActivity );
|
||||||
@ -414,5 +426,125 @@ void CBaseHLBludgeonWeapon::Swing( int bIsSecondary )
|
|||||||
|
|
||||||
#ifdef MAPBASE
|
#ifdef MAPBASE
|
||||||
pOwner->SetAnimation( PLAYER_ATTACK1 );
|
pOwner->SetAnimation( PLAYER_ATTACK1 );
|
||||||
|
|
||||||
|
if (GetHitDelay() > 0.f)
|
||||||
|
{
|
||||||
|
//Play swing sound
|
||||||
|
WeaponSound(SINGLE);
|
||||||
|
|
||||||
|
m_flDelayedFire = gpGlobals->curtime + GetHitDelay();
|
||||||
|
m_bShotDelayed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (traceHit.fraction == 1.0f)
|
||||||
|
{
|
||||||
|
// We want to test the first swing again
|
||||||
|
Vector testEnd = swingStart + forward * GetRange();
|
||||||
|
|
||||||
|
//Play swing sound
|
||||||
|
WeaponSound(SINGLE);
|
||||||
|
|
||||||
|
// See if we happened to hit water
|
||||||
|
ImpactWater(swingStart, testEnd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Other melee sounds
|
||||||
|
if (traceHit.m_pEnt && traceHit.m_pEnt->IsWorld())
|
||||||
|
WeaponSound(MELEE_HIT_WORLD);
|
||||||
|
else if (traceHit.m_pEnt && !traceHit.m_pEnt->PassesDamageFilter(triggerInfo))
|
||||||
|
WeaponSound(MELEE_MISS);
|
||||||
|
else
|
||||||
|
WeaponSound(MELEE_HIT);
|
||||||
|
|
||||||
|
Hit(traceHit, nHitActivity, bIsSecondary ? true : false);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
void CBaseHLBludgeonWeapon::DelayedAttack(void)
|
||||||
|
{
|
||||||
|
m_bShotDelayed = false;
|
||||||
|
|
||||||
|
trace_t traceHit;
|
||||||
|
|
||||||
|
// Try a ray
|
||||||
|
CBasePlayer* pOwner = ToBasePlayer(GetOwner());
|
||||||
|
if (!pOwner)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pOwner->RumbleEffect(RUMBLE_CROWBAR_SWING, 0, RUMBLE_FLAG_RESTART);
|
||||||
|
|
||||||
|
Vector swingStart = pOwner->Weapon_ShootPosition();
|
||||||
|
Vector forward;
|
||||||
|
|
||||||
|
forward = pOwner->GetAutoaimVector(AUTOAIM_SCALE_DEFAULT, GetRange());
|
||||||
|
|
||||||
|
Vector swingEnd = swingStart + forward * GetRange();
|
||||||
|
UTIL_TraceLine(swingStart, swingEnd, MASK_SHOT_HULL, pOwner, COLLISION_GROUP_NONE, &traceHit);
|
||||||
|
|
||||||
|
if (traceHit.fraction == 1.0)
|
||||||
|
{
|
||||||
|
float bludgeonHullRadius = 1.732f * BLUDGEON_HULL_DIM; // hull is +/- 16, so use cuberoot of 2 to determine how big the hull is from center to the corner point
|
||||||
|
|
||||||
|
// Back off by hull "radius"
|
||||||
|
swingEnd -= forward * bludgeonHullRadius;
|
||||||
|
|
||||||
|
UTIL_TraceHull(swingStart, swingEnd, g_bludgeonMins, g_bludgeonMaxs, MASK_SHOT_HULL, pOwner, COLLISION_GROUP_NONE, &traceHit);
|
||||||
|
if (traceHit.fraction < 1.0 && traceHit.m_pEnt)
|
||||||
|
{
|
||||||
|
Vector vecToTarget = traceHit.m_pEnt->GetAbsOrigin() - swingStart;
|
||||||
|
VectorNormalize(vecToTarget);
|
||||||
|
|
||||||
|
float dot = vecToTarget.Dot(forward);
|
||||||
|
|
||||||
|
// YWB: Make sure they are sort of facing the guy at least...
|
||||||
|
if (dot < 0.70721f)
|
||||||
|
{
|
||||||
|
// Force amiss
|
||||||
|
traceHit.fraction = 1.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ChooseIntersectionPointAndActivity(traceHit, g_bludgeonMins, g_bludgeonMaxs, pOwner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (traceHit.fraction == 1.0f)
|
||||||
|
{
|
||||||
|
// We want to test the first swing again
|
||||||
|
Vector testEnd = swingStart + forward * GetRange();
|
||||||
|
|
||||||
|
// See if we happened to hit water
|
||||||
|
ImpactWater(swingStart, testEnd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CTakeDamageInfo triggerInfo(GetOwner(), GetOwner(), GetDamageForActivity(GetActivity()), GetDamageType());
|
||||||
|
triggerInfo.SetDamagePosition(traceHit.startpos);
|
||||||
|
triggerInfo.SetDamageForce(forward);
|
||||||
|
|
||||||
|
// Other melee sounds
|
||||||
|
if (traceHit.m_pEnt && traceHit.m_pEnt->IsWorld())
|
||||||
|
WeaponSound(MELEE_HIT_WORLD);
|
||||||
|
else if (traceHit.m_pEnt && !traceHit.m_pEnt->PassesDamageFilter(triggerInfo))
|
||||||
|
WeaponSound(MELEE_MISS);
|
||||||
|
else
|
||||||
|
WeaponSound(MELEE_HIT);
|
||||||
|
|
||||||
|
Hit(traceHit, GetActivity(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CBaseHLBludgeonWeapon::CanHolster(void)
|
||||||
|
{
|
||||||
|
if (m_bShotDelayed)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return BaseClass::CanHolster();
|
||||||
|
}
|
||||||
|
#endif // MAPBASE
|
||||||
|
@ -23,6 +23,9 @@ public:
|
|||||||
CBaseHLBludgeonWeapon();
|
CBaseHLBludgeonWeapon();
|
||||||
|
|
||||||
DECLARE_SERVERCLASS();
|
DECLARE_SERVERCLASS();
|
||||||
|
#ifdef MAPBASE
|
||||||
|
DECLARE_DATADESC();
|
||||||
|
#endif // MAPBASE
|
||||||
|
|
||||||
virtual void Spawn( void );
|
virtual void Spawn( void );
|
||||||
virtual void Precache( void );
|
virtual void Precache( void );
|
||||||
@ -30,6 +33,9 @@ public:
|
|||||||
//Attack functions
|
//Attack functions
|
||||||
virtual void PrimaryAttack( void );
|
virtual void PrimaryAttack( void );
|
||||||
virtual void SecondaryAttack( void );
|
virtual void SecondaryAttack( void );
|
||||||
|
#ifdef MAPBASE
|
||||||
|
void DelayedAttack(void);
|
||||||
|
#endif // MAPBASE
|
||||||
|
|
||||||
virtual void ItemPostFrame( void );
|
virtual void ItemPostFrame( void );
|
||||||
|
|
||||||
@ -46,6 +52,8 @@ public:
|
|||||||
|
|
||||||
#ifdef MAPBASE
|
#ifdef MAPBASE
|
||||||
virtual int GetDamageType() { return DMG_CLUB; }
|
virtual int GetDamageType() { return DMG_CLUB; }
|
||||||
|
virtual float GetHitDelay() { return 0.f; }
|
||||||
|
virtual bool CanHolster(void);
|
||||||
#endif // MAPBASE
|
#endif // MAPBASE
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -56,6 +64,11 @@ private:
|
|||||||
void Swing( int bIsSecondary );
|
void Swing( int bIsSecondary );
|
||||||
void Hit( trace_t &traceHit, Activity nHitActivity, bool bIsSecondary );
|
void Hit( trace_t &traceHit, Activity nHitActivity, bool bIsSecondary );
|
||||||
Activity ChooseIntersectionPointAndActivity( trace_t &hitTrace, const Vector &mins, const Vector &maxs, CBasePlayer *pOwner );
|
Activity ChooseIntersectionPointAndActivity( trace_t &hitTrace, const Vector &mins, const Vector &maxs, CBasePlayer *pOwner );
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
float m_flDelayedFire;
|
||||||
|
bool m_bShotDelayed;
|
||||||
|
#endif // MAPBASE
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -55,6 +55,8 @@ typedef struct HL2CustomMeleeData_s
|
|||||||
float m_flRefireRate;
|
float m_flRefireRate;
|
||||||
float m_flDamage;
|
float m_flDamage;
|
||||||
float m_flNPCDamage;
|
float m_flNPCDamage;
|
||||||
|
float m_flHitDelay;
|
||||||
|
Activity m_nHitActivity = ACT_INVALID;
|
||||||
byte m_nDamageClass;
|
byte m_nDamageClass;
|
||||||
|
|
||||||
bool Parse(KeyValues*);
|
bool Parse(KeyValues*);
|
||||||
@ -72,6 +74,7 @@ public:
|
|||||||
|
|
||||||
float GetRange(void) { return m_CustomData.m_flMeleeRange; }
|
float GetRange(void) { return m_CustomData.m_flMeleeRange; }
|
||||||
float GetFireRate(void) { return m_CustomData.m_flRefireRate; }
|
float GetFireRate(void) { return m_CustomData.m_flRefireRate; }
|
||||||
|
float GetHitDelay() { return m_CustomData.m_flHitDelay; }
|
||||||
|
|
||||||
void AddViewKick(void);
|
void AddViewKick(void);
|
||||||
float GetDamageForActivity(Activity hitActivity);
|
float GetDamageForActivity(Activity hitActivity);
|
||||||
@ -86,6 +89,9 @@ public:
|
|||||||
acttable_t* GetBackupActivityList() { return NULL; }
|
acttable_t* GetBackupActivityList() { return NULL; }
|
||||||
int GetBackupActivityListCount() { return 0; }
|
int GetBackupActivityListCount() { return 0; }
|
||||||
|
|
||||||
|
//Functions to select animation sequences
|
||||||
|
virtual Activity GetPrimaryAttackActivity(void) { return m_CustomData.m_nHitActivity; }
|
||||||
|
|
||||||
const char* GetWeaponScriptName() { return m_iszWeaponScriptName.Get(); }
|
const char* GetWeaponScriptName() { return m_iszWeaponScriptName.Get(); }
|
||||||
virtual int GetDamageType() { return g_nDamageClassTypeBits[m_CustomData.m_nDamageClass]; }
|
virtual int GetDamageType() { return g_nDamageClassTypeBits[m_CustomData.m_nDamageClass]; }
|
||||||
|
|
||||||
@ -116,6 +122,16 @@ bool HL2CustomMeleeData_s::Parse(KeyValues* pKVWeapon)
|
|||||||
m_flNPCDamage = pkvData->GetFloat("damage_npc", m_flDamage);
|
m_flNPCDamage = pkvData->GetFloat("damage_npc", m_flDamage);
|
||||||
m_flMeleeRange = pkvData->GetFloat("range", 70.f);
|
m_flMeleeRange = pkvData->GetFloat("range", 70.f);
|
||||||
m_flRefireRate = pkvData->GetFloat("rate", 0.7f);
|
m_flRefireRate = pkvData->GetFloat("rate", 0.7f);
|
||||||
|
m_flHitDelay = pkvData->GetFloat("hitdelay");
|
||||||
|
if (pkvData->FindKey("activity_hit"))
|
||||||
|
{
|
||||||
|
m_nHitActivity = (Activity)ActivityList_IndexForName(pkvData->GetString("activity_hit"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_nHitActivity == ACT_INVALID)
|
||||||
|
{
|
||||||
|
m_nHitActivity = ACT_VM_HITCENTER;
|
||||||
|
}
|
||||||
|
|
||||||
const char* pszDamageClass = pkvData->GetString("damage_type", nullptr);
|
const char* pszDamageClass = pkvData->GetString("damage_type", nullptr);
|
||||||
if (pszDamageClass)
|
if (pszDamageClass)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user