How To: Add callbacks without a module.

For scripting examples for learning how to use AMXX.
User avatar
Archive-Poster
Posts: 1229
Gender:
United States of America

How To: Add callbacks without a module.

Post by Archive-Poster »

This tutorial will explain how one can add callbacks without building a new module.

A callback is a function that is called when certain things happen. For instance, "pfn_touch" is a callback, called whenever two objects touch.

Callbacks have a lot of useful features. For instance, while all plugins are executed in sequence, top ones to bottom ones, this means a task set on client_connect (id) is not on the same timer for every plugin, there are slight flaws. This caused problems for me when I needed several plugins to be working almost in synch.

So, registering callbacks for your own small functions can be useful, but typically it is not very useful if your plugin is entirely stand alone. Registering callbacks int he methods I'm about to provide is usually most useful when the callback will be received from a plugin different from your own.

In any case, the first thing you want to do is identify when and where you want the callback to originate from. For the purpose of this tutorial, we will use a simple task that will start on client_putinserver(id), and will push out a callback every second.

Code: Select all

#include <amxmodx> 

// Init. Self explanatory
public plugin_init() register_plugin("CallBack Test","Gamma","Twilight Suzuka")

// Start the calling, keep it calling
public client_putinserver(id) set_task(1.0,"callback",id,"",0,"b");

// Handle the sending of the callback.
public callback(id)
{
    // Start the callback command.
    server_cmd("test_callback %i",id)

    // Send it.
    server_exec();
}
Ok, so we've made a small plugin. It starts the callback feed when someone enters the server, and keeps pushing out callbacks every second. Now we need to receive them:

Code: Select all

#include <amxmodx> 

// Init. Self explanatory
public plugin_init()
{
    register_plugin("CallBack Test","Gamma","Twilight Suzuka")

    // Catch the command we send.
    register_srvcmd("test_callback","handle_callback")
}

// Start the calling.
public client_putinserver(id) set_task(1.0,"callback",id,"",0,"b");

public client_disconnect(id) remove_task(id);

// Handle the sending of the callback.
public callback(id)
{
    // Start the callback command.
    server_cmd("test_callback %i",id)

    // Send it.
    server_exec();
}

// Handle the callback
public handle_callback()
{
    // Get the ID of the person being sent about.
    new arg[32]
    read_argv(1,arg,31)

    new id = str_to_num(arg)
    
    // Tell the server console we got the message
    server_print("CallBack Received for: %i",id)

    // Return continued so other people can catch it too.
    return PLUGIN_CONTINUE;
}
As you can see, this plugin sends its own callback, then receives it and prints a message saying it got it. This plugin, on its own, is useless. You could just as easily simply call the function yourself.

But, lets say the catching and sending parts are in two different plugins. Sure, you could force a call of that function and get it done quicker. But what if you didnt know what plugin to call? What if you wanted any plugin that wanted to receive the callback to receive it? In that case, this method is the best method.

So, making a callback is very easy. Find out where you want to start it, send a command, and hook that command to receive it. Using this method, you can quickly, effeciently, and reliably design sort of mini-mod plugins with their own callbacks and such.

- Melanie.
User avatar
Archive-Poster
Posts: 1229
Gender:
United States of America

Re: How To: Add callbacks without a module.

Post by Archive-Poster »

Code: Select all

public send_callback(function[])
{
	for(new i = 0; i < get_pluginsnum(); i++)
	{
		new filename[100],other[100]
		get_plugin ( i,filename,99,other,99,other,99,other,99,other,99 )

		new check = callfunc_begin ( function, filename )
		if(check > 0)
		{
			new block = callfunc_end ( )

			if(block == PLUGIN_HANDLED) return;
		}
	}
	return;
}
As you can see, this will call the plugin in ALL plugins, and block it if the plugin wants.

It is faster, but less effecient than the server command callback.
You can easily add parameters to it as well, as many as you like.
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest