Zeex / sampgdk

Write SA-MP gamemodes in C/C++
http://zeex.github.io/sampgdk
Apache License 2.0
153 stars 83 forks source link

Call public(callback) from another plugin #187

Closed buridan1999 closed 6 years ago

buridan1999 commented 6 years ago

Excuse me, I need your help, because I want to know how can I call public(callback) from another plugin, like streamer maybe, for example he has got public OnDynamicObjectMoved(objectid) ?

Will be this code work? PLUGIN_EXPORT bool PLUGIN_CALL OnDynamicObjectMoved(int objectid) { return false; }

IstuntmanI commented 6 years ago

You need to use OnPublicCall to hook other callbacks. Here it is for the streamer plugin (casting as int isn't needed I think, AFAIK cell has int's size) 2.9.0+ :

PLUGIN_EXPORT bool PLUGIN_CALL OnPublicCall( AMX * amx, const char * name, cell * params, cell * retval )
{
    std::string Name = std::string( name );

    // Streamer
    if( Name == "OnDynamicObjectMoved" ) { return OnDynamicObjectMoved( static_cast< int >( params[ 1 ] ) ); } // ( int objectid )
    else if( Name == "OnPlayerEditDynamicObject" ) { return OnPlayerEditDynamicObject( static_cast< int >( params[ 1 ] ), static_cast< int >( params[ 2 ] ), static_cast< int >( params[ 3 ] ), amx_ctof( params[ 4 ] ), amx_ctof( params[ 5 ] ), amx_ctof( params[ 6 ] ), amx_ctof( params[ 7 ] ), amx_ctof( params[ 8 ] ), amx_ctof( params[ 9 ] ) ); } // ( int playerid, int objectid, int response, float x, float y, float z, float rx, float ry, float rz )
    else if( Name == "OnPlayerSelectDynamicObject" ) { return OnPlayerSelectDynamicObject( static_cast< int >( params[ 1 ] ), static_cast< int >( params[ 2 ] ), static_cast< int >( params[ 3 ] ), amx_ctof( params[ 4 ] ), amx_ctof( params[ 5 ] ), amx_ctof( params[ 6 ] ) ); } // ( int playerid, int objectid, int modelid, float x, float y, float z )
    else if( Name == "OnPlayerShootDynamicObject" ) { return OnPlayerShootDynamicObject( static_cast< int >( params[ 1 ] ), static_cast< int >( params[ 2 ] ), static_cast< int >( params[ 3 ] ), amx_ctof( params[ 4 ] ), amx_ctof( params[ 5 ] ), amx_ctof( params[ 6 ] ) ); } // ( int playerid, int weaponid, int objectid, float x, float y, float z )
    else if( Name == "OnPlayerPickUpDynamicPickup" ) { return OnPlayerPickUpDynamicPickup( static_cast< int >( params[ 1 ] ), static_cast< int >( params[ 2 ] ) ); } // ( int playerid, int pickupid )
    else if( Name == "OnPlayerEnterDynamicCP" ) { return OnPlayerEnterDynamicCP( static_cast< int >( params[ 1 ] ), static_cast< int >( params[ 2 ] ) ); } // ( int playerid, int checkpointid )
    else if( Name == "OnPlayerLeaveDynamicCP" ) { return OnPlayerLeaveDynamicCP( static_cast< int >( params[ 1 ] ), static_cast< int >( params[ 2 ] ) ); } // ( int playerid, int checkpointid )
    else if( Name == "OnPlayerEnterDynamicRaceCP" ) { return OnPlayerEnterDynamicRaceCP( static_cast< int >( params[ 1 ] ), static_cast< int >( params[ 2 ] ) ); } // ( int playerid, int checkpointid )
    else if( Name == "OnPlayerLeaveDynamicRaceCP" ) { return OnPlayerLeaveDynamicRaceCP( static_cast< int >( params[ 1 ] ), static_cast< int >( params[ 2 ] ) ); } // ( int playerid, int checkpointid )
    else if( Name == "OnPlayerEnterDynamicArea" ) { return OnPlayerEnterDynamicArea( static_cast< int >( params[ 1 ] ), static_cast< int >( params[ 2 ] ) ); } // ( int playerid, int areaid )
    else if( Name == "OnPlayerLeaveDynamicArea" ) { return OnPlayerLeaveDynamicArea( static_cast< int >( params[ 1 ] ), static_cast< int >( params[ 2 ] ) ); } // ( int playerid, int areaid )
    else if( Name == "OnPlayerGiveDamageDynamicActor" ) { return OnPlayerGiveDamageDynamicActor( static_cast< int >( params[ 1 ] ), static_cast< int >( params[ 2 ] ), amx_ctof( params[ 3 ] ), static_cast< int >( params[ 4 ] ), static_cast< int >( params[ 5 ] ) ); } // ( playerid, int actorid, float amount, int weaponid, int bodypart );
    else if( Name == "OnDynamicActorStreamIn" ) { return OnDynamicActorStreamIn( static_cast< int >( params[ 1 ] ), static_cast< int >( params[ 2 ] ) ); } // ( int actorid, int forplayerid );
    else if( Name == "OnDynamicActorStreamOut" ) { return OnDynamicActorStreamOut( static_cast< int >( params[ 1 ] ), static_cast< int >( params[ 2 ] ) ); } // ( int actorid, int forplayerid );
    else if( Name == "Streamer_OnItemStreamIn" ) { return Streamer_OnItemStreamIn( static_cast< int >( params[ 1 ] ), static_cast< int >( params[ 2 ] ) ); } // ( int type, int id );
    else if( Name == "Streamer_OnItemStreamOut" ) { return Streamer_OnItemStreamOut( static_cast< int >( params[ 1 ] ), static_cast< int >( params[ 2 ] ) ); } // ( int type, int id );
    //else if( Name == "Streamer_OnPluginError" ) { } // ( const char error[ ] )
    return 1;
}

no Streamer_OnPluginError hooking because we need a parameter in that callback for the error length to be able to get the string correctly (I don't know if there's any way to do that), but anyway, I don't think you need it, it is disabled by default anyway.

EDIT: Well, maybe you got this by yourself, but you would need to declare those returned functions by yourself and define them somewhere in your code.

buridan1999 commented 6 years ago

Okey) Thank you for help!

buridan1999 commented 6 years ago

Is that right?

` PLUGIN_EXPORT bool PLUGIN_CALL OnPublicCall( AMX amx, const char name, cell params, cell retval ) { std::string Name = std::string( name );

// Streamer
if( Name == "OnDynamicObjectMoved" ) 
    { 
            int object_id = static_cast< int >( params[ 1 ] );
            // Manipulation with parametrs, and other code
            return OnDynamicObjectMoved( object_id ); 
    } // ( int objectid )
return 1;

} `

IstuntmanI commented 6 years ago

Yes, that's fine too.

philip1337 commented 6 years ago

Hi, I implemented the streramer directly into my plugin without using that method (I think it consumes alot of time to compare that strings...)

https://github.com/Sphinxila/samp-plugin-streamer/blob/master/src/include/streamer/streamer.hpp

You can use 'streamer-lib' and just '#include <streamer/streamer.hpp>' after that you need to call all this events in your plugin: https://github.com/Sphinxila/samp-plugin-streamer/blob/master/src/include/streamer/streamer.hpp#L25-L51

Kind regards Sphinx

buridan1999 commented 6 years ago

Thank you all !

buridan1999 commented 6 years ago

Compiler wrote that OnDynamicObjectMoved() is undefined when i try to return this...

PLUGIN_EXPORT bool PLUGIN_CALL OnPublicCall( AMX amx, const char name, cell params, cell retval ) { std::string Name = std::string( name ); // Streamer if( Name == "OnDynamicObjectMoved" ) { return OnDynamicObjectMoved( static_cast(params[1]) ); } return 1; }

I found theme "Call a callback" on this URL: http://forum.sa-mp.com/showthread.php?t=295798 It is tutorial by samp sdk. Is that the best way to call callback?

IstuntmanI commented 6 years ago

@Sphinxila: The major downside of implementing it directly in the gamemode for now is about the future updates of the plugin. We would have to manually update lines one by one (well, if you won't update that fork) when commits are made. Because of this I created this issue: https://github.com/samp-incognito/samp-streamer-plugin/issues/195 . You may want to help with that issue, if you are interested in making your work easier in the future ? For now, I think it's better to let Incognito create the base, so we can see what style he wants to use for this.

@buridan1999: As I said, you need to declare the OnDynamicObjectMoved function somewhere:

bool OnDynamicObjectMoved( int objectid );

This has been discussed multiple times in issues here, also on forum. You should search better in the future. Also, issues should be made here only if there's a problem with the plugin itself, for questions you have the forum.

buridan1999 commented 6 years ago

Thank you a lot for detail answer, and I really must be more intent. P.S. Sorry for bad english.

buridan1999 commented 6 years ago

Does this variant can work fine?

https://pastebin.com/1TbsHCUn