Introducción al SourceMod Scripting
#1
- Introducción


Esta guía les dará una pequeña idea de como empezar a escribir plugins en SourceMod. Toda la redacción es de mi autoría, saque la idea y ejemplos de como armar el post de la guía original en la wiki de SourceMod (aquí). Quiero recalcar que al leer esta guía tienen conocimiento del lenguaje pawn, caso negativo les recomiendo leer esta guía.

Para empezar a escribir plugins necesitarán un editor de texto (en lo personal les recomiendo Notepad++). Para compilar plugins pueden usar el compilador web, más adelante les dejaré un post para compilarlos ustedes mismos.

- Inicio


Para empezar, abriremos un nuevo documento en blanco en Notepad++ o en el editor que esten usando. Comenzaremos como todo plugin, definiendo las librerías. En AMX Mod X, la default era amxmodx, aquí sera sourcemod:

Código PHP:
#include <sourcemod> 

Esta es la más común. Hay varias más para usar, por ejemplo sdktools que tiene muchas funciones útiles.

Para seguir definiremos el autor del plugin, descripción, versión, etc.

Código PHP:
public Plugin:myinfo =
{
    
name "Mi primer plugin",
    
author "Yo",
    
description "Mi primer plugin",
    
version "1.0",
    
url "http://www.amxmodx-es.com/"
}; 

Hasta ahora tenemos el cuerpo principal de todo plugin, que será este:

Código PHP:
#include <sourcemod>
 
public Plugin:myinfo =
{
    
name "Mi primer plugin",
    
author "Yo",
    
description "Mi primer plugin",
    
version "1.0",
    
url "http://www.amxmodx-es.com/"
}; 

- Funciones y eventos más comunes


La función mas usada es cuando es inicia el plugin (OnPluginStart). En ella definiremos CVARS, comandos de consola, hookeo de eventos, etc. Esta función es igual a la de AMX Mod X plugin_init.

Su estructura es muy simple y es esta:

Código PHP:
public OnPluginStart()
{
    
// Todo lo que querramos registrar


Por ejemplo, registraremos un simple comando para admins:

Código PHP:
public OnPluginStart()
{
    
RegAdminCmd("sm_myslap"Command_MySlapADMFLAG_SLAY);
}
 
public 
Action:Command_MySlap(clientargs)
{


Si queremos usarla seguramente nos dará un "Unknown command" por el simple hecho que no hay nada definido en la función. Lo que tenemos que hacer es devolver algún valor al llamarla. Para eso simplemente haremos un return PLUGIN_HANDLED para que simplemente ignore el comando. No hará nada pero de esta forma no arrojará ningún error.

Código PHP:
public Action:Command_MySlap(clientargs)
{
    return 
Plugin_Handled;


Para utilizar los eventos hay que llamarlos previamente en PluginStart. Por ejemplo nosotros llamaremos al evento cuando spawnea un player:

Código PHP:
public OnPluginStart()
{
    
HookEvent("player_spawned"EventSpawnPlayer);
}

public 
Action:EventSpawnPlayer(Handle:event,const String:name[],bool:dontBroadcast)
{
    new 
client GetClientOfUserId(GetEventInt(event,"userid")); /* Obtenemos el id del cliente que acaba de respawner */


- Llamado de comandos/funciones


En esta parte explicaremos el llamado de comandos, leyendo sus argumentos y mostrandoles como obtener sus valores.

El modo de uso de nuestro comando es el siguiente:

Código:
sm_myslap <nombre|#userid> [daño]

El primer argumento es el nombre o el id del player, el segundo es el daño que le aplicaremos.

Código PHP:
#include <sourcemod>
#include <sdktools>
 
public Plugin:myinfo =
{
    
name "Mi primer plugin",
    
author "Yo",
    
description "Mi primer plugin",
    
version "1.0",
    
url "http://www.amxmodx-es.com/"
};
 
public 
OnPluginStart()
{
    
RegAdminCmd("sm_myslap"Command_MySlapADMFLAG_SLAY);
}
 
public 
Action:Command_MySlap(clientargs)
{
    new 
String:arg1[32], String:arg2[32]; /* Variables para guardar los argumentos */
    
new damage/* Variable para almacenar el daño que aplicaremos */
 
    /* Obtenemos el primer argumento */
    
GetCmdArg(1arg1sizeof(arg1));
 
    
/* Acá comprobamos que haya 2 o más argumentos y que el segundo argumento fue almacenado con éxito */
     
*/
    if (
args >= && GetCmdArg(2arg2sizeof(arg2)))
    {
        
damage StringToInt(arg2); /* Pasamos a entero el valor del daño */
    
}
 
    
/* Utilizamos la función FindTarget para obtener el id del player */
    
new target FindTarget(clientarg1);
    if (
target == -1/* La funcion FindTarget devuelve el id del player, si es -1 significa error */
    
{
        return 
Plugin_Handled;
    }
 
    
SlapPlayer(targetdamage);
 
    return 
Plugin_Handled;


- Menues


Este es un ejemplo sencillo de un menú, con su resultado final:

Código PHP:
public OnPluginStart()
{
    
RegConsoleCmd("menu_test1"Menu_Test1);
}
 
public 
MenuHandler1(Handle:menuMenuAction:actionparam1param2)
{
    
/*Si una opción fue seleccionada, le avisamos al cliente lo que eligió. */
    
if (action == MenuAction_Select)
    {
        new 
String:info[32];
        new 
bool:found GetMenuItem(menuparam2infosizeof(info));
        
PrintToConsole(param1"You selected item: %d (found? %d info: %s)"param2foundinfo);
    }
    
/* Si el menú fue cancelado, le enviamos un mensaje al servidor. */
    
else if (action == MenuAction_Cancel)
    {
        
PrintToServer("Client %d's menu was cancelled.  Reason: %d"param1param2);
    }
    
/* Cuando el menú fue finalizado, lo destruimos. */
    
else if (action == MenuAction_End)
    {
        
CloseHandle(menu);
    }
}
 
public 
Action:Menu_Test1(clientargs)
{
    new 
Handle:menu CreateMenu(MenuHandler1);
    
SetMenuTitle(menu"Do you like apples?");
    
AddMenuItem(menu"yes""Yes");
    
AddMenuItem(menu"no""No");
    
SetMenuExitButton(menufalse);
    
DisplayMenu(menuclient20);
 
    return 
Plugin_Handled;



[Imagen: Basic_menu_1.PNG]

Ahora paso por paso les explicaré cada linea.

Código PHP:
new Handle:menu CreateMenu(MenuHandler1); 

Por lógica, CreateMenu es la función para crear nuestro menú. El único parámetro que necesita es el nombre para el handler.

Código PHP:
SetMenuTitle(menu"Do you like apples?"); 

El segundo parámetro es para definir el título de nuestro menú. En el primer parámetro pondremos la variable que tiene alojado el menu que hayamos creado, el segundo parámetro es para poner el título.

Código PHP:
AddMenuItem(menu"yes""Yes"); 

AddMenuItem agrega los item al menu. En el primer parámetro pondremos el nombre de la variable que tiene alojado nuestro menú, el segundo parámetro es el identificador para luego utilizarlo en el handler y el tercero es el nombre del item que se mostrará en el menú.

Código PHP:
SetMenuExitButton(menufalse); 

Sirve para agregar una opción para salir del menú. El primer parámetro ya esta explicado, el segundo indicará si agregamos o no un botón para salir (true para agregarlo, false para no agregarlo).

Código PHP:
DisplayMenu(menuclient20); 

El último parámetro es para mostrar el menú. El primer parámetro es la variable del menú, el segundo el ID del player al que se lo queremos mostrar y el tercer parámetro es cuanto tiempo queremos que le aparezca el menú (en segundos). Si se quiere mostrar para siempre (hasta que salga), agregaremos: MENU_TIME_FOREVER.

Código PHP:
public MenuHandler1(Handle:menuMenuAction:actionparam1param2

El Handler posee 4 parámetros. El primero es la variable que contiene el menú, el segundo es lo que hizo el usuario. Los action pueden ser:
  • MenuAction_Select - Si el usuario eligió una opción
  • MenuAction_Cancel - Si el menu fue cancelado
  • MenuAction_End - Si el menu finalizó

El tercer parámetro (param1) contiene el ID del player al que se le mostró el menú, y el último parámetro contiene el número del item que eligió (empieza desde el 0).

Código PHP:
GetMenuItem(menuparam2infosizeof(info)); 

GetMenuItem obtiene el número del item que el player eligió. El primer parámetro ya lo conocemos, el segundo también, el 3 y el 4 es donde se va a guardar el identificador del item. El identificador (por si no se acuerdan) es el segundo parámetro de AddMenuItem (AddMenuItem(menu, "yes", "Yes")). Lo que esta subrayado y en negrita, es lo que se guardará en info, por eso mismo siempre se guarda en un string.

- Timers


Para crear un timer, se hace uso de la función:

Código PHP:
CreateTimer(5.0Nombre_de_la_funcion); 

En donde el primer parámetro (en este caso 5.0), es el intervalo de tiempo, y el segundo es el nombre de la función a ejecutar cuando pase el intervalo de tiempo que hayamos puesto.

Ejemplo:

public OnPluginStart()
{
CreateTimer(5.0, Mensaje);
}

public Action:Mensaje(Handle:timer)
{
PrintToServer("Mensaje enviado despues de 5 segundos");
}

Para hacer un timer repetitivo, simplemente se agrega 1 parámetro mas. Acá un demostración simple si queremos mandar un mensaje 5 veces:

Código PHP:
// Variable local de control
int numPrinted

someFunction
()
{
    
CreateTimer(3.0Timer_PrintMessageFiveTimes_TIMER_REPEAT);
}
 
public 
Action:Timer_PrintMessageFiveTimes(Handle:timer)
{
    if (
numPrinted >= 5) {
        
numPrinted 0;
        return 
Plugin_Stop;
    }
 
    
PrintToServer("Mensaje");
    
numPrinted++;
 
    return 
Plugin_Continue;


Para pasar datos a un timer, simplemente se los agregamos después del nombre de la función a ejecutar

Código PHP:
public OnClientPutInServer(client)
{
    
CreateTimer(15.0WelcomePlayerclient);
}

public 
Action:WelcomePlayer(Handle:timerany:client)
{
    
PrintToConsole(client"Bienvenido al servidor!");


- TakeDamageHook


El problema de SourceMod es que muchos eventos o funciones, no estan hookeadas por defecto. Entonces tenemos que hacer uso de extensiones creadas por usuarios de AM inglés para poder hookearlas.

Las mas usadas (y las que sugiero que usen), son: SDKHooks y SDKTools.

Por ejemplo, para hookear TakeDamage con SDKHooks:

Código PHP:
#include <sourcemod>
#include <sdkhooks>

public OnPluginStart()
{
    for (new 
client 1client <= MaxClientsclient++) 
    { 
        if (
IsClientInGame(client)) 
        {
            
SDKHook(clientSDKHook_OnTakeDamageTakeDamageHook);
        }
    }
}

public 
OnClientPutInServer(client)
{
      
SDKHook(clientSDKHook_OnTakeDamageTakeDamageHook);
}

public 
Action OnTakeDamage(int victimint &attackerint &inflictorfloat &damageint &damagetypeint &weaponfloat damageForce[3], float damagePosition[3], int damagecustom)
{
      if ( (
client>=1) && (client<=MaxClients) && (attacker>=1) && (attacker<=MaxClients) && (attacker==inflictor) )
    {
        
// Obtenemos el arma del atacante
        
decl String:WeaponName[64];
        
GetClientWeapon(attackerWeaponNamesizeof(WeaponName));
 
        if(
damagetype CS_DMG_HEADSHOT)
    {
                    
// Detectamos el headshot...
        
}
    }

    
// Retornamos "Plugin_Continue", para que el evento haga lo que tenga que hacer
    
return Plugin_Continue;












En construcción... tarda tiempo traducir y armar el post.
Responder
#2
Muy bueno!, puedo usar el AMXX Studio para compilar?
Facebook para preguntas/pedidos: Fb.com/scripterfrosst
Responder
#3
(03/01/2015, 09:27 PM)Frosst escribió: Muy bueno!, puedo usar el AMXX Studio para compilar?

Nop.
Responder
#4
PrintToServer sería el say común en el CS y PrintToConsole la consola verdad?
Facebook para preguntas/pedidos: Fb.com/scripterfrosst
Responder
#5
Print to server es para todo el servidor. Print to Console para la consola, puede ser un jugador especifico o todos.
Responder
#6
Código PHP:
return Plugin_Handled

es obligatorio ponerlo así , o puede ser todo en mayúsculas si uno lo desea?
Responder
#7
(03/01/2015, 11:01 PM)ErikMav94 escribió:
Código PHP:
return Plugin_Handled

es obligatorio ponerlo así , o puede ser todo en mayúsculas si uno lo desea?

Tiene que ser así. Si lo pones en mayúsculas el compilador te tira error
Responder
#8
(03/01/2015, 11:03 PM)wiD escribió:
(03/01/2015, 11:01 PM)ErikMav94 escribió:
Código PHP:
return Plugin_Handled

es obligatorio ponerlo así , o puede ser todo en mayúsculas si uno lo desea?

Tiene que ser así. Si lo pones en mayúsculas el compilador te tira error

(Y)

Podrías poner spoilers en los códigos así uno puede leer tranquilamente la explicación y luego el código (ademas de que se haría mas pequeño el thread)

PD: excelente introducción , me dieron ganas de aprender sm porque por lo que veo no hay mucha diferencia (o al menos en estos que has escrito)
Responder
#9
(03/01/2015, 11:14 PM)ErikMav94 escribió:
(03/01/2015, 11:03 PM)wiD escribió:
(03/01/2015, 11:01 PM)ErikMav94 escribió:
Código PHP:
return Plugin_Handled

es obligatorio ponerlo así , o puede ser todo en mayúsculas si uno lo desea?

Tiene que ser así. Si lo pones en mayúsculas el compilador te tira error

(Y)

Podrías poner spoilers en los códigos así uno puede leer tranquilamente la explicación y luego el código (ademas de que se haría mas pequeño el thread)

PD: excelente introducción , me dieron ganas de aprender sm porque por lo que veo no hay mucha diferencia (o al menos en estos que has escrito)

Listo, códigos grandes agregados en spoiler
Responder
#10
Hice muy poca cosa en source y no me dio por ver si hay algun compilador aparte de la web. Hay algun compilador tipo amx studio?
[Imagen: 76561198066347799.png]
Responder
#11
(05/01/2015, 05:32 AM)Side^^ escribió: Hice muy poca cosa en source y no me dio por ver si hay algun compilador aparte de la web. Hay algun compilador tipo amx studio?

pawn studio lee sourcemod por lo que sé

PD: quien puede ser tan genio de decir AMX studio usarlo para sourcemod -.- dice "AMX" studio.

wiD puedes explicar los parametros? y decir distintos eventos, dejar el inc de sdktools, etc... como seria en sourcemod register_clcmd() register_srvcmd() register_forward() etc etc
Responder
#12
(05/01/2015, 05:32 AM)Side^^ escribió: Hice muy poca cosa en source y no me dio por ver si hay algun compilador aparte de la web. Hay algun compilador tipo amx studio?

No hay un compilador que venga adentro de un editor. El compilador viene con el SourceMod, y para usarlo tenes que abrir la ventana de windows y escribir:

Código:
cd <sourcemod>\scripting
spcomp myplugin.sp

Mi recomendación: Usen siempre el compilador web, da menos trabajo y no tenes que andar lidiando con includes

(05/01/2015, 05:51 AM)matrix123 escribió: wiD puedes explicar los parametros? y decir distintos eventos, dejar el inc de sdktools, etc... como seria en sourcemod register_clcmd() register_srvcmd() register_forward() etc etc

Los parametros de...?

Los eventos varían de acuerdo a cada juego. No son los mismos eventos del Left 4 Dead que del CS:GO. Para ver los eventos de cada juego, los podes encontrar en la carpeta resource en el archivo gameevents.res

Register_clcmd en sourcemod:

Código PHP:
public OnPluginStart()
{
    
RegServerCmd("test_command"Command_Test);
}
 
public 
Action:Command_Test(args)
{
    new 
String:arg[128];
    new 
String:full[256];
 
    
GetCmdArgString(fullsizeof(full));
 
    
PrintToServer("Argument string: %s"full);
    
PrintToServer("Argument count: %d"args);
    for (new 
i=1i<=argsi++)
    {
        
GetCmdArg(iargsizeof(arg));
        
PrintToServer("Argument %d: %s"iarg);
    }
    return 
Plugin_Handled;

Responder
#13
Actualizado. Amplié la parte de menus.

Como ya me quede sin ideas, si quieren pueden pedirme la explicación de algo.
Responder
#14
(10/01/2015, 07:29 PM)wiD escribió: Como ya me quede sin ideas,

pilla los tutoriales de inglés y comienza a traducirlos Whatever

jajajaja, se vería mejor la sección de SourceMod y quizás venga más gente a utilizarla
(17/04/2015, 03:36 PM)Neeeeeeeeeel.- escribió: No se va a volver a conectar a internet en toda su puta vida... nadie sube porno a mi foro y vive para contarlo.
Responder
#15
(12/01/2015, 10:02 AM)RauliTop escribió:
(10/01/2015, 07:29 PM)wiD escribió: Como ya me quede sin ideas,

pilla los tutoriales de inglés y comienza a traducirlos Whatever

jajajaja, se vería mejor la sección de SourceMod y quizás venga más gente a utilizarla

Es que no tengo ganas de traducir cosas innecesarias. Por eso es mejor que me digan que les interesa saber y explico eso.

La idea de esto era que mas gente se copara con SourceMod, que creo que dentro de unos años va a ser la nueva tendencia.
Responder
#16
(05/01/2015, 12:59 PM)wiD escribió:
Código:
cd <sourcemod>\scripting
spcomp myplugin.sp

Se puede arrastrar??? en vez de comandos pendejos?
Competitive/Face it Pick Up Game (PUG) servidor de prueba: 45.77.94.109:27016 Click para Entrar
[Imagen: b_350_20_5A6C3E_383F2D_D2E1B5_2E3226.png]

(14/08/2015, 10:15 PM)Sugisaki escribió: "El mundo es caotico, irracional e injusto. No tiene ningun significado"
Palabras que desde hace mucho tiempo he buscado para describir, ¿Que es el mundo?
Crab

Código PHP:
if(ayuda && free)
{
    exit();

Responder
#17
(12/01/2015, 07:49 PM)Sugisaki escribió:
(05/01/2015, 12:59 PM)wiD escribió:
Código:
cd <sourcemod>\scripting
spcomp myplugin.sp

Se puede arrastrar??? en vez de comandos pendejos?

Nop. Yo por eso uso el compilador online que es mucho más facil

Solo uso el compilador local en caso de tener incs que el compilador web no tiene
Responder
#18
(12/01/2015, 01:28 PM)wiD escribió: Es que no tengo ganas de traducir cosas innecesarias. Por eso es mejor que me digan que les interesa saber y explico eso.

La idea de esto era que mas gente se copara con SourceMod, que creo que dentro de unos años va a ser la nueva tendencia.
quién ha dicho que sean innecesarias?

si no hay aportes/tutoriales/recursos es lógico que no haya gente en esta sección. yo creo que cuando se empiecen a poner cosas es cuando empezará la gente a venir. como bien hiciste con este post.
(17/04/2015, 03:36 PM)Neeeeeeeeeel.- escribió: No se va a volver a conectar a internet en toda su puta vida... nadie sube porno a mi foro y vive para contarlo.
Responder
#19
(03/01/2015, 11:01 PM)ErikMav94 escribió:
Código PHP:
return Plugin_Handled

es obligatorio ponerlo así , o puede ser todo en mayúsculas si uno lo desea?
Es claro que es una constante definida en algún include.

Si te gusta con mayusculas, en la parte de arriba ponés
Código PHP:
new const PLUGIN_HANDLED Plugin_Handled

Y listo...

@wiD, un mejor compilador es este: http://spider.limetech.org/ está hecho en HTML5 y es 100% client-side, es decir que compila con tu pc y ni siquiera hace falta tener conexión a internet para poder usarlo (simplemente habiendo entrado una vez ya podés entrar aunque no tengas Internet). Y además, a diferencia del original, permite utilizar includes custom.


(12/01/2015, 08:31 PM)wiD escribió:
(12/01/2015, 07:49 PM)Sugisaki escribió:
(05/01/2015, 12:59 PM)wiD escribió:
Código:
cd <sourcemod>\scripting
spcomp myplugin.sp

Se puede arrastrar??? en vez de comandos pendejos?

Nop. Yo por eso uso el compilador online que es mucho más facil

Solo uso el compilador local en caso de tener incs que el compilador web no tiene
Algún día que tenga un poco de tiempo hago una interfaz gráfica para el compilador...
[Imagen: paypalqr.png]
Responder
#20
wid como sería si al poner /vida me de vida acá en SM?
Facebook para preguntas/pedidos: Fb.com/scripterfrosst
Responder
#21
(13/01/2015, 01:54 PM)Frosst escribió: wid como sería si al poner /vida me de vida acá en SM?

https://forums.alliedmods.net/showthread.php?p=650481

Me tomo menos de 5 segundos encontrarlo. No es exactamente lo que pedís pero es extremadamente fácil modificarlo para tal fin.
[Imagen: paypalqr.png]
Responder
#22
(13/01/2015, 01:42 PM)Neeeeeeeeeel.- escribió: @wiD, un mejor compilador es este: http://spider.limetech.org/ está hecho en HTML5 y es 100% client-side, es decir que compila con tu pc y ni siquiera hace falta tener conexión a internet para poder usarlo (simplemente habiendo entrado una vez ya podés entrar aunque no tengas Internet). Y además, a diferencia del original, permite utilizar includes custom.

Gracias por la dataa!

PD: Frost, recorda que podes usar la api que da sourcemod. Esta muy completa y contiene todas las funciones que podes utilizar. Para setear la vida podes usar estas:

https://sm.alliedmods.net/api/index.php?...how&id=819&
https://sm.alliedmods.net/api/index.php?...how&id=423&
Responder
#23
Hola wiD, tengo una pregunta, soy bastante nuevo en esto. He leído la parte que expones de crear un menú. También de los eventos . He intentado buscar en internet ejemplos de la combinación de ambas cosas. Es decir, compilaciones en las que en el evento por ejemplo de spawnear aparezca un menú para seleccionar algo. No encuentro nada sencillo que pueda entender, editar y utilizar para mi pretensión.

Resumiendo, puedes poner aquí o mandarme por privado , 2 o 3 ejemplos sencillos de como hacer para que cuando un jugador nazca ( x ejemplo en modo deathmatch que nacen constantemente ) les aparezca un menú donde puedan elegir cosas como recibir un arma especifica, o una habilidad especifica para el que no afecte al resto ( por ejemplo tener mas vida, o menos gravedad o cosas asi )

El menú sencillo con el tema de armas ya lo tengo porque lo saque viendo sources de otros plugins, pero no se como hacer que aparezca cada vez que naces , sin tener que llamarlo mediante comandos.

Otra cosa interesante seria que guardara tu elección hasta que decidas seleccionar otra.

Se que pregunto muchas cosas, contéstame las mas sencillas o en función del tiempo que tengas. Un saludo y de antemano muchas gracias.
Responder
#24
(08/06/2015, 01:29 PM)volrath escribió: Hola wiD, tengo una pregunta, soy bastante nuevo en esto. He leído la parte que expones de crear un menú. También de los eventos . He intentado buscar en internet ejemplos de la combinación de ambas cosas. Es decir, compilaciones en las que en el evento por ejemplo de spawnear aparezca un menú para seleccionar algo. No encuentro nada sencillo que pueda entender, editar y utilizar para mi pretensión.

Resumiendo, puedes poner aquí o mandarme por privado , 2 o 3 ejemplos sencillos de como hacer para que cuando un jugador nazca ( x ejemplo en modo deathmatch que nacen constantemente ) les aparezca un menú donde puedan elegir cosas como recibir un arma especifica, o una habilidad especifica para el que no afecte al resto ( por ejemplo tener mas vida, o menos gravedad o cosas asi )

El menú sencillo con el tema de armas ya lo tengo porque lo saque viendo sources de otros plugins, pero no se como hacer que aparezca cada vez que naces , sin tener que llamarlo mediante comandos.

Otra cosa interesante seria que guardara tu elección hasta que decidas seleccionar otra.

Se que pregunto muchas cosas, contéstame las mas sencillas o en función del tiempo que tengas. Un saludo y de antemano muchas gracias.

Te dejo un ejemplo simple (aviso que hace 6 meses no estoy en source, deje el scripting).

Código PHP:
#include <sourcemod>
#include <sdktools>

public OnPluginStart()
{
    
HookEvent("player_spawn",SpawnEvent);
    
RegConsoleCmd("menu_test1"Menu_Test1);
}
 
public 
MenuHandler1(Handle:menuMenuAction:actionparam1param2)
{
    
/*Si una opción fue seleccionada, le avisamos al cliente lo que eligió. */
    
if (action == MenuAction_Select)
    {
        new 
String:info[32];
        new 
bool:found GetMenuItem(menuparam2infosizeof(info));
        
PrintToConsole(param1"You selected item: %d (found? %d info: %s)"param2foundinfo);
    }
    
/* Si el menú fue cancelado, le enviamos un mensaje al servidor. */
    
else if (action == MenuAction_Cancel)
    {
        
PrintToServer("Client %d's menu was cancelled.  Reason: %d"param1param2);
    }
    
/* Cuando el menú fue finalizado, lo destruimos. */
    
else if (action == MenuAction_End)
    {
        
CloseHandle(menu);
    }
}
 
public 
Action:Menu_Test1(clientargs)
{
    new 
Handle:menu CreateMenu(MenuHandler1);
    
SetMenuTitle(menu"Do you like apples?");
    
AddMenuItem(menu"yes""Yes");
    
AddMenuItem(menu"no""No");
    
SetMenuExitButton(menufalse);
    
DisplayMenu(menuclient20);
 
    return 
Plugin_Handled;


public 
Action:SpawnEvent(Handle:event,const String:name[],bool:dontBroadcast)
{
    new 
client_id GetEventInt(event"userid");
    new 
client GetClientOfUserId(client_id);
    
    
Menu_Test1(client0);

Responder
#25
wiD muchísimas gracias por contestar tan pronto, es una pena que no estes ya en "estos mundillos" seguro que podía haber aprendido mucho de ti en otra época. Últimamente no tengo mucho tiempo libre , pero el viernes compilaré tu código y lo probaré en un servidor de csgo. Si hace lo que necesito, intentaré rehacer tu código con el menú mio y te iré contando si funciona o no. Luego dependiendo de las ganas que tengas puedes ayudarme o no ( eso lo eliges tu ) en algo un poco mas ambicioso que sería el siguiente paso. No es algo que tenga que ser para "ya" y toda ayuda será agradecida y x su puesto seré yo el que se adapte a ti y no al revés. gracias por tu tiempo y tus conocimientos.
Responder


Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)