mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2025-03-22 18:40:20 +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_point_glow.cpp"
|
||||
$File "mapbase\c_vgui_text_display.cpp"
|
||||
$File "mapbase\c_weapon_custom_hl2.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 );
|
||||
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() )
|
||||
{
|
||||
|
@ -44,6 +44,10 @@ public:
|
||||
virtual int CapabilitiesGet( void );
|
||||
virtual int WeaponMeleeAttack1Condition( float flDot, float flDist );
|
||||
|
||||
#ifdef MAPBASE
|
||||
virtual int GetDamageType() { return DMG_CLUB; }
|
||||
#endif // MAPBASE
|
||||
|
||||
protected:
|
||||
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\variant_tools.h"
|
||||
$File "mapbase\vgui_text_display.cpp"
|
||||
$File "mapbase\weapon_custom_hl2.cpp"
|
||||
|
||||
$File "mapbase\logic_eventlistener.cpp"
|
||||
$File "mapbase\logic_register_activator.cpp"
|
||||
|
Loading…
x
Reference in New Issue
Block a user