//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: AK-47 Rifle. // //=============================================================================// #include "cbase.h" #include "NPCevent.h" #include "basecombatcharacter.h" #include "AI_BaseNPC.h" #include "player.h" #include "game.h" #include "in_buttons.h" #include "grenade_ar2.h" #include "AI_Memory.h" #include "soundent.h" #include "rumble_shared.h" #include "gamestats.h" #include "particle_parse.h" #include "weapon_ar3.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" IMPLEMENT_SERVERCLASS_ST(CWeaponAr3, DT_WeaponAr3) END_SEND_TABLE() LINK_ENTITY_TO_CLASS(weapon_ar3, CWeaponAr3); PRECACHE_WEAPON_REGISTER(weapon_ar3); BEGIN_DATADESC(CWeaponAr3) DEFINE_FIELD(m_vecTossVelocity, FIELD_VECTOR), DEFINE_FIELD(m_flNextGrenadeCheck, FIELD_TIME), END_DATADESC() acttable_t CWeaponAr3::m_acttable[] = { { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_AR2, false }, { ACT_HL2MP_RUN, ACT_HL2MP_RUN_AR2, false }, { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_AR2, false }, { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_AR2, false }, { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_AR2, false }, { ACT_HL2MP_GESTURE_RELOAD, ACT_GESTURE_RELOAD_SMG1, false }, { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_AR2, false }, { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SMG1, true }, // END //{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SMG1, true },//false { 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 }, // Readiness activities (not aiming) { ACT_IDLE_RELAXED, ACT_IDLE_SMG1_RELAXED, false },//never aims { ACT_IDLE_STIMULATED, ACT_IDLE_SMG1_STIMULATED, false }, { ACT_IDLE_AGITATED, ACT_IDLE_ANGRY_SMG1, false },//always aims { 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 // Readiness activities (aiming) { 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 //End readiness activities { ACT_WALK_AIM, ACT_WALK_AIM_RIFLE, true }, { 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_AIM, ACT_RUN_AIM_RIFLE, true }, { ACT_RUN_CROUCH, ACT_RUN_CROUCH_RIFLE, true }, { ACT_RUN_CROUCH_AIM, ACT_RUN_CROUCH_AIM_RIFLE, true }, { ACT_GESTURE_RANGE_ATTACK1, ACT_GESTURE_RANGE_ATTACK_SMG1, true }, { ACT_RANGE_ATTACK1_LOW, ACT_RANGE_ATTACK_SMG1_LOW, true }, { ACT_COVER_LOW, ACT_COVER_SMG1_LOW, false }, { ACT_RANGE_AIM_LOW, ACT_RANGE_AIM_SMG1_LOW, false }, { ACT_RELOAD_LOW, ACT_RELOAD_SMG1_LOW, false }, { ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_SMG1, true }, }; IMPLEMENT_ACTTABLE(CWeaponAr3); //========================================================= CWeaponAr3::CWeaponAr3() { m_fMinRange1 = 0;// No minimum range. m_fMaxRange1 = 2048; } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponAr3::Precache(void) { //UTIL_PrecacheOther("grenade_ar2"); PrecacheParticleSystem("weapon_muzzle_smoke"); PrecacheScriptSound("Weapon_oicw.EndFire");//OverCharged PrecacheScriptSound("Weapon_oicw.EndFire2");//OverCharged PrecacheScriptSound("Weapon_Ak47.Draw");//OverCharged PrecacheScriptSound("Weapon_Ak47.ClipOut");//OverCharged PrecacheScriptSound("Weapon_Ak47.ClipLocked");//OverCharged PrecacheScriptSound("Weapon_Ak47.ClipIn");//OverCharged PrecacheScriptSound("Weapon_Ak47.SlideBack");//OverCharged PrecacheScriptSound("Weapon_Ak47.SlideForward");//OverCharged BaseClass::Precache(); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponAr3::FireNPCPrimaryAttack(CBaseCombatCharacter *pOperator, Vector &vecShootOrigin, Vector &vecShootDir) { // FIXME: use the returned number of bullets to account for >10hz firerate WeaponSoundRealtime(SINGLE_NPC); CSoundEnt::InsertSound(SOUND_COMBAT | SOUND_CONTEXT_GUNFIRE, pOperator->GetAbsOrigin(), SOUNDENT_VOLUME_MACHINEGUN, 0.2, pOperator, SOUNDENT_CHANNEL_WEAPON, pOperator->GetEnemy()); pOperator->FireBullets(1, vecShootOrigin, vecShootDir, pOperator->GetAttackSpread(this), MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 1, entindex(), 0); pOperator->DoMuzzleFlash(); m_iClip1 = m_iClip1 - 1; } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponAr3::Operator_ForceNPCFire(CBaseCombatCharacter *pOperator, bool bSecondary) { // Ensure we have enough rounds in the clip m_iClip1++; Vector vecShootOrigin, vecShootDir; QAngle angShootDir; GetAttachment(LookupAttachment("muzzle"), vecShootOrigin, angShootDir); AngleVectors(angShootDir, &vecShootDir); FireNPCPrimaryAttack(pOperator, vecShootOrigin, vecShootDir); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponAr3::Operator_HandleAnimEvent(animevent_t *pEvent, CBaseCombatCharacter *pOperator) { switch (pEvent->event) { case EVENT_WEAPON_SMG1: { Vector vecShootOrigin, vecShootDir; QAngle angDiscard; // Support old style attachment point firing if ((pEvent->options == NULL) || (pEvent->options[0] == '\0') || (!pOperator->GetAttachment(pEvent->options, vecShootOrigin, angDiscard))) { vecShootOrigin = pOperator->Weapon_ShootPosition(); } CAI_BaseNPC *npc = pOperator->MyNPCPointer(); ASSERT(npc != NULL); vecShootDir = npc->GetActualShootTrajectory(vecShootOrigin); FireNPCPrimaryAttack(pOperator, vecShootOrigin, vecShootDir); } break; default: BaseClass::Operator_HandleAnimEvent(pEvent, pOperator); break; } } bool CWeaponAr3::Holster(CBaseCombatWeapon *pSwitchingTo) { if (!HasAnyAmmo()) { //BaseClass::Drop(vec3_origin); //Pickable = false; GetOwner()->Weapon_Drop(this); return true; } return BaseClass::Holster(pSwitchingTo); }