mirror of
https://github.com/Gigaslav/HL2Overcharged.git
synced 2026-09-04 11:44:45 +03:00
420 lines
12 KiB
C++
420 lines
12 KiB
C++
//========= Copyright © 2011-2018. Overcharged ================================//
|
|
//
|
|
// Purpose:
|
|
//
|
|
//=============================================================================//
|
|
|
|
#include "cbase.h"
|
|
#include "NPCEvent.h"
|
|
#include "basecombatcharacter.h"
|
|
#include "AI_BaseNPC.h"
|
|
#include "player.h"
|
|
#include "gamerules.h"
|
|
#include "in_buttons.h"
|
|
#include "soundent.h"
|
|
#include "game.h"
|
|
#include "vstdlib/random.h"
|
|
#include "engine/IEngineSound.h"
|
|
#include "IEffects.h"
|
|
#include "te_effect_dispatch.h"
|
|
#include "sprite.h"
|
|
#include "spritetrail.h"
|
|
#include "beam_shared.h"
|
|
#include "rumble_shared.h"
|
|
#include "gamestats.h"
|
|
#include "decals.h"
|
|
#include "particle_parse.h"
|
|
#include "grenade_spit.h"
|
|
#include "particle_system.h"
|
|
#include "effect_dispatch_data.h"
|
|
|
|
#include "weapon_hornetgun.h"
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
#define BOLT_MODEL oc_weapon_hornetgun_model.GetString() //"models/hornetgun.mdl"
|
|
#define GLOW_SPRITE "particles/particle_glow/particle_glow_03.vmt"
|
|
#define BOLT_AIR_VELOCITY 1500
|
|
#define BOLT_SKIN_NORMAL 0
|
|
#define BOLT_SKIN_GLOW 1
|
|
#define SHOCK_BEAM_SPRITE "sprites/laserbeam.vmt"
|
|
|
|
ConVar oc_weapon_hornetgun_model("oc_weapon_hornetgun_model", "models/spitball_small.mdl", FCVAR_REPLICATED | FCVAR_ARCHIVE, "Shock rifle projectile model.");
|
|
|
|
ConVar sk_plr_dmg_hornetgun("sk_plr_dmg_hornetgun", "30");
|
|
ConVar sk_npc_dmg_hornetgun("sk_npc_dmg_hornetgun", "30");
|
|
|
|
ConVar oc_weapon_hornetgun_projectile_x("oc_weapon_hornetgun_projectile_x", "0");
|
|
ConVar oc_weapon_hornetgun_projectile_y("oc_weapon_hornetgun_projectile_y", "0");
|
|
ConVar oc_weapon_hornetgun_projectile_z("oc_weapon_hornetgun_projectile_z", "0");
|
|
|
|
|
|
|
|
LINK_ENTITY_TO_CLASS(weapon_hornetgun, CWeaponHornetGun);
|
|
|
|
PRECACHE_WEAPON_REGISTER(weapon_hornetgun);
|
|
|
|
IMPLEMENT_SERVERCLASS_ST(CWeaponHornetGun, DT_WeaponHornetGun)
|
|
END_SEND_TABLE()
|
|
|
|
BEGIN_DATADESC(CWeaponHornetGun)
|
|
|
|
DEFINE_FIELD(m_hLaserBeam1, FIELD_EHANDLE),
|
|
DEFINE_FIELD(m_hLaserBeam2, FIELD_EHANDLE),
|
|
DEFINE_FIELD(m_hLaserBeam3, FIELD_EHANDLE),
|
|
DEFINE_FIELD(m_bInZoom, FIELD_BOOLEAN),
|
|
DEFINE_FIELD(m_bMustReload, FIELD_BOOLEAN),
|
|
DEFINE_FIELD(m_iFirePhase, FIELD_INTEGER),
|
|
DEFINE_FIELD(bFirstPickUp, FIELD_BOOLEAN),
|
|
|
|
END_DATADESC()
|
|
|
|
acttable_t CWeaponHornetGun::m_acttable[] =
|
|
{
|
|
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_PHYSGUN, false },
|
|
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_PHYSGUN, false },
|
|
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_PHYSGUN, false },
|
|
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_PHYSGUN, false },
|
|
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_PHYSGUN, false },
|
|
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_PHYSGUN, false },
|
|
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_PHYSGUN, false },
|
|
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SLAM, false },
|
|
|
|
{ ACT_IDLE_RELAXED, ACT_IDLE_SHOTGUN_RELAXED, false },//never aims
|
|
{ ACT_IDLE_STIMULATED, ACT_IDLE_SHOTGUN_STIMULATED, false },
|
|
|
|
{ ACT_WALK_RELAXED, ACT_WALK_RIFLE_RELAXED, false },//never aims
|
|
{ ACT_WALK_STIMULATED, ACT_WALK_RIFLE_STIMULATED, false },
|
|
{ ACT_WALK_AGITATED, ACT_WALK_AIM_RIFLE, false },//always aims
|
|
|
|
{ ACT_RUN_RELAXED, ACT_RUN_RIFLE_RELAXED, false },//never aims
|
|
{ ACT_RUN_STIMULATED, ACT_RUN_RIFLE_STIMULATED, false },
|
|
{ ACT_RUN_AGITATED, ACT_RUN_AIM_RIFLE, false },//always aims
|
|
|
|
{ ACT_IDLE_AIM_RELAXED, ACT_IDLE_SMG1_RELAXED, false },//never aims
|
|
{ ACT_IDLE_AIM_STIMULATED, ACT_IDLE_AIM_RIFLE_STIMULATED, false },
|
|
{ ACT_IDLE_AIM_AGITATED, ACT_IDLE_ANGRY_SMG1, false },//always aims
|
|
|
|
{ ACT_WALK_AIM_RELAXED, ACT_WALK_RIFLE_RELAXED, false },//never aims
|
|
{ ACT_WALK_AIM_STIMULATED, ACT_WALK_AIM_RIFLE_STIMULATED, false },
|
|
{ ACT_WALK_AIM_AGITATED, ACT_WALK_AIM_RIFLE, false },//always aims
|
|
|
|
{ ACT_RUN_AIM_RELAXED, ACT_RUN_RIFLE_RELAXED, false },//never aims
|
|
{ ACT_RUN_AIM_STIMULATED, ACT_RUN_AIM_RIFLE_STIMULATED, false },
|
|
{ ACT_RUN_AIM_AGITATED, ACT_RUN_AIM_RIFLE, false },//always aims
|
|
|
|
{ ACT_WALK_CROUCH, ACT_WALK_CROUCH_RIFLE, true },
|
|
{ ACT_WALK_CROUCH_AIM, ACT_WALK_CROUCH_AIM_RIFLE, true },
|
|
{ ACT_RUN, ACT_RUN_RIFLE, true },
|
|
{ ACT_RUN_CROUCH, ACT_RUN_CROUCH_RIFLE, true },
|
|
{ ACT_RUN_CROUCH_AIM, ACT_RUN_CROUCH_AIM_RIFLE, true },
|
|
|
|
{ ACT_IDLE, ACT_IDLE_SMG1, true },
|
|
{ ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_SHOTGUN, true },
|
|
{ ACT_IDLE_AGITATED, ACT_IDLE_ANGRY_SHOTGUN, true },
|
|
//{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SHOTGUN, true },
|
|
{ ACT_RELOAD, ACT_RELOAD_SMG1, true },
|
|
{ ACT_WALK_AIM, ACT_WALK_AIM_SHOTGUN, true },
|
|
{ ACT_RUN_AIM, ACT_RUN_AIM_SHOTGUN, true },
|
|
{ ACT_GESTURE_RANGE_ATTACK1, ACT_GESTURE_RANGE_ATTACK_SHOTGUN, true },
|
|
{ ACT_RELOAD_LOW, ACT_RELOAD_SHOTGUN_LOW, false },
|
|
{ ACT_RANGE_ATTACK1_LOW, ACT_RANGE_ATTACK_SHOTGUN_LOW, false },
|
|
{ ACT_COVER_LOW, ACT_COVER_SMG1_LOW, false },
|
|
{ ACT_RANGE_AIM_LOW, ACT_RANGE_AIM_SMG1_LOW, false },
|
|
{ ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_SMG1, false },
|
|
{ ACT_WALK, ACT_WALK_RIFLE, false },
|
|
};
|
|
|
|
IMPLEMENT_ACTTABLE(CWeaponHornetGun);
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Constructor
|
|
//-----------------------------------------------------------------------------
|
|
CWeaponHornetGun::CWeaponHornetGun(void)
|
|
{
|
|
m_bReloadsSingly = true;
|
|
m_bInZoom = false;
|
|
m_bMustReload = false;
|
|
m_iFirePhase = 0;
|
|
bFirstPickUp = true;
|
|
}
|
|
|
|
|
|
CWeaponHornetGun::~CWeaponHornetGun()
|
|
{
|
|
|
|
if (m_hLaserBeam1)
|
|
{
|
|
UTIL_Remove(m_hLaserBeam1);
|
|
}
|
|
if (m_hLaserBeam2)
|
|
{
|
|
UTIL_Remove(m_hLaserBeam2);
|
|
}
|
|
if (m_hLaserBeam3)
|
|
{
|
|
UTIL_Remove(m_hLaserBeam3);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CWeaponHornetGun::Precache(void)
|
|
{
|
|
#ifndef CLIENT_DLL
|
|
UTIL_PrecacheOther("ShockRifle_projectile");
|
|
#endif
|
|
PrecacheModel(SHOCK_BEAM_SPRITE);
|
|
PrecacheScriptSound("Weapon_Shock.Draw");
|
|
PrecacheScriptSound("Weapon_Shock.Impact");
|
|
PrecacheScriptSound("Weapon_Crossbow.BoltHitBody");
|
|
PrecacheScriptSound("Weapon_Crossbow.BoltHitWorld");
|
|
PrecacheScriptSound("Weapon_Crossbow.BoltSkewer");
|
|
PrecacheParticleSystem("Shock_rifle_main_ball");
|
|
PrecacheParticleSystem("Shock_rifle_main_glow");
|
|
UTIL_PrecacheOther("grenade_spit");
|
|
PrecacheModel(GLOW_SPRITE);
|
|
|
|
BaseClass::Precache();
|
|
}
|
|
|
|
void CWeaponHornetGun::Spawn(void)
|
|
{
|
|
BaseClass::Spawn();
|
|
|
|
m_takedamage = DAMAGE_YES;
|
|
m_iHealth = 15;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CWeaponHornetGun::PrimaryAttack(void)
|
|
{
|
|
CBasePlayer *pPlayer = ToBasePlayer(GetOwner());
|
|
if (!pPlayer)
|
|
return;
|
|
|
|
if (IsNearWall() || GetOwnerIsRunning())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
pPlayer->SetAnimation(PLAYER_ATTACK1);
|
|
|
|
FireBolt();
|
|
|
|
AddViewKick();
|
|
|
|
m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CWeaponHornetGun::SecondaryAttack(void)
|
|
{
|
|
CBasePlayer *pPlayer = ToBasePlayer(GetOwner());
|
|
if (!pPlayer)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (IsNearWall() || GetOwnerIsRunning())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//if (GetWpnData().m_bUsePrimaryAmmoAsSecondary ? GetPrimaryAmmoCount() <= 0 : GetSecondaryAmmoCount() <= 0)
|
|
/*if (GetWpnData().m_bUsePrimaryAmmoAsSecondary ? pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0 : pPlayer->GetAmmoCount(m_iSecondaryAmmoType) <= 0)
|
|
{
|
|
WeaponSound(EMPTY);
|
|
m_flNextPrimaryAttack = 0.15;
|
|
|
|
return;
|
|
}*/
|
|
|
|
WeaponSound(SINGLE);
|
|
|
|
SendWeaponAnim(ACT_VM_PRIMARYATTACK);
|
|
pPlayer->SetAnimation(PLAYER_ATTACK1);
|
|
|
|
//CBaseEntity *pHornet;
|
|
Vector vecSrc;
|
|
|
|
Vector vForward, vRight, vUp;
|
|
QAngle vecAngles;
|
|
|
|
pPlayer->EyeVectors(&vForward, &vRight, &vUp);
|
|
VectorAngles(vForward, vecAngles);
|
|
|
|
Vector vThrowPos;
|
|
vThrowPos = GetClientTracerVector();
|
|
/*vThrowPos.x = cvar->FindVar("oc_muzzle_tracer_x")->GetFloat();
|
|
vThrowPos.y = cvar->FindVar("oc_muzzle_tracer_y")->GetFloat();
|
|
vThrowPos.z = cvar->FindVar("oc_muzzle_tracer_z")->GetFloat();*/
|
|
|
|
trace_t tr;
|
|
UTIL_TraceLine(pPlayer->EyePosition(), vThrowPos, MASK_SHOT, pPlayer, COLLISION_GROUP_NONE, &tr);
|
|
|
|
vecSrc = tr.endpos + vForward * -15 + vRight * 8 + vUp * -12;
|
|
|
|
m_iFirePhase++;
|
|
switch (m_iFirePhase)
|
|
{
|
|
case 1:
|
|
vecSrc = vecSrc + vUp * 8;
|
|
break;
|
|
case 2:
|
|
vecSrc = vecSrc + vUp * 8;
|
|
vecSrc = vecSrc + vRight * 8;
|
|
break;
|
|
case 3:
|
|
vecSrc = vecSrc + vRight * 8;
|
|
break;
|
|
case 4:
|
|
vecSrc = vecSrc + vUp * -8;
|
|
vecSrc = vecSrc + vRight * 8;
|
|
break;
|
|
case 5:
|
|
vecSrc = vecSrc + vUp * -8;
|
|
break;
|
|
case 6:
|
|
vecSrc = vecSrc + vUp * -8;
|
|
vecSrc = vecSrc + vRight * -8;
|
|
break;
|
|
case 7:
|
|
vecSrc = vecSrc + vRight * -8;
|
|
break;
|
|
case 8:
|
|
vecSrc = vecSrc + vUp * 8;
|
|
vecSrc = vecSrc + vRight * -8;
|
|
m_iFirePhase = 0;
|
|
break;
|
|
}
|
|
|
|
CBaseEntity *pHornet = CBaseEntity::Create("hornet", vecSrc, vecAngles, pPlayer);
|
|
pHornet->SetAbsVelocity(vForward * 1200);
|
|
pHornet->SetThink(&CNPC_Hornet::StartDart);
|
|
|
|
/*CHornet *pBee = CHornet::Create(vecSrc, vecAngles, pPlayer);
|
|
|
|
if (pBee)
|
|
{
|
|
pBee->m_hOwner = this;
|
|
pBee->SetGracePeriod(2);
|
|
pBee->m_bDisaleSearch = true;
|
|
pBee->FindEnemy();
|
|
pBee->m_vInitialDirection = vForward;
|
|
pBee->SetAbsVelocity(vForward * HORNET_SPEED);
|
|
//pBee->SetEnemy(GetEnemy());
|
|
}*/
|
|
|
|
RemoveAmmo(GetPrimaryAmmoType(), 1); //pPlayer->RemoveAmmo(1, m_iPrimaryAmmoType);
|
|
|
|
m_flNextPrimaryAttack = gpGlobals->curtime + 0.7f; // BJ: 0.7 delay from second to primary, no extra calculations
|
|
m_flNextSecondaryAttack = gpGlobals->curtime + GetFireRate() * 0.4f; // BJ: Fixin timings, 0.4 is perfect like hl1
|
|
m_flTimeWeaponIdle = gpGlobals->curtime + SequenceDuration();
|
|
|
|
AddViewKick();
|
|
|
|
SecondaryAttackEffects();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Output : Returns true on success, false on failure.
|
|
//-----------------------------------------------------------------------------
|
|
bool CWeaponHornetGun::Reload(void)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CWeaponHornetGun::FireBolt(void)
|
|
{
|
|
/*if (GetPrimaryAmmoCount() <= 0)
|
|
{
|
|
WeaponSound(EMPTY);
|
|
m_flNextPrimaryAttack = 0.15;
|
|
|
|
return;
|
|
}*/
|
|
|
|
CBasePlayer *pOwner = ToBasePlayer(GetOwner());
|
|
|
|
if (pOwner == NULL)
|
|
return;
|
|
|
|
//pOwner->AbortReload(); //test
|
|
|
|
#ifndef CLIENT_DLL
|
|
Vector vecAiming = pOwner->GetAutoaimVector(0);
|
|
|
|
Vector vecMuzzlePos2; Vector vecEndPos2;
|
|
QAngle angDir;
|
|
/*Vector Muzzle = pOwner->Weapon_ShootPosition(1);
|
|
|
|
Muzzle.x += oc_weapon_hornetgun_projectile_x.GetFloat();
|
|
Muzzle.y += oc_weapon_hornetgun_projectile_y.GetFloat();
|
|
Muzzle.z += oc_weapon_hornetgun_projectile_z.GetFloat();*/
|
|
|
|
Vector vThrowPos;
|
|
vThrowPos = GetClientTracerVector();
|
|
/*vThrowPos.x = cvar->FindVar("oc_muzzle_tracer_x")->GetFloat();
|
|
vThrowPos.y = cvar->FindVar("oc_muzzle_tracer_y")->GetFloat();
|
|
vThrowPos.z = cvar->FindVar("oc_muzzle_tracer_z")->GetFloat();*/
|
|
|
|
trace_t tr;
|
|
UTIL_TraceLine(pOwner->EyePosition(), vThrowPos, MASK_SHOT, pOwner, COLLISION_GROUP_NONE, &tr);
|
|
|
|
QAngle angAiming;
|
|
VectorAngles(vecAiming, angAiming);
|
|
|
|
//CShockRifleProjectile *pShockRifleProjectile = CShockRifleProjectile::BoltCreate(vThrowPos, angAiming, 0, pOwner); // BriJee OVR : Better start angles
|
|
|
|
Vector vForward, vRight, vUp;
|
|
|
|
pOwner->EyeVectors(&vForward, &vRight, &vUp);
|
|
|
|
CBaseEntity *pHornet = CBaseEntity::Create("hornet", tr.endpos, angAiming, pOwner);
|
|
//DevMsg("WeaponVel: %.2f %.2f %.2f \n", (vForward * 300).x, (vForward * 300).y, (vForward * 300).z);
|
|
pHornet->SetAbsVelocity(vForward * 300);
|
|
|
|
/*CHornet *pBee = CHornet::Create(vThrowPos, angAiming, pOwner);
|
|
|
|
if (pBee)
|
|
{
|
|
pBee->m_hOwner = this;
|
|
pBee->SetGracePeriod(2);
|
|
pBee->m_bDisaleSearch = false;
|
|
pBee->FindEnemy();
|
|
pBee->m_vInitialDirection = vForward;
|
|
pBee->SetAbsVelocity(vForward * HORNET_SPEED);
|
|
//pBee->SetEnemy(GetEnemy());
|
|
}*/
|
|
|
|
|
|
#endif
|
|
|
|
RemoveAmmo(GetPrimaryAmmoType(), 1); //pOwner->RemoveAmmo(1, m_iPrimaryAmmoType);
|
|
|
|
WeaponSound(SINGLE);
|
|
WeaponSound(SPECIAL2);
|
|
|
|
SendWeaponAnim(GetPrimaryAttackActivity());
|
|
}
|