/* Copyright (c) 1999, Cold Ice Modification. This code has been written by SlimShady ( darcuri@optonline.net ) Use, distribution, and modification of this source code and/or resulting object code is restricted to non-commercial enhancements to products from Valve LLC. All other use, distribution, or modification is prohibited without written permission from Valve LLC and from the Cold Ice team. Please if you use this code in any public form, please give us credit. */ #include "extdll.h" #include "util.h" #include "cbase.h" #include "monsters.h" #include "weapons.h" #include "nodes.h" #include "player.h" #include "gamerules.h" // special deathmatch shotgun spreads #define VECTOR_CONE_DM_SHOTGUN Vector( 0.08716, 0.04362, 0.00 )// 10 degrees by 5 degrees #define VECTOR_CONE_DM_DOUBLESHOTGUN Vector( 0.17365, 0.04362, 0.00 ) // 20 degrees by 5 degrees enum shotgun_e { ASHOTGUN_IDLE = 0, ASHOTGUN_FIRE, ASHOTGUN_FIRE2, ASHOTGUN_RELOAD, ASHOTGUN_PUMP, ASHOTGUN_START_RELOAD, ASHOTGUN_DRAW, ASHOTGUN_HOLSTER, ASHOTGUN_IDLE4, ASHOTGUN_IDLE_DEEP }; class CAshotgun : public CBasePlayerWeapon { public: int Save( CSave &save ); int Restore( CRestore &restore ); static TYPEDESCRIPTION m_SaveData[]; void Spawn( void ); void Precache( void ); int iItemSlot( ) { return 3; } int GetItemInfo(ItemInfo *p); int AddToPlayer( CBasePlayer *pPlayer ); void PrimaryAttack( void ); void SecondaryAttack( void ); BOOL Deploy( ); void Reload( void ); void WeaponIdle( void ); int m_fInReload; float m_flNextReload; int m_iShell; float m_flPumpTime; }; LINK_ENTITY_TO_CLASS( weapon_ashotgun, CAshotgun ); LINK_ENTITY_TO_CLASS( weapon_shotgun, CAshotgun ); TYPEDESCRIPTION CAshotgun::m_SaveData[] = { DEFINE_FIELD( CAshotgun, m_flNextReload, FIELD_TIME ), DEFINE_FIELD( CAshotgun, m_fInReload, FIELD_INTEGER ), DEFINE_FIELD( CAshotgun, m_flNextReload, FIELD_TIME ), DEFINE_FIELD( CAshotgun, m_flPumpTime, FIELD_TIME ), }; IMPLEMENT_SAVERESTORE( CAshotgun, CBasePlayerWeapon ); void CAshotgun::Spawn( ) { pev->classname = MAKE_STRING("weapon_ashotgun"); Precache( ); m_iId = WEAPON_ASHOTGUN; SET_MODEL(ENT(pev), "models/wmodels/w_ashotgun.mdl"); m_iDefaultAmmo = ASHOTGUN_DEFAULT_GIVE; FallInit(); } void CAshotgun::Precache( void ) { PRECACHE_MODEL("models/vmodels/v_ashotgun.mdl"); PRECACHE_MODEL("models/wmodels/w_ashotgun.mdl"); PRECACHE_MODEL("models/pmodels/p_ashotgun.mdl"); m_iShell = PRECACHE_MODEL ("models/shotgunshell.mdl"); PRECACHE_SOUND ("weapons/ashotgun1.wav"); PRECACHE_SOUND ("weapons/reload1.wav"); PRECACHE_SOUND ("weapons/reload3.wav"); PRECACHE_SOUND ("weapons/scock1.wav"); } int CAshotgun::AddToPlayer( CBasePlayer *pPlayer ) { if ( CBasePlayerWeapon::AddToPlayer( pPlayer ) ) { MESSAGE_BEGIN( MSG_ONE, gmsgWeapPickup, NULL, pPlayer->pev ); WRITE_BYTE( m_iId ); MESSAGE_END(); return TRUE; } return FALSE; } int CAshotgun::GetItemInfo(ItemInfo *p) { p->pszName = STRING(pev->classname); p->pszAmmo1 = "buckshot"; p->iMaxAmmo1 = BUCKSHOT_MAX_CARRY; p->pszAmmo2 = NULL; p->iMaxAmmo2 = -1; p->iMaxClip = ASHOTGUN_MAX_CLIP; p->iSlot = 2; p->iPosition = 1; p->iFlags = 0; p->iId = m_iId = WEAPON_ASHOTGUN; p->iWeight = ASHOTGUN_WEIGHT; return 1; } BOOL CAshotgun::Deploy( ) { return DefaultDeploy( "models/vmodels/v_ashotgun.mdl", "models/pmodels/p_ashotgun.mdl", ASHOTGUN_DRAW, "shotgun" ); } void CAshotgun::PrimaryAttack() { if (m_pPlayer->pev->waterlevel == 3) { PlayEmptySound( ); m_flNextPrimaryAttack = gpGlobals->time + 0.15; return; } if (m_iClip <= 0) { Reload( ); if (m_iClip == 0) PlayEmptySound( ); return; } m_pPlayer->m_iWeaponVolume = LOUD_GUN_VOLUME; m_pPlayer->m_iWeaponFlash = NORMAL_GUN_FLASH; m_iClip--; m_pPlayer->pev->effects = (int)(m_pPlayer->pev->effects) | EF_MUZZLEFLASH; SendWeaponAnim( ASHOTGUN_FIRE ); // player "shoot" animation m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); UTIL_MakeVectors( m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle ); Vector vecShellVelocity = m_pPlayer->pev->velocity + gpGlobals->v_right * RANDOM_FLOAT(50,70) + gpGlobals->v_up * RANDOM_FLOAT(100,150) + gpGlobals->v_forward * 25; EjectBrass ( m_pPlayer->pev->origin + m_pPlayer->pev->view_ofs + gpGlobals->v_up * -12 + gpGlobals->v_forward * 20 + gpGlobals->v_right * 4 , vecShellVelocity, pev->angles.y, m_iShell, TE_BOUNCE_SHOTSHELL); EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/ashotgun1.wav", RANDOM_FLOAT(0.95, 1.0), ATTN_NORM, 0, 93 + RANDOM_LONG(0,0x1f)); Vector vecSrc = m_pPlayer->GetGunPosition( ); Vector vecAiming = m_pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES ); m_pPlayer->FireBullets( 12, vecSrc, vecAiming, VECTOR_CONE_DM_SHOTGUN, 2048, BULLET_PLAYER_BUCKSHOT, 0 ); if (m_iClip != 0) m_flPumpTime = gpGlobals->time + 0.5; m_flNextPrimaryAttack = gpGlobals->time + 0.75; m_flNextSecondaryAttack = gpGlobals->time + 0.75; if (m_iClip != 0) m_flTimeWeaponIdle = gpGlobals->time + 5.0; else m_flTimeWeaponIdle = 0.75; m_fInReload = 0; m_pPlayer->pev->punchangle.x -= 5; } void CAshotgun::SecondaryAttack( void ) { } void CAshotgun::Reload( void ) { if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 || m_iClip == ASHOTGUN_MAX_CLIP) return; if (m_flNextReload > gpGlobals->time) return; if (m_flNextPrimaryAttack > gpGlobals->time) return; if (m_fInReload == 0) { SendWeaponAnim( ASHOTGUN_START_RELOAD ); m_fInReload = 1; m_pPlayer->m_flNextAttack = gpGlobals->time + 0.6; m_flTimeWeaponIdle = gpGlobals->time + 0.6; m_flNextPrimaryAttack = gpGlobals->time + 1.0; m_flNextSecondaryAttack = gpGlobals->time + 1.0; return; } else if (m_fInReload == 1) { if (m_flTimeWeaponIdle > gpGlobals->time) return; m_fInReload = 2; if (RANDOM_LONG(0,1)) EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/reload1.wav", 1, ATTN_NORM, 0, 85 + RANDOM_LONG(0,0x1f)); else EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/reload3.wav", 1, ATTN_NORM, 0, 85 + RANDOM_LONG(0,0x1f)); SendWeaponAnim( ASHOTGUN_RELOAD ); m_flNextReload = gpGlobals->time + 0.5; m_flTimeWeaponIdle = gpGlobals->time + 0.5; } else { // Add them to the clip m_iClip += 1; m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] -= 1; m_fInReload = 1; } } void CAshotgun::WeaponIdle( void ) { ResetEmptySound( ); m_pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES ); if (m_flPumpTime && m_flPumpTime < gpGlobals->time) { // play pumping sound EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/scock1.wav", 1, ATTN_NORM, 0, 95 + RANDOM_LONG(0,0x1f)); m_flPumpTime = 0; } if (m_flTimeWeaponIdle < gpGlobals->time) { if (m_iClip == 0 && m_fInReload == 0 && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]) { Reload( ); } else if (m_fInReload != 0) { if (m_iClip != 16 && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]) { Reload( ); } else { // reload debounce has timed out SendWeaponAnim( ASHOTGUN_PUMP ); // play cocking sound EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/scock1.wav", 1, ATTN_NORM, 0, 95 + RANDOM_LONG(0,0x1f)); m_fInReload = 0; m_flTimeWeaponIdle = gpGlobals->time + 1.5; } } else { int iAnim; float flRand = RANDOM_FLOAT(0, 1); if (flRand <= 0.8) { iAnim = ASHOTGUN_IDLE_DEEP; m_flTimeWeaponIdle = gpGlobals->time + (60.0/12.0);// * RANDOM_LONG(2, 5); } else if (flRand <= 0.95) { iAnim = ASHOTGUN_IDLE; m_flTimeWeaponIdle = gpGlobals->time + (20.0/9.0); } else { iAnim = ASHOTGUN_IDLE4; m_flTimeWeaponIdle = gpGlobals->time + (20.0/9.0); } SendWeaponAnim( iAnim ); } } } class CAshotgunAmmo : public CBasePlayerAmmo { void Spawn( void ) { Precache( ); SET_MODEL(ENT(pev), "models/ammo/w_buckshot.mdl"); CBasePlayerAmmo::Spawn( ); } void Precache( void ) { PRECACHE_MODEL ("models/ammo/w_buckshot.mdl"); PRECACHE_SOUND("items/9mmclip1.wav"); } BOOL AddAmmo( CBaseEntity *pOther ) { if (pOther->GiveAmmo( AMMO_BUCKSHOTBOX_GIVE, "buckshot", BUCKSHOT_MAX_CARRY ) != -1) { EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM); return TRUE; } return FALSE; } }; LINK_ENTITY_TO_CLASS( ammo_buckshotbox, CAshotgunAmmo );