AMXX Moderator: Others
Join Date: Sep 2007
Location: Street
|
06-19-2010
, 03:02
[ES] Nuevo Sistema de Menus
|
#1
|
El thread original de este tutorial es el siguiente: http://forums.alliedmods.net/showthread.php?t=46364
Yo me encargo de traducirlo y modificar/agregarle cierta informacion desde mi punto de vista. Por lo tanto no es simplemente una traduccion exacta, es decir que solo me baso en el post original y luego armo el tutorial de acuerdo a lo que yo crea conveniente.
Menu Basico - Un menu basico con diferentes items para elegir, como por ejemplo un menu de comandos
Menu de Players - Un menu donde apareceran los players dentro del server, como por ejemplo un menu para kickear
Menu Basico de Vote - Un menu para que cualquier player pueda votar, como por ejemplo un vote de mapas
Sub-Menu - Un menu dentro de otro, como por ejemplo un menu de administracion dentro de otro general
Menu Avanzado de Vote - Un menu de vote mas avanzado, como por ejemplo los del plugin Galileo
newmenus.inc - Algunos datos importantes sobre el include newmenus.inc
Notas finales - Algunas caracteristicas a saber del nuevo sistema de menus
Menu Basico [top]
Code:
#include <amxmodx>
public plugin_init()
{
// creamos el comando con el cual se abrira el menu, en este caso escribiendo
// en el chat: /menu
register_clcmd("say /menu", "HookCmdMenu");
}
// creamos la funcion que va a contener los datos del menu y lo va a mostrar
public HookCmdMenu(id)
{
// primero necesitamos crear la variable que va a contener nuestro menu
// o mejor dicho, que va a contener la ID de nuestro menu
new menu = menu_create("\rSoy un Menu Basico", "BasicMenuHandler");
// el primer parametro de menu_create( ) es el titulo que va a llevar nuestro menu
// el segundo parametro es el nombre de la funcion de las acciones que el menu va a realizar
// y otros datos mas, tales como las teclas que fueron presionadas, el nombre de cada opcion, etc...
// ahora necesitamos agregarle items/opciones a nuestro menu
menu_additem(menu, "Soy la opcion numero #1", "1", 0);
menu_additem(menu, "Soy la opcion numero #2", "2", 0);
menu_additem(menu, "Soy la opcion numero #3", "3", ADMIN_ADMIN);
// el primer parametro es la ID del menu al que le queremos agregar esta opcion
// el segundo aprametro es el texto/nombre de dicha opcion
// el tercer parametro es la data/info que mandamos con esta opcion (el numero de item)
// el cuarto parametro es la flag de admin necesaria para acceder a este item
// le seteamos ciertas propiedades al menu previamente creado
menu_setprop(menu, MPROP_EXITNAME, "Salir");
menu_setprop(menu, MPROP_EXIT, MEXIT_ALL);
// el primer parametro es la ID del menu al que le queremos setear ciertas propiedades
// el segundo parametro es lo que queremos modificar o cambiar (buscar mas en amxconst.inc)
// el tercer parametro es el cambio/atributo que le hacemos a lo que queremos modificar
// lo que hace este ejemplo es setear el nombre "Salir" a la opcion que por default se llama "Exit"
// y luego setear MEXIT_ALL para que aparezca dicho boton
// en el caso de no querer que aparezca el boton para salir, simplemente se usa:
// menu_setprop(menu, MPROP_EXIT, MEXIT_NEVER); solamente y listo
// ahora solo queda mostrarle al player el menu (el titulo y las opciones)
menu_display(id, menu, 0);
// el primer parametro es el ID del player a mostrar el menu
// el segundo parametro es el ID del menu que queremos mostrarle
// el tercero parametro es la pagina con la que queremos empezar
// el tercer parametro por default es 0, si no se usa es lo mismo
}
// ya mostramos el menu, ahora lo que falta es obtener los items que el player selecciona y realizar cierta accion
public BasicMenuHandler(id, menu, item)
{
// si el jugador selecciona la opcion de Salir
if(item == MENU_EXIT)
{
// destruimos el menu y luego bloqueamos la funcion
menu_destroy(menu);
return PLUGIN_HANDLED;
}
// ahora creamos las variables donde se va a alojar la informacion obtenida del menu, tales como
// las opciones seleccionadas, los nombres de las opciones, el acceso y mas...
new data[6], iName[64];
new access, callback;
// con esta funcion obtenemos esos datos, previamente mensionados
menu_item_getinfo(menu, item, access, data, 5, iName, 63, callback);
// la variable data es la informacion de cada opcion, que previamente habiamos agregado en el
// tercer parametro de menu_additem( ), en este ejemplo se usaron numeros: "1", "2", "3"
// por lo que tenemos que convertir el string data en un numero, usando str_to_num( ) y se lo
// asignamos a la nueva variable creada llamada "iKey"
new iKey = str_to_num(data);
// cabe aclarar que lo mas usado son numeros como data, pero si se quiere se usa strings tmb
// ahora realizamos cierta accion dependiendo que opcion fue seleccionada
switch(iKey)
{
case 1:
{
client_print(id, print_chat, "Seleccionaste la primer opcion del menu");
// en el caso de querer que al seleccionar esta opcion, el menu no se cierre
// simplemente debemos mostrarlo nuevamente, de la siguiente forma
menu_display(id, menu);
return PLUGIN_CONTINUE;
// en este caso el return es necesario ya que sino el codigo seguiria hasta
// abajo del switch( ) y se encontraria con el menu_destroy( ), lo cual haria
// que el plugin se cerrara, entonces esto no serviria para nada
}
case 2:
{
client_print(id, print_chat, "Seleccionaste la segunda opcion del menu");
}
case 3:
{
client_print(id, print_chat, "Seleccionaste la tercer opcion del menu, lo que significa que sos ADMIN");
}
}
// ahora debemos cerrar el menu, si es que no se eligio la primer opcion
// lo hacemos con menu_destroy( ) y luego con un return
menu_destroy(menu);
return PLUGIN_HANDLED;
// como informacion extra quiero aclarar que hay algo de lo que no estoy seguro
// y es sobre el menu_destroy( ), supuestamente hay que usarlo cada vez que queremos
// cerrar el menu, pero con un return PLUGIN_HANDLED directamente se puede hacer
// cuando consiga aclarar esta duda, de si es necesario o no el menu_destroy( )
// voy a editar esto con la informacion correcta sobre este tema
}
Menu de Players [top]
* Para poder entender este tipo de menu, se requiere haber entendido el Menu Basico
Code:
#include <amxmodx>
#include <fun>
public plugin_init()
{
// registramo el comando para abrir nuestro menu
register_clcmd("say /players", "HookCmdMenuPlr");
}
public HookCmdMenuPlr(id)
{
// creamos al menu con su titulo y su nombre de funcion y guardamos su ID en una variable
new menu = menu_create("\rMenu de Players:", "PlayerMenuHandler");
// creamos algunas variables para poder obtener cada id de los players
new players[32], pnum, tempid;
// creamos algunas variables para guardar cierta informacion de los players
new szName[32], szTempid[10];
// buscamos todos los players y guardamos sus ids dentro de players[32]
// tambien guardamos la cantidad de players encontrados en pnum
get_players(players, pnum);
// hacemos uso de un loop para obtener cada id de los players y mostrar
// el nombre de cada player dentro del menu, en cada opcion
for(new i = 0; i < pnum; i++)
{
//Save a tempid so we do not re-index
// guardamos la id del player encontrado en la variable tempid
// asi no tenemos que reindexar (usar players[i])
tempid = players[i];
// ahora obtenemos el nombre de cada player y convertimos el id
// de cada uno en un string, para luego usarlo en menu_additem( )
get_user_name(tempid, szName, 31);
num_to_str(tempid, szTempid, 9);
// y por ultimo agregamos el item con la informacion obtenida
// previamente, haciendo uso de la funcion menu_additem( )
menu_additem(menu, szName, szTempid);
// cabe aclarar que todo lo explicado recientemente esta dentro de
// un loop, por lo cual esto se hace una y otra vez con cada player
// que esta conectado en el server y asi muestra la lista completa
// tambien cabe aclarar que este es un ejemplo, cada uno puede usar
// su propio metodo, por ejemplo esto se puede hacer tambien sin el uso
// de get_players( ), es decir... usando get_maxplayers( )
}
// ahora que ya tenemos todos los items creados cons u respectiva informacion
// nos queda simplemente mostrar el menu con esos items
menu_display(id, menu);
return PLUGIN_HANDLED;
}
public PlayerMenuHandler(id, menu, item)
{
// en esta parte solo se va a explicar lo "nuevo", ya que lo demas esta
// explicado en el tutoriald el menu basico, por lo que no es necesario
if(item == MENU_EXIT)
{
menu_destroy(menu);
return PLUGIN_HANDLED;
}
new iData[6], iName[64];
new access, callback;
menu_item_getinfo(menu, item, access, iData,5, szName, 63, callback);
// con esto convertimos el string iData en un numero, iData en este caso
// contiene el id de cada player encontrado previamente
// y le asignamos ese id a la nueva variable creada llamada "iTarget"
new iTarget = str_to_num(iData);
// ahora si esta vivo el player le agregamos + 50 de vida y hacemos
// un client_print( ) mostrando tambien su nombre
if(is_user_alive(iTarget) )
{
set_user_health(tempid, get_user_health(iTarget) + 50);
client_print(id, print_chat, "Se le sumo 50 de vida al player %s", szName);
}
menu_destroy(menu);
return PLUGIN_HANDLED;
}
Menu Basico de Vote [top]
* Para poder entender este tipo de menu, se requiere haber entendido el Menu Basico y el Menu de Players
Code:
#include <amxmodx>
// en esta variable se va a guardar el menu de vote
// como ven en este caso lo hacemos globalmente y no
// dentro del plugin_init( ) como en otros ejemplos
new gVoteMenu;
// en esta variable se va a guardar los votos por cada
// opcion, como veran el tamaņo del array es de 2
// es porque van a ser 2 opciones, ustedes deberan
// poner el tamaņo adecuado dependiendo de los votos
// que van a utilizar en su menu
new gVotes[2];
// esta variable va a determinar si un voto esta
// en actual proceso
new gVoting;
public plugin_init()
{
// registramos el comando por el cual accedemos al menu de vote
register_clcmd("say /vote", "HookCmdVoteMenu");
}
public HookCmdVoteMenu(id)
{
// si ya hay un vote en estos momentos, no deberiamos empezar otro
if(gVoting)
{
client_print(id, print_chat, "Ya hay un vote en estos momentos!");
// bloqueamos la funcion y usamos PLUGIN_HANDLED para que en el chat
// no aparezca lo que escribio el player ("/vote" en este caso)
return PLUGIN_HANDLED;
}
// creamos el menu y se lo asignamos a la variable global que previamente creamos
gVoteMenu = menu_create("\rVote Menu:", "VoteMenuHandler");
// Agregamos las opciones de vote
menu_additem(gVoteMenu, "Opcion de Vote #1", "0", 0);
menu_additem(gVoteMenu, "Opcion de Vote #2", "1", 0);
// ahora necesitamos loopear entre todos los players para poder mostrarles el vote
// a todos, esto es similar al Menu de Players, solo que en este caso en vez de
// agregar una opcion por cada player, solo les mostramos el menu a cada player
// No voy a explicar en detalles este loopeo ya que se deberia tener conocimiento
// del Menu de Players previamente explicado en el thread
new players[32], pnum, tempid;
get_players(players, pnum);
for( new i; i<pnum; i++ )
{
tempid = players[i];
// con esto les mostramos el menu a cada player encontrado en el loop
menu_display(tempid, gVoteMenu);
// incrementamos la variable gVoting para saber cuantos players se
// encontraron y estan votando
gVoting++;
}
// creamos un task para finazliar el vote luego de haber pasado 10 segundos
set_task(10.0, "EndVote");
return PLUGIN_HANDLED;
}
public VoteMenuHandler(id, menu, item)
{
// si el menu fue cerrado o si no hay ningun vote
if(item == MENU_EXIT || !gVoting)
{
// bloqueamos la funcion con PLUGIN_HANDLED
// en este caso no se requiere de menu_destroy( )
// porque todavia el voto no finalizo
return PLUGIN_HANDLED;
}
new data[6], iName[64];
new access, callback;
menu_item_getinfo(menu, item, access, data, 5, iName, 63, callback);
// obtenemos el id de la opcion que el player selecciono
new voteid = str_to_num(data);
// incrementamos el vote de la opcion seleccionada
gVotes[voteid]++;
return PLUGIN_HANDLED;
}
// ahora hacemos uso del task para finalizar el vote luego de haber pasado 10 segundos
public EndVote()
{
// si la primer opcion del menu recibio mas votos
if( gVotes[0] > gVotes[1] )
client_print(0, print_chat, "La primer opcion recibio mas votos (%d)", gVotes[0] );
// en cambio si la segunda opcion recibio mas votos
else if( gVotes[0] < gVotes[1] )
client_print(0, print_chat, "La segunda opcion recibio mas votos (%d)", gVotes[1] );
// en cambio si no hubo votos o hubo un empate entre las 2 opciones
else
client_print(0, print_chat, "Los votos empataron con un numero de %d votos cada opcion", gVotes[0] );
// no se olviden de destruir el menu ya que ahora terminamos completamente
menu_destroy(gVoteMenu);
// reseteamos la variable gVoting a 0 para que ya se pueda volver a votar nuevamente
gVoting = 0;
}
Sub-Menu [top]
* Para poder entender este tipo de menu, se requiere haber entendido el Menu Basico
Code:
#include <amxmodx>
public plugin_init()
{
register_clcmd("say /menu", "HookCmdMenu");
}
public HookCmdMenu(id)
{
new menu = menu_create("\rMenu con Submenu:", "HookMenuHandler")
menu_additem(menu, "Opcion #1", "1", 0);
menu_additem(menu, "Ir al SubMenu", "2", 0);
menu_setprop(menu, MPROP_EXITNAME, "Salir");
menu_setprop(menu, MPROP_EXIT, MEXIT_ALL);
menu_display(id, menu, 0);
return PLUGIN_HANDLED;
}
public HookMenuHandler(id, menu, item)
{
if(item == MENU_EXIT)
{
menu_destroy(menu);
return PLUGIN_HANDLED;
}
new data[6], iName[64];
new access, callback;
menu_item_getinfo(menu, item, access, data, 5, iName, 63, callback);
new key = str_to_num(data);
switch(key)
{
case 1:
{
client_print(id, print_chat, "Seleccionaste la opcion numero #1");
}
case 2:
{
// al seleccionar la opcion #2 ponemos una nueva funcion
// que nosotros debemos crear luego y mostrar otro menu
SubMenu(id);
}
}
menu_destroy(menu);
return PLUGIN_HANDLED;
}
// esta funcion es la que va a ser usada cuando el player elija la opcion #2 del primer menu
SubMenu(id)
{
// recuerden usar otro nombre al handler de la funcion, ya que es OTRO menu
new menu = menu_create("\rSoy un Submenu:", "HookSubMenuHandler")
menu_additem(menu, "\wOpcion #1", "1", 0);
menu_additem(menu, "\wOpcion #2", "2", 0);
menu_setprop(menu, MPROP_EXIT, MEXIT_ALL);
menu_display(id, menu, 0);
// en este caso no necesitamos returnear PLUGIN_HANDLED para bloquear
// la funcion ya que no estamos usando un comando para acceder a este
// menu, por lo cual no se mostrara nada en el chat
}
public HookSubMenuHandler(id, menu, item)
{
if(item == MENU_EXIT)
{
menu_destroy(menu);
// aca lo que hacemos es que si el usuario sigue conectado y cierra
// el submenu, le mostramos el menu principal, esto es opcional
if(is_user_connected(id) )
HookCmdMenu(id);
return PLUGIN_HANDLED;
}
new data[6], iName[64];
new access, callback;
menu_item_getinfo(menu, item, access, data, 5, iName, 63, callback);
new key = str_to_num(data);
switch(key)
{
case 1:
{
client_print(id, print_chat, "Seleccionaste la opcion #1 del submenu");
}
case 2:
{
client_print(id, print_chat, "Seleccionaste la opcion #2 del submenu");
}
}
menu_destroy(menu);
// al elegir una opcion del menu, si queremos que aparezca el menu principal,
// agregamos lo siguiente:
HookCmdMenu(id);
return PLUGIN_HANDLED;
}
En construccion...
__________________
Approved Plugins - Steam Profile
Public non-terminated projects:
All Admins Menu, HLTV parameters, Subnick,
Second Password (cool style), InfoZone,
Binary C4 plant/defuse, and more...
Private projects:
NoSpec (+menu), NV Surf Management,
PM Adanved System, KZ longjump2, and more...
Last edited by Alucard^; 07-16-2010 at 01:57.
|
|