mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2025-03-23 19:10:21 +03:00
Added factory for melee weapons
This commit is contained in:
parent
749f9ffae0
commit
332856e37e
@ -65,6 +65,7 @@ $Project
|
|||||||
$File "mapbase\c_func_fake_worldportal.h"
|
$File "mapbase\c_func_fake_worldportal.h"
|
||||||
$File "mapbase\c_point_glow.cpp"
|
$File "mapbase\c_point_glow.cpp"
|
||||||
$File "mapbase\c_vgui_text_display.cpp"
|
$File "mapbase\c_vgui_text_display.cpp"
|
||||||
|
$File "mapbase\c_weapon_custom_hl2.cpp"
|
||||||
$File "mapbase\mapbase_autocubemap.cpp"
|
$File "mapbase\mapbase_autocubemap.cpp"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
34
sp/src/game/client/mapbase/c_weapon_custom_hl2.cpp
Normal file
34
sp/src/game/client/mapbase/c_weapon_custom_hl2.cpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#include "cbase.h"
|
||||||
|
#include "c_weapon__stubs.h"
|
||||||
|
#include "basehlcombatweapon_shared.h"
|
||||||
|
#include "c_basehlcombatweapon.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
#pragma region Melee
|
||||||
|
class C_HLCustomWeaponMelee : public C_BaseHLBludgeonWeapon
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS(C_HLCustomWeaponMelee, C_BaseHLBludgeonWeapon);
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
DECLARE_PREDICTABLE();
|
||||||
|
|
||||||
|
C_HLCustomWeaponMelee();
|
||||||
|
|
||||||
|
virtual const char* GetWeaponScriptName() { return m_iszWeaponScriptName; }
|
||||||
|
private:
|
||||||
|
char m_iszWeaponScriptName[128];
|
||||||
|
};
|
||||||
|
|
||||||
|
STUB_WEAPON_CLASS_IMPLEMENT(weapon_hlcustommelee, C_HLCustomWeaponMelee);
|
||||||
|
|
||||||
|
IMPLEMENT_CLIENTCLASS_DT(C_HLCustomWeaponMelee, DT_HLCustomWeaponMelee, CHLCustomWeaponMelee)
|
||||||
|
RecvPropString(RECVINFO(m_iszWeaponScriptName)),
|
||||||
|
END_RECV_TABLE();
|
||||||
|
|
||||||
|
C_HLCustomWeaponMelee::C_HLCustomWeaponMelee()
|
||||||
|
{
|
||||||
|
m_iszWeaponScriptName[0] = '\0';
|
||||||
|
}
|
||||||
|
#pragma endregion
|
@ -162,7 +162,12 @@ void CBaseHLBludgeonWeapon::Hit( trace_t &traceHit, Activity nHitActivity, bool
|
|||||||
pPlayer->EyeVectors( &hitDirection, NULL, NULL );
|
pPlayer->EyeVectors( &hitDirection, NULL, NULL );
|
||||||
VectorNormalize( hitDirection );
|
VectorNormalize( hitDirection );
|
||||||
|
|
||||||
CTakeDamageInfo info( GetOwner(), GetOwner(), GetDamageForActivity( nHitActivity ), DMG_CLUB );
|
#ifdef MAPBASE
|
||||||
|
CTakeDamageInfo info(GetOwner(), GetOwner(), GetDamageForActivity(nHitActivity), GetDamageType());
|
||||||
|
#else
|
||||||
|
CTakeDamageInfo info(GetOwner(), GetOwner(), GetDamageForActivity(nHitActivity), DMG_CLUB);
|
||||||
|
#endif // MAPBASE
|
||||||
|
|
||||||
|
|
||||||
if( pPlayer && pHitEntity->IsNPC() )
|
if( pPlayer && pHitEntity->IsNPC() )
|
||||||
{
|
{
|
||||||
|
@ -44,6 +44,10 @@ public:
|
|||||||
virtual int CapabilitiesGet( void );
|
virtual int CapabilitiesGet( void );
|
||||||
virtual int WeaponMeleeAttack1Condition( float flDot, float flDist );
|
virtual int WeaponMeleeAttack1Condition( float flDot, float flDist );
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
virtual int GetDamageType() { return DMG_CLUB; }
|
||||||
|
#endif // MAPBASE
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void ImpactEffect( trace_t &trace );
|
virtual void ImpactEffect( trace_t &trace );
|
||||||
|
|
||||||
|
296
sp/src/game/server/mapbase/weapon_custom_hl2.cpp
Normal file
296
sp/src/game/server/mapbase/weapon_custom_hl2.cpp
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
#include "cbase.h"
|
||||||
|
#include "custom_weapon_factory.h"
|
||||||
|
#include "basebludgeonweapon.h"
|
||||||
|
#include "ai_basenpc.h"
|
||||||
|
#include "player.h"
|
||||||
|
#include "npcevent.h"
|
||||||
|
|
||||||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
|
#include "tier0/memdbgon.h"
|
||||||
|
|
||||||
|
#pragma region Melee
|
||||||
|
const char* g_ppszDamageClasses[] = {
|
||||||
|
"BLUNT",
|
||||||
|
"SLASH",
|
||||||
|
"STUN",
|
||||||
|
"BURN",
|
||||||
|
};
|
||||||
|
|
||||||
|
int g_nDamageClassTypeBits[ARRAYSIZE(g_ppszDamageClasses)] = {
|
||||||
|
DMG_CLUB,
|
||||||
|
DMG_SLASH,
|
||||||
|
DMG_CLUB|DMG_SHOCK,
|
||||||
|
DMG_CLUB|DMG_BURN,
|
||||||
|
};
|
||||||
|
|
||||||
|
class CHLCustomWeaponMelee : public CBaseHLBludgeonWeapon, public ICustomWeapon
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS(CHLCustomWeaponMelee, CBaseHLBludgeonWeapon);
|
||||||
|
|
||||||
|
DECLARE_SERVERCLASS();
|
||||||
|
DECLARE_ACTTABLE();
|
||||||
|
|
||||||
|
CHLCustomWeaponMelee();
|
||||||
|
|
||||||
|
float GetRange(void) { return m_flMeleeRange; }
|
||||||
|
float GetFireRate(void) { return m_flRefireRate; }
|
||||||
|
|
||||||
|
void AddViewKick(void);
|
||||||
|
float GetDamageForActivity(Activity hitActivity);
|
||||||
|
|
||||||
|
virtual int WeaponMeleeAttack1Condition(float flDot, float flDist);
|
||||||
|
void SecondaryAttack(void) { return; }
|
||||||
|
|
||||||
|
// Animation event
|
||||||
|
virtual void Operator_HandleAnimEvent(animevent_t* pEvent, CBaseCombatCharacter* pOperator);
|
||||||
|
|
||||||
|
// Don't use backup activities
|
||||||
|
acttable_t* GetBackupActivityList() { return NULL; }
|
||||||
|
int GetBackupActivityListCount() { return 0; }
|
||||||
|
|
||||||
|
const char* GetWeaponScriptName() { return m_iszWeaponScriptName.Get(); }
|
||||||
|
virtual int GetDamageType() { return g_nDamageClassTypeBits[m_nDamageClass]; }
|
||||||
|
|
||||||
|
virtual void ParseCustomFromWeaponFile(const char* pFileName);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Animation event handlers
|
||||||
|
void HandleAnimEventMeleeHit(animevent_t* pEvent, CBaseCombatCharacter* pOperator);
|
||||||
|
|
||||||
|
private:
|
||||||
|
float m_flMeleeRange;
|
||||||
|
float m_flRefireRate;
|
||||||
|
float m_flDamage;
|
||||||
|
float m_flNPCDamage;
|
||||||
|
byte m_nDamageClass;
|
||||||
|
|
||||||
|
CNetworkString(m_iszWeaponScriptName, 128);
|
||||||
|
};
|
||||||
|
|
||||||
|
IMPLEMENT_SERVERCLASS_ST(CHLCustomWeaponMelee, DT_HLCustomWeaponMelee)
|
||||||
|
SendPropString(SENDINFO(m_iszWeaponScriptName)),
|
||||||
|
END_SEND_TABLE();
|
||||||
|
|
||||||
|
DEFINE_CUSTOM_WEAPON_FACTORY(hl2_melee, CHLCustomWeaponMelee);
|
||||||
|
|
||||||
|
acttable_t CHLCustomWeaponMelee::m_acttable[] =
|
||||||
|
{
|
||||||
|
{ ACT_MELEE_ATTACK1, ACT_MELEE_ATTACK_SWING, true },
|
||||||
|
{ ACT_GESTURE_MELEE_ATTACK1, ACT_GESTURE_MELEE_ATTACK_SWING, false},
|
||||||
|
|
||||||
|
{ ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_MELEE, false },
|
||||||
|
#if EXPANDED_HL2_WEAPON_ACTIVITIES
|
||||||
|
{ ACT_IDLE, ACT_IDLE_MELEE, false },
|
||||||
|
{ ACT_RUN, ACT_RUN_MELEE, false },
|
||||||
|
{ ACT_WALK, ACT_WALK_MELEE, false },
|
||||||
|
|
||||||
|
{ ACT_ARM, ACT_ARM_MELEE, false },
|
||||||
|
{ ACT_DISARM, ACT_DISARM_MELEE, false },
|
||||||
|
#else
|
||||||
|
{ ACT_IDLE, ACT_IDLE_ANGRY_MELEE, false },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
// HL2:DM activities (for third-person animations in SP)
|
||||||
|
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SLAM, true },
|
||||||
|
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_MELEE, false },
|
||||||
|
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_MELEE, false },
|
||||||
|
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_MELEE, false },
|
||||||
|
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_MELEE, false },
|
||||||
|
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE, false },
|
||||||
|
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_MELEE, false },
|
||||||
|
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_MELEE, false },
|
||||||
|
#if EXPANDED_HL2DM_ACTIVITIES
|
||||||
|
{ ACT_HL2MP_GESTURE_RANGE_ATTACK2, ACT_HL2MP_GESTURE_RANGE_ATTACK2_MELEE, false },
|
||||||
|
{ ACT_HL2MP_WALK, ACT_HL2MP_WALK_MELEE, false },
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
IMPLEMENT_ACTTABLE(CHLCustomWeaponMelee);
|
||||||
|
|
||||||
|
CHLCustomWeaponMelee::CHLCustomWeaponMelee()
|
||||||
|
{
|
||||||
|
m_nDamageClass = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Get the damage amount for the animation we're doing
|
||||||
|
// Input : hitActivity - currently played activity
|
||||||
|
// Output : Damage amount
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
float CHLCustomWeaponMelee::GetDamageForActivity(Activity hitActivity)
|
||||||
|
{
|
||||||
|
if ((GetOwner() != NULL) && (GetOwner()->IsPlayer()))
|
||||||
|
return m_flDamage;
|
||||||
|
|
||||||
|
return m_flNPCDamage;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Add in a view kick for this weapon
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CHLCustomWeaponMelee::AddViewKick(void)
|
||||||
|
{
|
||||||
|
CBasePlayer* pPlayer = ToBasePlayer(GetOwner());
|
||||||
|
|
||||||
|
if (pPlayer == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QAngle punchAng;
|
||||||
|
|
||||||
|
punchAng.x = random->RandomFloat(1.0f, 2.0f);
|
||||||
|
punchAng.y = random->RandomFloat(-2.0f, -1.0f);
|
||||||
|
punchAng.z = 0.0f;
|
||||||
|
|
||||||
|
pPlayer->ViewPunch(punchAng);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Attempt to lead the target (needed because citizens can't hit manhacks with the crowbar!)
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
extern ConVar sk_crowbar_lead_time;
|
||||||
|
|
||||||
|
int CHLCustomWeaponMelee::WeaponMeleeAttack1Condition(float flDot, float flDist)
|
||||||
|
{
|
||||||
|
// Attempt to lead the target (needed because citizens can't hit manhacks with the crowbar!)
|
||||||
|
CAI_BaseNPC* pNPC = GetOwner()->MyNPCPointer();
|
||||||
|
CBaseEntity* pEnemy = pNPC->GetEnemy();
|
||||||
|
if (!pEnemy)
|
||||||
|
return COND_NONE;
|
||||||
|
|
||||||
|
Vector vecVelocity;
|
||||||
|
vecVelocity = pEnemy->GetSmoothedVelocity();
|
||||||
|
|
||||||
|
// Project where the enemy will be in a little while
|
||||||
|
float dt = sk_crowbar_lead_time.GetFloat();
|
||||||
|
dt += random->RandomFloat(-0.3f, 0.2f);
|
||||||
|
if (dt < 0.0f)
|
||||||
|
dt = 0.0f;
|
||||||
|
|
||||||
|
Vector vecExtrapolatedPos;
|
||||||
|
VectorMA(pEnemy->WorldSpaceCenter(), dt, vecVelocity, vecExtrapolatedPos);
|
||||||
|
|
||||||
|
Vector vecDelta;
|
||||||
|
VectorSubtract(vecExtrapolatedPos, pNPC->WorldSpaceCenter(), vecDelta);
|
||||||
|
|
||||||
|
if (fabs(vecDelta.z) > 70)
|
||||||
|
{
|
||||||
|
return COND_TOO_FAR_TO_ATTACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector vecForward = pNPC->BodyDirection2D();
|
||||||
|
vecDelta.z = 0.0f;
|
||||||
|
float flExtrapolatedDist = Vector2DNormalize(vecDelta.AsVector2D());
|
||||||
|
if ((flDist > 64) && (flExtrapolatedDist > 64))
|
||||||
|
{
|
||||||
|
return COND_TOO_FAR_TO_ATTACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
float flExtrapolatedDot = DotProduct2D(vecDelta.AsVector2D(), vecForward.AsVector2D());
|
||||||
|
if ((flDot < 0.7) && (flExtrapolatedDot < 0.7))
|
||||||
|
{
|
||||||
|
return COND_NOT_FACING_ATTACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return COND_CAN_MELEE_ATTACK1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Animation event handlers
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CHLCustomWeaponMelee::HandleAnimEventMeleeHit(animevent_t* pEvent, CBaseCombatCharacter* pOperator)
|
||||||
|
{
|
||||||
|
// Trace up or down based on where the enemy is...
|
||||||
|
// But only if we're basically facing that direction
|
||||||
|
Vector vecDirection;
|
||||||
|
AngleVectors(GetAbsAngles(), &vecDirection);
|
||||||
|
|
||||||
|
CBaseEntity* pEnemy = pOperator->MyNPCPointer() ? pOperator->MyNPCPointer()->GetEnemy() : NULL;
|
||||||
|
if (pEnemy)
|
||||||
|
{
|
||||||
|
Vector vecDelta;
|
||||||
|
VectorSubtract(pEnemy->WorldSpaceCenter(), pOperator->Weapon_ShootPosition(), vecDelta);
|
||||||
|
VectorNormalize(vecDelta);
|
||||||
|
|
||||||
|
Vector2D vecDelta2D = vecDelta.AsVector2D();
|
||||||
|
Vector2DNormalize(vecDelta2D);
|
||||||
|
if (DotProduct2D(vecDelta2D, vecDirection.AsVector2D()) > 0.8f)
|
||||||
|
{
|
||||||
|
vecDirection = vecDelta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector vecEnd;
|
||||||
|
VectorMA(pOperator->Weapon_ShootPosition(), 50, vecDirection, vecEnd);
|
||||||
|
CBaseEntity* pHurt = pOperator->CheckTraceHullAttack(pOperator->Weapon_ShootPosition(), vecEnd,
|
||||||
|
Vector(-16, -16, -16), Vector(36, 36, 36), m_flNPCDamage, GetDamageType(), 0.75);
|
||||||
|
|
||||||
|
// did I hit someone?
|
||||||
|
if (pHurt)
|
||||||
|
{
|
||||||
|
// play sound
|
||||||
|
WeaponSound(MELEE_HIT);
|
||||||
|
|
||||||
|
// Fake a trace impact, so the effects work out like a player's crowbaw
|
||||||
|
trace_t traceHit;
|
||||||
|
UTIL_TraceLine(pOperator->Weapon_ShootPosition(), pHurt->GetAbsOrigin(), MASK_SHOT_HULL, pOperator, COLLISION_GROUP_NONE, &traceHit);
|
||||||
|
ImpactEffect(traceHit);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WeaponSound(MELEE_MISS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Animation event
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CHLCustomWeaponMelee::Operator_HandleAnimEvent(animevent_t* pEvent, CBaseCombatCharacter* pOperator)
|
||||||
|
{
|
||||||
|
switch (pEvent->event)
|
||||||
|
{
|
||||||
|
case EVENT_WEAPON_MELEE_HIT:
|
||||||
|
HandleAnimEventMeleeHit(pEvent, pOperator);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
BaseClass::Operator_HandleAnimEvent(pEvent, pOperator);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHLCustomWeaponMelee::ParseCustomFromWeaponFile(const char* pFileName)
|
||||||
|
{
|
||||||
|
Q_FileBase(pFileName, m_iszWeaponScriptName.GetForModify(), 128);
|
||||||
|
KeyValuesAD pKVWeapon("WeaponData");
|
||||||
|
if (pKVWeapon->LoadFromFile(filesystem, pFileName, "GAME"))
|
||||||
|
{
|
||||||
|
KeyValues* pkvData = pKVWeapon->FindKey("CustomData");
|
||||||
|
if (pkvData)
|
||||||
|
{
|
||||||
|
m_flDamage = pkvData->GetFloat("damage");
|
||||||
|
m_flNPCDamage = pkvData->GetFloat("damage_npc", m_flDamage);
|
||||||
|
m_flMeleeRange = pkvData->GetFloat("range", 70.f);
|
||||||
|
m_flRefireRate = pkvData->GetFloat("rate", 0.7f);
|
||||||
|
|
||||||
|
const char* pszDamageClass = pkvData->GetString("damage_type", nullptr);
|
||||||
|
if (pszDamageClass)
|
||||||
|
{
|
||||||
|
for (byte i = 0; i < ARRAYSIZE(g_ppszDamageClasses); i++)
|
||||||
|
{
|
||||||
|
if (V_stricmp(pszDamageClass, g_ppszDamageClasses[i]) == 0)
|
||||||
|
{
|
||||||
|
m_nDamageClass = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#pragma endregion
|
@ -88,6 +88,7 @@ $Project
|
|||||||
$File "mapbase\SystemConvarMod.h"
|
$File "mapbase\SystemConvarMod.h"
|
||||||
$File "mapbase\variant_tools.h"
|
$File "mapbase\variant_tools.h"
|
||||||
$File "mapbase\vgui_text_display.cpp"
|
$File "mapbase\vgui_text_display.cpp"
|
||||||
|
$File "mapbase\weapon_custom_hl2.cpp"
|
||||||
|
|
||||||
$File "mapbase\logic_eventlistener.cpp"
|
$File "mapbase\logic_eventlistener.cpp"
|
||||||
$File "mapbase\logic_register_activator.cpp"
|
$File "mapbase\logic_register_activator.cpp"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user