- 12.04.2023
- 5
- 2
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <reapi>
#define IsDefaultWeapon(%0) bool: ( get_entvar( %0, var_impulse ) == 0 )
#define UpdateHudIcon(%0,%1,%2) UTIL_StatusIcon( MSG_ONE, %0, eStatusIconStatus: %1, fmt( "number_%i", %2 ), WEAPON_HUD_ICON_COLOR )
enum _: eStatusIconStatus
{
STATUS_HIDE,
STATUS_SHOW,
STATUS_FLASH
};
const WEAPON_ANIM_CHARGE = 4;
const Float: WEAPON_ANIM_CHARGE_TIME = 1.03;
new const WEAPON_REFERENCE[ ] = "weapon_hegrenade";
new const WEAPON_WEAPONLIST[ ] = "weapon_thunderstorm";
new const WEAPON_MODEL_VIEW[ ] = "models/Ruby/v_thunderstorm.mdl";
new const WEAPON_MODEL_PLAYER[ ] = "models/Ruby/p_thunderstorm.mdl";
new const WEAPON_MODEL_WORLD[ ] = "models/Ruby/w_thunderstorm.mdl";
const WEAPON_MODEL_WORLD_BODY = 0;
new const WEAPON_SOUNDS[ ][ ] =
{
"weapons/thunderstorm_charge.wav",
"weapons/thunderstorm_exp.wav",
"weapons/thunderstorm_depoly.wav",
"weapons/thunderstorm_idle.wav",
"weapons/thunderstorm_pullpin.wav",
"weapons/thunderstorm_throw.wav"
};
const WEAPON_MIN_TIME = 1;
const WEAPON_MAX_TIME = 4;
new const WEAPON_HUD_ICON_COLOR[ ] = { 255, 128, 0 };
new g_iAllocString_WeaponUId,
g_iMsgHook_TempEntity;
public plugin_init( )
{
register_plugin( "Grenade: Thunderstorm", "1.1", "Ruby" );
RegisterHookChain( RG_ThrowHeGrenade, "CBasePlayer__ThrowHeGrenade_Post", true );
RegisterHookChain( RG_CGrenade_ExplodeHeGrenade, "CGrenade__ExplodeHeGrenade_Pre", false );
RegisterHookChain( RG_CGrenade_ExplodeHeGrenade, "CGrenade__ExplodeHeGrenade_Post", true );
RegisterHookChain( RG_CWeaponBox_SetModel, "CWeaponBox__SetModel_Pre", false );
RegisterHam( Ham_Spawn, WEAPON_REFERENCE, "CBasePlayerWeapon__Spawn_Post", true );
RegisterHam( Ham_Item_AddToPlayer, WEAPON_REFERENCE, "CBasePlayerWeapon__AddToPlayer_Post", true );
RegisterHam( Ham_Item_Deploy, WEAPON_REFERENCE, "CBasePlayerWeapon__Deploy_Post", true );
RegisterHam( Ham_Item_Holster, WEAPON_REFERENCE, "CBasePlayerWeapon__Holster_Post", true );
RegisterHam( Ham_Weapon_SecondaryAttack, WEAPON_REFERENCE, "CBasePlayerWeapon__SecondaryAttack_Post", true );
g_iAllocString_WeaponUId = engfunc( EngFunc_AllocString, WEAPON_WEAPONLIST );
}
public plugin_precache( )
{
engfunc( EngFunc_PrecacheModel, WEAPON_MODEL_VIEW );
engfunc( EngFunc_PrecacheModel, WEAPON_MODEL_PLAYER );
engfunc( EngFunc_PrecacheModel, WEAPON_MODEL_WORLD );
for ( new i; i < sizeof WEAPON_SOUNDS; i++ )
engfunc( EngFunc_PrecacheSound, WEAPON_SOUNDS[ i ] );
UTIL_PrecacheWeaponlist( WEAPON_WEAPONLIST );
}
public Message__TempEntity( const iMsgId, const iMsgDest, const iMsgEntity )
{
if ( get_msg_arg_int( 1 ) != TE_EXPLOSION )
return;
set_msg_arg_int( 8, ARG_BYTE, get_msg_arg_int( 8 ) | TE_EXPLFLAG_NOSOUND );
}
public CBasePlayer__ThrowHeGrenade_Post( const pPlayer, const Float: vecStart[ 3 ], const Float: vecVelocity[ 3 ], const Float: flTime, const iTeam, const usEvent )
{
new pActiveItem = get_member( pPlayer, m_pActiveItem );
if ( is_nullent( pActiveItem ) || !IsDefaultWeapon( pActiveItem ) )
return;
new pEntity = GetHookChainReturn( ATYPE_INTEGER );
if ( is_nullent( pEntity ) )
return;
engfunc( EngFunc_SetModel, pEntity, WEAPON_MODEL_WORLD );
set_entvar( pEntity, var_body, WEAPON_MODEL_WORLD_BODY );
set_entvar( pEntity, var_impulse, g_iAllocString_WeaponUId );
set_entvar( pEntity, var_dmgtime, get_gametime( ) + float( get_member( pActiveItem, m_Weapon_iFamasShotsFired ) ) );
}
public CGrenade__ExplodeHeGrenade_Pre( const pEntity )
{
if ( is_nullent( pEntity ) || get_entvar( pEntity, var_impulse ) != g_iAllocString_WeaponUId )
return;
g_iMsgHook_TempEntity = register_message( SVC_TEMPENTITY, "Message__TempEntity" );
}
public CGrenade__ExplodeHeGrenade_Post( const pEntity )
{
if ( is_nullent( pEntity ) || get_entvar( pEntity, var_impulse ) != g_iAllocString_WeaponUId )
return;
emit_sound( pEntity, CHAN_WEAPON, WEAPON_SOUNDS[ 1 ], VOL_NORM, ATTN_NORM, 0, PITCH_NORM );
unregister_message( SVC_TEMPENTITY, g_iMsgHook_TempEntity );
}
public CWeaponBox__SetModel_Pre( const pWeaponBox, const szModel[ ] )
{
new pItem = UTIL_GetWeaponBoxItem( pWeaponBox );
if ( is_nullent( pItem ) || get_member( pItem, m_iId ) != get_weaponid( WEAPON_REFERENCE ) || !IsDefaultWeapon( pItem ) )
return;
SetHookChainArg( 2, ATYPE_STRING, WEAPON_MODEL_WORLD );
set_entvar( pWeaponBox, var_body, WEAPON_MODEL_WORLD_BODY );
}
public CBasePlayerWeapon__Spawn_Post( const pItem )
{
if ( !IsDefaultWeapon( pItem ) )
return;
set_entvar( pItem, var_classname, WEAPON_WEAPONLIST );
rg_set_iteminfo( pItem, ItemInfo_pszName, WEAPON_WEAPONLIST );
set_member( pItem, m_Weapon_iFamasShotsFired, clamp( WEAPON_MIN_TIME, 1, 9 ) );
}
public CBasePlayerWeapon__AddToPlayer_Post( const pItem, const pPlayer )
{
if ( !IsDefaultWeapon( pItem ) )
return;
UTIL_WeaponList( MSG_ONE, pPlayer, pItem );
}
public CBasePlayerWeapon__Deploy_Post( const pItem )
{
if ( !IsDefaultWeapon( pItem ) )
return;
new pPlayer = get_member( pItem, m_pPlayer );
set_entvar( pPlayer, var_viewmodel, WEAPON_MODEL_VIEW );
set_entvar( pPlayer, var_weaponmodel, WEAPON_MODEL_PLAYER );
UpdateHudIcon( pPlayer, STATUS_SHOW, get_member( pItem, m_Weapon_iFamasShotsFired ) );
}
public CBasePlayerWeapon__Holster_Post( const pItem )
{
if ( !IsDefaultWeapon( pItem ) )
return;
UpdateHudIcon( get_member( pItem, m_pPlayer ), STATUS_HIDE, get_member( pItem, m_Weapon_iFamasShotsFired ) );
}
public CBasePlayerWeapon__SecondaryAttack_Post( const pItem )
{
if ( !IsDefaultWeapon( pItem ) || get_member( pItem, m_flStartThrow ) > 0.0 || get_member( pItem, m_flReleaseThrow ) > 0.0 )
return
new pPlayer = get_member( pItem, m_pPlayer );
UTIL_SendWeaponAnim( MSG_ONE, pPlayer, WEAPON_ANIM_CHARGE );
emit_sound( pPlayer, CHAN_WEAPON, WEAPON_SOUNDS[ 0 ], VOL_NORM, ATTN_NORM, 0, PITCH_NORM );
new iTime = get_member( pItem, m_Weapon_iFamasShotsFired );
UpdateHudIcon( pPlayer, STATUS_HIDE, iTime );
if ( ( iTime++ ) >= WEAPON_MAX_TIME ) iTime = 1;
UpdateHudIcon( pPlayer, STATUS_SHOW, iTime );
set_member( pItem, m_Weapon_iFamasShotsFired, iTime );
set_member( pItem, m_Weapon_flNextPrimaryAttack, WEAPON_ANIM_CHARGE_TIME );
set_member( pItem, m_Weapon_flNextSecondaryAttack, WEAPON_ANIM_CHARGE_TIME );
set_member( pItem, m_Weapon_flTimeWeaponIdle, WEAPON_ANIM_CHARGE_TIME );
}
stock bool: UTIL_PrecacheWeaponlist( const szWeaponList[ ] )
{
if ( !strlen( szWeaponList ) )
return false;
new szBuffer[ 128 ], pFile;
format( szBuffer, charsmax( szBuffer ), "sprites/%s.txt", szWeaponList );
engfunc( EngFunc_PrecacheGeneric, szBuffer );
if ( !( pFile = fopen( szBuffer, "rb" ) ) )
return false;
new szSprName[ 64 ], iPos;
while ( !feof( pFile ) )
{
fgets( pFile, szBuffer, charsmax( szBuffer ) );
trim( szBuffer );
if ( !strlen( szBuffer ) )
continue;
if ( ( iPos = containi( szBuffer, "640" ) ) == -1 )
continue;
format( szBuffer, charsmax( szBuffer ), "%s", szBuffer[ iPos + 3 ] );
trim( szBuffer );
strtok( szBuffer, szSprName, charsmax( szSprName ), szBuffer, charsmax( szBuffer ), ' ', 1 );
trim( szSprName );
engfunc( EngFunc_PrecacheGeneric, fmt( "sprites/%s.spr", szSprName ) );
}
fclose( pFile );
return true;
}
stock UTIL_SendWeaponAnim( const iDest, const pPlayer, const iAnim )
{
set_entvar( pPlayer, var_weaponanim, iAnim );
message_begin( iDest, SVC_WEAPONANIM, _, pPlayer );
write_byte( iAnim );
write_byte( 0 );
message_end( );
}
stock UTIL_WeaponList( const iDest, const pPlayer, const pItem = 0, const szWeaponName[ ] = "", const iPrimaryAmmoType = -2, iMaxPrimaryAmmo = -2,
iSecondaryAmmoType = -2, iMaxSecondaryAmmo = -2, iSlot = -2, iPosition = -2, iWeaponID = -2, iFlags = -2 )
{
new szBuffer[ 32 ];
szWeaponName[ 0 ] == EOS ? rg_get_iteminfo( pItem, ItemInfo_pszName, szBuffer, charsmax( szBuffer ) ) : copy( szBuffer, charsmax( szBuffer ), szWeaponName );
static iMsgID_Weaponlist; if ( !iMsgID_Weaponlist ) iMsgID_Weaponlist = get_user_msgid( "WeaponList" );
message_begin( iDest, iMsgID_Weaponlist, _, pPlayer );
write_string( szBuffer );
write_byte( ( iPrimaryAmmoType <= -2 ) ? get_member( pItem, m_Weapon_iPrimaryAmmoType ) : iPrimaryAmmoType );
write_byte( ( iMaxPrimaryAmmo <= -2 ) ? rg_get_iteminfo( pItem, ItemInfo_iMaxAmmo1 ) : iMaxPrimaryAmmo );
write_byte( ( iSecondaryAmmoType <= -2 ) ? get_member( pItem, m_Weapon_iSecondaryAmmoType ) : iSecondaryAmmoType );
write_byte( ( iMaxSecondaryAmmo <= -2 ) ? rg_get_iteminfo( pItem, ItemInfo_iMaxAmmo2 ) : iMaxSecondaryAmmo );
write_byte( ( iSlot <= -2 ) ? rg_get_iteminfo( pItem, ItemInfo_iSlot ) : iSlot );
write_byte( ( iPosition <= -2 ) ? rg_get_iteminfo( pItem, ItemInfo_iPosition ) : iPosition );
write_byte( ( iWeaponID <= -2 ) ? rg_get_iteminfo( pItem, ItemInfo_iId ) : iWeaponID );
write_byte( ( iFlags <= -2 ) ? rg_get_iteminfo( pItem, ItemInfo_iFlags ) : iFlags );
message_end( );
}
stock UTIL_GetWeaponBoxItem( const pWeaponBox )
{
for ( new iSlot, pItem; iSlot < MAX_ITEM_TYPES; iSlot++ )
{
if ( !is_nullent( ( pItem = get_member( pWeaponBox, m_WeaponBox_rgpPlayerItems, iSlot ) ) ) )
return pItem;
}
return NULLENT;
}
stock UTIL_StatusIcon( const iDest, const pPlayer, const eStatusIconStatus: iStatus, const szSprite[ ], const iColor[ 3 ] )
{
static iMsgID_StatusIcon; if ( !iMsgID_StatusIcon ) iMsgID_StatusIcon = get_user_msgid( "StatusIcon" );
message_begin( iDest, iMsgID_StatusIcon, _, pPlayer );
write_byte( clamp( iStatus, STATUS_HIDE, STATUS_FLASH ) );
write_string( szSprite );
write_byte( iColor[ 0 ] );
write_byte( iColor[ 1 ] );
write_byte( iColor[ 2 ] );
message_end( );
}