mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2025-02-05 02:00:34 +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 )
|
||||
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
|
||||
|
||||
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()
|
||||
{
|
||||
m_bFiresUnderwater = true;
|
||||
#ifdef MAPBASE
|
||||
m_bShotDelayed = false;
|
||||
#endif // MAPBASE
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -96,11 +108,19 @@ void CBaseHLBludgeonWeapon::ItemPostFrame( void )
|
||||
#ifdef MAPBASE
|
||||
if (pOwner->HasSpawnFlags( SF_PLAYER_SUPPRESS_FIRING ))
|
||||
{
|
||||
m_bShotDelayed = false;
|
||||
WeaponIdle();
|
||||
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) )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose : Starts the swing of the weapon and determines the animation
|
||||
// Input : bIsSecondary - is this a secondary attack?
|
||||
@ -320,10 +339,14 @@ void CBaseHLBludgeonWeapon::Swing( int bIsSecondary )
|
||||
|
||||
Vector swingEnd = swingStart + forward * GetRange();
|
||||
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.
|
||||
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.SetDamageForce( 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;
|
||||
|
||||
#ifndef MAPBASE
|
||||
// We want to test the first swing again
|
||||
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
|
||||
ImpactWater( swingStart, testEnd );
|
||||
ImpactWater(swingStart, testEnd);
|
||||
#endif // !MAPBASE
|
||||
}
|
||||
#ifndef MAPBASE
|
||||
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 );
|
||||
}
|
||||
#endif
|
||||
|
||||
// Send the anim
|
||||
SendWeaponAnim( nHitActivity );
|
||||
@ -414,5 +426,125 @@ void CBaseHLBludgeonWeapon::Swing( int bIsSecondary )
|
||||
|
||||
#ifdef MAPBASE
|
||||
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
|
||||
}
|
||||
|
||||
#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();
|
||||
|
||||
DECLARE_SERVERCLASS();
|
||||
#ifdef MAPBASE
|
||||
DECLARE_DATADESC();
|
||||
#endif // MAPBASE
|
||||
|
||||
virtual void Spawn( void );
|
||||
virtual void Precache( void );
|
||||
@ -30,6 +33,9 @@ public:
|
||||
//Attack functions
|
||||
virtual void PrimaryAttack( void );
|
||||
virtual void SecondaryAttack( void );
|
||||
#ifdef MAPBASE
|
||||
void DelayedAttack(void);
|
||||
#endif // MAPBASE
|
||||
|
||||
virtual void ItemPostFrame( void );
|
||||
|
||||
@ -46,6 +52,8 @@ public:
|
||||
|
||||
#ifdef MAPBASE
|
||||
virtual int GetDamageType() { return DMG_CLUB; }
|
||||
virtual float GetHitDelay() { return 0.f; }
|
||||
virtual bool CanHolster(void);
|
||||
#endif // MAPBASE
|
||||
|
||||
protected:
|
||||
@ -56,6 +64,11 @@ private:
|
||||
void Swing( int bIsSecondary );
|
||||
void Hit( trace_t &traceHit, Activity nHitActivity, bool bIsSecondary );
|
||||
Activity ChooseIntersectionPointAndActivity( trace_t &hitTrace, const Vector &mins, const Vector &maxs, CBasePlayer *pOwner );
|
||||
|
||||
#ifdef MAPBASE
|
||||
float m_flDelayedFire;
|
||||
bool m_bShotDelayed;
|
||||
#endif // MAPBASE
|
||||
};
|
||||
|
||||
#endif
|
@ -55,6 +55,8 @@ typedef struct HL2CustomMeleeData_s
|
||||
float m_flRefireRate;
|
||||
float m_flDamage;
|
||||
float m_flNPCDamage;
|
||||
float m_flHitDelay;
|
||||
Activity m_nHitActivity = ACT_INVALID;
|
||||
byte m_nDamageClass;
|
||||
|
||||
bool Parse(KeyValues*);
|
||||
@ -72,6 +74,7 @@ public:
|
||||
|
||||
float GetRange(void) { return m_CustomData.m_flMeleeRange; }
|
||||
float GetFireRate(void) { return m_CustomData.m_flRefireRate; }
|
||||
float GetHitDelay() { return m_CustomData.m_flHitDelay; }
|
||||
|
||||
void AddViewKick(void);
|
||||
float GetDamageForActivity(Activity hitActivity);
|
||||
@ -86,6 +89,9 @@ public:
|
||||
acttable_t* GetBackupActivityList() { return NULL; }
|
||||
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(); }
|
||||
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_flMeleeRange = pkvData->GetFloat("range", 70.f);
|
||||
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);
|
||||
if (pszDamageClass)
|
||||
|
Loading…
x
Reference in New Issue
Block a user