#include "cbase.h" #include "npcevent.h" #include "in_buttons.h" #ifdef CLIENT_DLL #include "c_hl2mp_player.h" #else #include "grenade_ar2.h" #include "hl2mp_player.h" #include "basegrenade_shared.h" #endif #include "weapon_hl2mpbase.h" #include "weapon_hl2mpbase_machinegun.h" #ifdef CLIENT_DLL #define CWeaponLasergun C_WeaponLasergun #endif #include "tier0\memdbgon.h" class CWeaponLasergun : public CHL2MPMachineGun { public: DECLARE_CLASS(CWeaponLasergun, CHL2MPMachineGun); CWeaponLasergun(); DECLARE_NETWORKCLASS(); DECLARE_PREDICTABLE(); void Precache(); void ItemPreFrame(); void ItemBusyFrame(); void ItemPostFrame(); void PrimaryAttack(); void AddViewKick(); void DryFire(); virtual bool Reload(void); virtual const Vector& GetBulletSpread() { static Vector cone = VECTOR_CONE_1DEGREES, npcCone = VECTOR_CONE_1DEGREES; if (GetOwner() && GetOwner()->IsNPC()) //Always handle NPCs first return npcCone; else return cone; } #ifndef CLIENT_DLL DECLARE_ACTTABLE(); CWeaponLasergun(const CWeaponLasergun &); #endif private: float m_flRateOfFire; }; IMPLEMENT_NETWORKCLASS_ALIASED( WeaponLasergun, DT_WeaponLasergun) BEGIN_NETWORK_TABLE( CWeaponLasergun, DT_WeaponLasergun) END_NETWORK_TABLE() BEGIN_PREDICTION_DATA(CWeaponLasergun) END_PREDICTION_DATA() LINK_ENTITY_TO_CLASS(weapon_lasergun, CWeaponLasergun); PRECACHE_WEAPON_REGISTER(weapon_lasergun); #ifndef CLIENT_DLL acttable_t CWeaponLasergun::m_acttable[] = { { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SMG1, true }, { ACT_RELOAD, ACT_RELOAD_SMG1, true }, { ACT_IDLE, ACT_IDLE_SMG1, true }, { ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_SMG1, true }, { ACT_WALK, ACT_WALK_RIFLE, true }, { ACT_WALK_AIM, ACT_WALK_AIM_RIFLE, true }, }; IMPLEMENT_ACTTABLE(CWeaponLasergun); #endif CWeaponLasergun::CWeaponLasergun() { m_fMinRange1 = 24; m_fMaxRange1 = 3000; m_bFiresUnderwater = true; } void CWeaponLasergun::Precache() { m_flRateOfFire = 0.05f; #ifndef CLIENT_DLL PrecacheModel("models/weapons/v_lasergun.mdl", true); PrecacheModel("models/weapons/w_lasergun.mdl", true); #endif BaseClass::Precache(); } void CWeaponLasergun::DryFire() { WeaponSound(EMPTY); SendWeaponAnim(ACT_VM_DRYFIRE); m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration(); } void CWeaponLasergun::ItemPreFrame() { BaseClass::ItemPreFrame(); } void CWeaponLasergun::ItemBusyFrame() { BaseClass::ItemBusyFrame(); } void CWeaponLasergun::ItemPostFrame() { BaseClass::ItemPostFrame(); } void CWeaponLasergun::PrimaryAttack() { CBasePlayer* pPlayer = ToBasePlayer(GetOwner()); //This gets the current player holding the weapon Vector vecSrc = pPlayer->Weapon_ShootPosition(); //This simply just gets the current position of the player. Vector vecAim = pPlayer->GetAutoaimVector(0.0); //This gets where the player is looking, but also corrected by autoaim. FireBulletsInfo_t info(1, vecSrc, vecAim, vec3_origin, MAX_TRACE_LENGTH, m_iPrimaryAmmoType); //if (m_iClip1 <= 0) if (pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0) { if (!m_bFireOnEmpty) { Reload(); } else { WeaponSound(EMPTY); m_flNextPrimaryAttack = 0.15; } return; } pPlayer->FireBullets(info); //This is a lengthy one. All of the args in here are data for our bullet. We could simply use //BaseClass::PrimaryAttack, but this gives us no control over how our weapon is fired. //So instead, we use this and give it all our info for our bullet. //The next 2 are just where the bullet is being fired from and where it should go. //Next is how far the bullet is fired, and after that is what type of ammo we use. //After this is the tracer freq, which really doesnt matter. //Next is the id of the entity firing the weapon, and the attachment id. These 2 dont really matter. //Next is how much damage each bullet should do, which is 30. //Next is what entity is firing the bullet, again. //The final 2 define wether our first shot should be accurate, and wether this is the primary attack. WeaponSound(SINGLE); //This makes our weapon emit the single show sound. SendWeaponAnim(ACT_VM_PRIMARYATTACK); //This sends the animation for us shooting. m_flNextPrimaryAttack = gpGlobals->curtime + m_flRateOfFire; //This defines when our next attack should be //m_iClip1--; pPlayer->RemoveAmmo(1, m_iPrimaryAmmoType); //AddViewKick(); //Don't forget to add our viewkick } void CWeaponLasergun::AddViewKick() { CBasePlayer* pPlayer = ToBasePlayer(GetOwner()); QAngle punch; punch += QAngle(-0.2, 0.0, 0.0); pPlayer->ViewPunch(punch); } bool CWeaponLasergun::Reload() { bool fRet = DefaultReload(GetMaxClip1(), GetMaxClip2(), ACT_VM_RELOAD); if (fRet) WeaponSound(RELOAD); return fRet; }