#include <a_samp> //Including a_samp
public OnPlayerEnterVehicle(playerid, vehicleid, ispassenger)
{
//This callback is triggered whenever a player attempts to enter a vehicle.
//I don't have to consider using 'ispassenger' parameter because hydra
//contains a seat for pilot only.
if(GetVehicleModel(vehicleid) == 520) //If the vehicle model is equal to hydra's model ID, then:
{
CallLocalFunction("OnPlayerEnterHydra", "ii", playerid, vehicleid);
//Calling a local function called "OnPlayerEnterHydra" with 2 integer
//formats ("ii") of values "playerid"'s value and "vehicleid"'s value.
//Know more about CallLocalFunction : wiki.sa-mp.com/wiki/CallLocalFunction
return 1; //You can either use return CallLocalFunction(...) if something has to be returned
//from what that function wanted to, or simply return 1 this callback.
}
//If hooking "OnPlayerEnterVehicle" (Not going detailed over hooking parts, you should know them.)
#if defined L_OnPlayerEnterVehicle
return L_OnPlayerEnterVehicle(playerid, vehicleid, ispassenger);
#else
return 1;
#endif
}
#if defined _ALS_OnPlayerEnterVehicle
#undef OnPlayerEnterVehicle
#else
#define _ALS_OnPlayerEnterVehicle
#endif
#define OnPlayerEnterVehicle L_OnPlayerEnterVehicle
#if defined L_OnPlayerEnterVehicle
forward L_OnPlayerEnterVehicle(playerid, vehicleid, ispassenger);
#endif
forward OnPlayerEnterHydra(playerid, vehicleid); //Forwarding my custom callback - OnPlayerEnterHydra or it cannot be implemented like this:
/*public OnPlayerEnterHydra(playerid, vehicleid)
{
SendClientMessage(playerid, -1, "You entering on a hydra!");
return 1;
}
*/
//On some event, instead of using CallLocalFunction I call it directly.
<call_back>; //Example : OnPlayerEnterHydra(playerid, vehicleid);
//Now, forwarding it:
forward <call_back>; //Example : forward OnPlayerEnterHydra(playerid, vehicleid);
//Since the callback isn't implemented, it will give an error. To avoid that,
//implement the callback and to use it on future, hook it.
public <call_back> //Example : public OnPlayerEnterHydra(playerid, vehicleid)
{
//Hooking it like just another callback.
#if defined Lib_<call_back> //Example : #if defined Lib_OnPlayerEnterVehicle
return Lib_<call_back>; //Example : return Lib_OnPlayerEnterVehicle(playerid, vehicleid);
#else
return 1;
#endif
}
#if defined _ALS_<call_back> //If _ALS_<call_back> is defined (Example : #if defined _ALS_OnPlayerEnterHydra)
#undef <call_back> //If so, undefine that callback. Example : #undef OnPlayerEnterHydra
#else //Else
#define _ALS_<call_back> //Define _ALS_<call_back> Example : #define _ALS_OnPlayerEnterHydra
#endif //Ending the #if statement.
#define <call_back> Lib_<call_back> //<call_back> has been undefined, it can be defined to any value now.
//Defining it to what we used it on the undefined callback earlier.
//Example : #define OnPlayerEnterHydra Lib_OnPlayerEnterHydra
#if defined Lib_<call_back> //If Lib_<call_back> has been defined anywhere:
//Example : #if defined Lib_OnPlayerEnterHydra
forward Lib_<call_back>; //Then, forward that. Example : Lib_OnPlayerEnterHydra(playerid, vehicleid);
#endif //Ending the #if statement.
#include <a_samp> //Including a_samp
public OnPlayerEnterVehicle(playerid, vehicleid, ispassenger)
{
//This callback is triggered whenever a player attempts to enter a vehicle.
//I don't have to consider using 'ispassenger' parameter because hydra
//contains a seat for pilot only.
if(GetVehicleModel(vehicleid) == 520) //If the vehicle model is equal to hydra's model ID, then:
{
OnPlayerEnterHydra(playerid, vehicleid); //Directly calling out this one rather than using CallLocalFunction.
//Can also be done as return OnPlayerEnterHydra(playerid, vehicleid);
return 1;
}
//If hooking "OnPlayerEnterVehicle" (Not going detailed over hooking parts, you should know them.)
#if defined L_OnPlayerEnterVehicle
return L_OnPlayerEnterVehicle(playerid, vehicleid, ispassenger);
#else
return 1;
#endif
}
#if defined _ALS_OnPlayerEnterVehicle
#undef OnPlayerEnterVehicle
#else
#define _ALS_OnPlayerEnterVehicle
#endif
#define OnPlayerEnterVehicle L_OnPlayerEnterVehicle
#if defined L_OnPlayerEnterVehicle
forward L_OnPlayerEnterVehicle(playerid, vehicleid, ispassenger);
#endif
forward OnPlayerEnterHydra(playerid, vehicleid); //Forwarding my custom callback - OnPlayerEnterHydra or it cannot be implemented like this:
//Since I've directly called, I should implement the callback to avoid errors.
public OnPlayerEnterHydra(playerid, vehicleid)
{
//But I also want this callback to be used after, so I hook it.
#if defined Lib_OnPlayerEnterHydra
return Lib_OnPlayerEnterHydra(playerid, vehicleid);
#else
return 1;
#endif
}
#if defined _ALS_OnPlayerEnterHydra
#undef OnPlayerEnterHydra
#else
#define _ALS_OnPlayerEnterHydra
#endif
#define OnPlayerEnterHydra Lib_OnPlayerEnterHydra
#if defined Lib_OnPlayerEnterHydra
forward Lib_OnPlayerEnterHydra(playerid, vehicleid);
#endif
//I've hooked my callback, now I can use it again like this:
public OnPlayerEnterHydra(playerid, vehicleid)
{
return 1;
}
//Callback hooked : OnFilterScriptInit
//My custom callback : MyCustomFSCall();
#include <a_samp>
new
rand_int;
public OnFilterScriptInit() {
print("Test : Started FS");
rand_int = 5;
if(rand_int == 5) {
return MyCustomFSCall();
}
#if defined Lib_OnFSInit
return Lib_OnFSInit();
#else
return 1;
#endif
}
#if defined _ALS_OnFilterScriptInit
#undef OnFilterScriptInit
#else
#define _ALS_OnFilterScriptInit
#endif
#define OnFilterScriptInit Lib_OnFSInit
#if defined Lib_OnFSInit
forward Lib_OnFSInit();
#endif
forward MyCustomFSCall();
public MyCustomFSCall() {
//Hooking it once more to use it again.
print("Test : Call 1");
#if defined Lib_MyCustomFSCall
return Lib_MyCustomFSCall();
#else
return 1;
#endif
}
#if defined _ALS_MyCustomFSCall
#undef MyCustomFSCall
#else
#define _ALS_MyCustomFSCall
#endif
#define MyCustomFSCall Lib_MyCustomFSCall
#if defined Lib_MyCustomFSCall
forward Lib_MyCustomFSCall();
#endif
public MyCustomFSCall() {
//Here's it, once again I'm using this callback. If you're building an include, you don't have to
//call your same callback once again, if you do, you will have to hook it to call it again separately.
printf("Test : Call 2");
return 1;
}
- Instead of CallLocalFunction, directly call your callback.
- Forward the custom callback like you do normally.
- Implement your custom callback and hook it, you're done.
NOTE : By performance, it means both the call and compile time. This method also saves memory as compared to CallLocalFunction.
The reason why CallLocalFunction is used is because the user may not have the default callback in their gamemode. If you delete OnPlayerEnterVehicle from your gamemode you will get compiling errors.
|
//Callback hooked : OnFilterScriptInit
//My custom callback : MyCustomFSCall();
#include <a_samp>
new
rand_int;
public OnFilterScriptInit() {
print("Test : Started FS");
rand_int = 5;
if(rand_int == 5) {
return MyCustomFSCall();
}
#if defined Lib_OnFSInit
return Lib_OnFSInit();
#else
return 1;
#endif
}
#if defined _ALS_OnFilterScriptInit
#undef OnFilterScriptInit
#else
#define _ALS_OnFilterScriptInit
#endif
#define OnFilterScriptInit Lib_OnFSInit
#if defined Lib_OnFSInit
forward Lib_OnFSInit();
#endif
forward MyCustomFSCall();
public MyCustomFSCall() {
//Hooking it once more to use it again.
print("Test : Call 1");
#if defined Lib_MyCustomFSCall
return Lib_MyCustomFSCall();
#else
return 1;
#endif
}
#if defined _ALS_MyCustomFSCall
#undef MyCustomFSCall
#else
#define _ALS_MyCustomFSCall
#endif
#define MyCustomFSCall Lib_MyCustomFSCall
#if defined Lib_MyCustomFSCall
forward Lib_MyCustomFSCall();
#endif
//#Suppose this as an end of an include
//My FS
/*public MyCustomFSCall() {
//Here's it, once again I'm using this callback. If you're building an include, you don't have to
//call your same callback once again, if you do, you will have to hook it to call it again separately.
printf("Test : Call 2");
return 1;
}*/
//Even if that's not implemented on my FS, it won't give errors because it's already implemented on my include.
//To avoid the error if it's also implemented on this FS, I hooked it.
@Eth : You should know how normally callbacks are triggered and how hooking works. If you were clear with that and didn't understand the tutorial, let me know.
Yes and the main point of this tutorial is to avoid that error even if the user may not have it defined on their gamemode. pawn Code:
|
This is more complex than simply using CallLocalFunction.
|