//Counter-Strike 1.6 High Explosive Grenade /* Model Credits / Model: Valve / Textures: Valve / Animations: Valve / Sounds: Valve / Sprites: Valve / Misc: Valve, D.N.I.O. 071 (Player Model Fix) / Script: KernCore, original base from Nero */ #include "../base" #include "../proj/proj_csgren" namespace CS16_HEGRENADE { // Animations enum CS16_Hegrenades_Animations { IDLE = 0, PULLPIN, THROW, DRAW }; // Models string W_MODEL = "models/cs16/wpn/he/w_he.mdl"; string V_MODEL = "models/cs16/wpn/he/v_he.mdl"; string P_MODEL = "models/cs16/wpn/he/p_he.mdl"; // Sprites string SPR_CAT = "misc/"; //Weapon category used to get the sprite's location // Sounds array WeaponSoundEvents = { "cs16/he/pin.wav" }; // Information int MAX_CARRY = 10; int MAX_CLIP = WEAPON_NOCLIP; int DEFAULT_GIVE = 1; int WEIGHT = 5; int FLAGS = ITEM_FLAG_LIMITINWORLD | ITEM_FLAG_EXHAUSTIBLE; uint DAMAGE = 150; uint SLOT = 4; uint POSITION = 4; string AMMO_TYPE = GetName(); float TIMER = 1.5; //Buy Menu Information string WPN_NAME = "High Explosive Grenade"; uint WPN_PRICE = 50; class weapon_hegrenade : ScriptBasePlayerWeaponEntity, CS16BASE::WeaponBase, CS16BASE::GrenadeWeaponExplode { private CBasePlayer@ m_pPlayer { get const { return cast( self.m_hPlayer.GetEntity() ); } set { self.m_hPlayer = EHandle( @value ); } } private bool m_bInAttack, m_bThrown; private float m_fAttackStart, m_flStartThrow; private int GetBodygroup() { return 0; } void Spawn() { Precache(); self.pev.dmg = DAMAGE; CommonSpawn( W_MODEL, DEFAULT_GIVE ); self.pev.scale = 1; } void Precache() { self.PrecacheCustomModels(); //Models g_Game.PrecacheModel( W_MODEL ); g_Game.PrecacheModel( V_MODEL ); g_Game.PrecacheModel( P_MODEL ); //Entities g_Game.PrecacheOther( CS16GRENADEPROJECTILE::DEFAULT_PROJ_NAME ); //Sounds CS16BASE::PrecacheSounds( WeaponSoundEvents ); //Sprites CommonSpritePrecache(); g_Game.PrecacheGeneric( CS16BASE::MAIN_SPRITE_DIR + CS16BASE::MAIN_CSTRIKE_DIR + SPR_CAT + self.pev.classname + ".txt" ); } bool GetItemInfo( ItemInfo& out info ) { info.iMaxAmmo1 = MAX_CARRY; info.iMaxAmmo2 = -1; info.iMaxClip = MAX_CLIP; info.iSlot = SLOT; info.iPosition = POSITION; info.iId = g_ItemRegistry.GetIdForName( self.pev.classname ); info.iFlags = FLAGS; info.iWeight = WEIGHT; return true; } bool AddToPlayer( CBasePlayer@ pPlayer ) { return CommonAddToPlayer( pPlayer ); } // Better ammo extraction --- Anggara_nothing bool CanHaveDuplicates() { return true; } private int m_iAmmoSave; bool Deploy() { m_iAmmoSave = 0; // Zero out the ammo save return Deploy( V_MODEL, P_MODEL, DRAW, "gren", GetBodygroup(), (20.0/30.0) ); } bool CanHolster() { if( m_fAttackStart != 0 ) return false; return true; } bool CanDeploy() { if( m_pPlayer.m_rgAmmo( self.m_iPrimaryAmmoType) == 0 ) return false; return true; } private CBasePlayerItem@ DropItem() { m_iAmmoSave = m_pPlayer.AmmoInventory( self.m_iPrimaryAmmoType ); //Save the player's ammo pool in case it has any in DropItem return self; } void Holster( int skipLocal = 0 ) { m_bThrown = false; m_bInAttack = false; m_fAttackStart = 0; m_flStartThrow = 0; CommonHolster(); if( m_pPlayer.m_rgAmmo( self.m_iPrimaryAmmoType ) > 0 ) //Save the player's ammo pool in case it has any in Holster { m_iAmmoSave = m_pPlayer.m_rgAmmo( self.m_iPrimaryAmmoType ); } if( m_iAmmoSave <= 0 ) { SetThink( ThinkFunction( DestroyThink ) ); self.pev.nextthink = g_Engine.time + 0.1; } BaseClass.Holster( skipLocal ); } void PrimaryAttack() { if( m_pPlayer.m_rgAmmo( self.m_iPrimaryAmmoType ) <= 0 ) return; if( m_fAttackStart < 0 || m_fAttackStart > 0 ) return; self.m_flNextPrimaryAttack = WeaponTimeBase() + (40.0/41.0); self.SendWeaponAnim( PULLPIN, 0, GetBodygroup() ); m_bInAttack = true; m_fAttackStart = g_Engine.time + (40.0/41.0); self.m_flTimeWeaponIdle = g_Engine.time + (40.0/41.0) + (23.0/30.0); } void LaunchThink() { //g_SoundSystem.EmitSoundDyn( m_pPlayer.edict(), CHAN_VOICE, SHOOT_S, VOL_NORM, ATTN_NORM, 0, PITCH_NORM ); Vector angThrow = m_pPlayer.pev.v_angle + m_pPlayer.pev.punchangle; if ( angThrow.x < 0 ) angThrow.x = -10 + angThrow.x * ( (90 - 10) / 90.0 ); else angThrow.x = -10 + angThrow.x * ( (90 + 10) / 90.0 ); float flVel = (90.0f - angThrow.x) * 6; if ( flVel > 750.0f ) flVel = 750.0f; Math.MakeVectors( angThrow ); Vector vecSrc = m_pPlayer.pev.origin + m_pPlayer.pev.view_ofs + g_Engine.v_forward * 16; Vector vecThrow = g_Engine.v_forward * flVel + m_pPlayer.pev.velocity; CS16GRENADEPROJECTILE::CCs16Grenade@ pGrenade2 = CS16GRENADEPROJECTILE::TossGrenade( m_pPlayer.pev, vecSrc, vecThrow, TIMER, DAMAGE, W_MODEL ); m_pPlayer.m_rgAmmo( self.m_iPrimaryAmmoType, m_pPlayer.m_rgAmmo( self.m_iPrimaryAmmoType ) - 1 ); m_fAttackStart = 0; } void ItemPreFrame() { if( m_fAttackStart == 0 && m_bThrown == true && m_bInAttack == false && self.m_flTimeWeaponIdle - 0.1 < g_Engine.time ) { if( m_pPlayer.m_rgAmmo( self.m_iPrimaryAmmoType ) == 0 ) { self.Holster(); } else { self.Deploy(); m_bThrown = false; m_bInAttack = false; m_fAttackStart = 0; m_flStartThrow = 0; } } if( !m_bInAttack || CheckButton() || g_Engine.time < m_fAttackStart ) return; self.m_flTimeWeaponIdle = self.m_flNextPrimaryAttack = self.m_flNextSecondaryAttack = self.m_flNextTertiaryAttack = WeaponTimeBase() + (22.0/30.0); self.SendWeaponAnim( THROW, 0, GetBodygroup() ); m_bThrown = true; m_bInAttack = false; m_pPlayer.SetAnimation( PLAYER_ATTACK1 ); SetThink( ThinkFunction( this.LaunchThink ) ); self.pev.nextthink = g_Engine.time + 0.2; BaseClass.ItemPreFrame(); } void WeaponIdle() { if( self.m_flTimeWeaponIdle > WeaponTimeBase() ) return; self.SendWeaponAnim( IDLE, 0, GetBodygroup() ); self.m_flTimeWeaponIdle = WeaponTimeBase() + g_PlayerFuncs.SharedRandomFloat( m_pPlayer.random_seed, 5, 7 ); } } string GetName() { return "weapon_hegrenade"; } void Register() { CS16GRENADEPROJECTILE::Register(); CS16BASE::RegisterCWEntityEX( "CS16_HEGRENADE::", "weapon_hegrenade", GetName(), GetName(), CS16BASE::MAIN_CSTRIKE_DIR + SPR_CAT, AMMO_TYPE ); } }