Raised This Month: $ Target: $400
 0% 

Smoke events?


  
 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
Arkshine
AMX Mod X Plugin Approver
Join Date: Oct 2005
Old 07-20-2011 , 13:58   Re: Smoke events?
Reply With Quote #8

You can use grenade_throw forward to hook when a grenade is thrown.
This forward is based on SetModel forward, in others words grenade_throw is called right after a throw(ing?) when the grenade model is applied.

The problem is : the explosion comes after, so you may think that's not a good way.
Here, a preview of a basic flow (and only what we need) of a smoke grenade explosion :

Code:
 You throw a grenade
    ┌ A new grenade entity spawns
    └ The smoke grenade model is applied on the entity → grenade_throw called.
        ┌ After 1.5 seconds, the grenade detonates
        ├ createsmoke.sc event is called. (big smoke)
        └ m_SGExplosionPos offset is set by the current grenade position.
            └ 0.1 second later, the grenade explodes.
                ┌ 0.1 second later, the smoke appears
                └ A second createsmoke.sc event is fired. (20 times, small smoke)
                    └ Grenade removed.
So, a solution would be to hook the createsmoke.sc event (the first) in grenade_throw and since we hook this forward, we don't need the offset anymore.
But since the player's id is not passed for this event, we need some trick.

An example :

PHP Code:
#include <amxmodx>
#include <fakemeta>
#include <csx>

new HandleFwdPlaybackEvent;
new Array:
HandleGrenadePlayerIdQueue;

public 
plugin_init()
{
    
register_plugin"""""" );
}

public 
grenade_throwplayergrenadeweaponId )
{
    if( 
weaponId == CSW_SMOKEGRENADE )
    {
        if( 
HandleGrenadePlayerIdQueue == Invalid_Array )
        {
            
HandleGrenadePlayerIdQueue ArrayCreate();
        }
    
        
ArrayPushCellHandleGrenadePlayerIdQueueplayer );
    
        if( !
HandleFwdPlaybackEvent )
        {
            
HandleFwdPlaybackEvent register_forwardFM_PlaybackEvent"OnPlaybackEvent" );
        }
    }
}

public 
OnPlaybackEvent( const flags, const client, const eventIndex, const Float:delay, const Float:origin[3] )
{
    if( 
HandleFwdPlaybackEvent )
    {
        new 
player ArrayGetCellHandleGrenadePlayerIdQueue);
        
ArrayDeleteItemHandleGrenadePlayerIdQueue);
        
        if( !
ArraySizeHandleGrenadePlayerIdQueue ) )
        {
            
ArrayDestroyHandleGrenadePlayerIdQueue );
            
            
unregister_forwardFM_PlaybackEventHandleFwdPlaybackEvent );
            
HandleFwdPlaybackEvent 0;
        }

        
// Use origin variable to get the explosion origin.
        //server_print( "Player %d - Explosion origin = %f %f %f", player, origin[ 0 ], origin[ 1 ], origin[ 2 ] );
    
}



Note #1 : It's an example, so it may need more check for example if player is still connected, or if you throw a grenade, the game is reset or new round and the grenade is removed right away without exploding, the Array would need to be destroy. Such situation where you need to check.

Note #2 : A more direct way would be simply to hook directly CGrenade::SG_Detonate() as post, with orpheu and retrieving the m_SGExplosionPos offset. If you don't care using Orpheu module, tell me.
__________________

Last edited by Arkshine; 07-20-2011 at 14:12.
Arkshine is offline
 



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 00:48.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode