Bueno, ahora que estoy muy al pedo, voy a explicar como crear logros, de la manera en que siempre lo he hecho yo.
Aclaro que la guia va dedicada a gente que conoce los conceptos basicos sobre scripting (Como crear un menu, que es un loop, variable, etc)
Esto es solo una guia, ustedes pueden agregar mas logros, y lo unico que deben hacer es saber como y donde usar la funcion pCheckLogro para otorgar el logro, es algo sencillo dentro de todo.
Espero que les haya servido, salud!
Aclaro que la guia va dedicada a gente que conoce los conceptos basicos sobre scripting (Como crear un menu, que es un loop, variable, etc)
Código PHP:
/* Script generated by Pawn Studio */
// Bueno, empecemos
#include <amxmodx>
#include <amxmisc>
#define PLUGIN "[GUIA] Logros"
#define AUTHOR "Gonza.-*"
#define VERSION "1.0.0"
// Creamos un enum para los nombres de los logros y su descripcion
enum _:LOGROS
{
LOGROS_NOMBRE = 0,
LOGROS_DESCRIPCION
}
// Creamos otro enum para definir las categorias de los logros
enum _:LOGROS_TIPO
{
LOGROS_TT = 0,
LOGROS_CT,
LOGROS_GENERALES
}
// Ahora definimos nuestros logros y su descripcion para cada categoria
// Ahora solo dejamos correr nuestra imaginacion!
new const LogrosTT[LOGROS][][] =
{
// Nombre
{
"El DIOS de la glock" // 0 Esto es la enumeracion del logro (Lo usamos de ayuda para pCheckLogro)
// Si hay otro logro, deberia ir sumandose +1 al anterior, es decir, el segundo logro valdria 1, el tercero 2, y asi sucesivamente
},
// Descripcion
{
"Mata a 3 CTs con Glock en una ronda" // 0
}
}
new const LogrosCT[LOGROS][][] =
{
// Nombre
{
"El CT mas potente" // 0
},
// Descripcion
{
"Mata a 5 TTs en una ronda con M4A1^n^n\
\r- \yNOTA:\w Debe ser de HeadShot!" // 0
}
}
new const LogrosGEN[LOGROS][][] =
{
// Nombre
{
"Bombardeando la ciudad" // 0
},
// Descripcion
{
"Mata a 3 o mas enemigos con HE Grenade en una ronda" // 0
}
}
// Creamos una variable para saber si el logro fue completado o no
new g_logros[33][LOGROS_TIPO][100] // 100 = Max Logros (Por categoria)
// Creamos variables para poder contar los frags nesesarios para los logros
new g_GlockFrags[33], g_M4A1Frags[33], g_HEFrags[33]
// Creamos dos variable para utilizar solo dos sub-menus que cambien segun la categoria de logros
new g_Menu[33], g_MenuLogro[33]
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
// say /logros para ver el menu de logros!
register_clcmd("say /logros", "MenuLogros")
// Registramos el menu de la descripcion de los logros
// 1 << 9 = Solo podemos apretar el item 0
register_menu("Descripcion", 1 << 9, "MenuLogrosDesc_h")
// Eventos nesesarios para los logros
register_event("HLTV", "event_RoundStart", "a", "1=0", "2=0") // Evento de inicio de ronda
register_event("DeathMsg", "event_DeathMsg", "a") // Evento de muertes
}
// Creamos un menu con las categorias de los logros
public MenuLogros(id)
{
new menu = menu_create("Menu de logros", "MenuLogros_h")
// Deben estar en el mismo orden que en el enum LOGROS_TIPO
menu_additem(menu, "Logros TT")
menu_additem(menu, "Logros CT")
menu_additem(menu, "Logros GENERALES")
menu_setprop(menu, MPROP_EXITNAME, "Cerrar")
menu_display(id, menu)
}
public MenuLogros_h(id, menu, item)
{
if (item == MENU_EXIT) // Si apretamos en "Cerrar"
{
menu_destroy(menu) // Destruimos el menu
return PLUGIN_HANDLED // Debe retornar en PLUGIN_HANDLED para que no haya problemas entre el old y el new menu system
}
// Es importante que esta variable valga lo mismo que el valor de las categorias (LOGROS_TIPO)
g_Menu[id] = item // Si es 0 muestra logros TT, si es 1 muestra logros CT y si 2 muestra logros GENERALES
MenuLogrosCategoria(id) // Vamos al primer sub-menu
menu_destroy(menu)
return PLUGIN_HANDLED
}
public MenuLogrosCategoria(id)
{
new szTitle[16]
formatex(szTitle, charsmax(szTitle), "%s", !g_Menu[id] ? "Logros TT" : g_Menu[id] == 1 ? "Logros CT" : "Logros GENERALES")
new menu = menu_create(szTitle, "LogrosCat_h")
// Realizamos un loop con los nombres de los logros
new maxloop = !g_Menu[id] ? sizeof(LogrosTT[]) : g_Menu[id] == 1 ? sizeof(LogrosCT[]) : sizeof(LogrosGEN[])
new szNombre[60], szNum[5] // Para el nombre del item y el numero de logro
for (new logro; logro < maxloop; logro++)
{
// Agregamos un item con el nombre del logro y si esta completo o no
formatex(szNombre, charsmax(szNombre), "%s %s", !g_Menu[id] ? LogrosTT[LOGROS_NOMBRE][logro] : g_Menu[id] == 1 ? LogrosCT[LOGROS_NOMBRE][logro] : LogrosGEN[LOGROS_NOMBRE][logro], g_logros[id][g_Menu[id]][logro] ? "\y(COMPLETO)" : "\d(INCOMPLETO)")
num_to_str(logro, szNum, charsmax(szNum))
menu_additem(menu, szNombre, szNum)
}
menu_setprop(menu, MPROP_NEXTNAME, "Siguiente")
menu_setprop(menu, MPROP_BACKNAME, "Anterior")
menu_setprop(menu, MPROP_EXITNAME, "Atras")
menu_display(id, menu)
}
public LogrosCat_h(id, menu, item)
{
if (item == MENU_EXIT)
{
menu_destroy(menu)
MenuLogros(id)
return PLUGIN_HANDLED
}
new ac, cb, num[5]
menu_item_getinfo(menu, item, ac, num, charsmax(num), "", 0, cb) // Obtenemos el numero del logro
g_MenuLogro[id] = str_to_num(num) // Seteamos el numero de logro en la variable
MenuLogrosDescripcion(id) // Segundo sub-menu con la descripcion del logro
menu_destroy(menu)
return PLUGIN_HANDLED
}
public MenuLogrosDescripcion(id)
{
new szText[512], len
len += formatex(szText[len], charsmax(szText) - len, "\yMenu de logros\d [%s]^n^n", !g_Menu[id] ? "TT" : g_Menu[id] == 1 ? "CT" : "GENERALES")
len += formatex(szText[len], charsmax(szText) - len, "\r-\y NOMBRE:\w %s^n^n",
g_Menu[id] == LOGROS_TT ? LogrosTT[LOGROS_NOMBRE][g_MenuLogro[id]] : g_Menu[id] == LOGROS_CT ? LogrosCT[LOGROS_NOMBRE][g_MenuLogro[id]] : LogrosGEN[LOGROS_NOMBRE][g_MenuLogro[id]])
len += formatex(szText[len], charsmax(szText) - len, "\r-\y DESCRIPCION:\w %s^n^n",
g_Menu[id] == LOGROS_TT ? LogrosTT[LOGROS_DESCRIPCION][g_MenuLogro[id]] : g_Menu[id] == LOGROS_CT ? LogrosCT[LOGROS_DESCRIPCION][g_MenuLogro[id]] : LogrosGEN[LOGROS_DESCRIPCION][g_MenuLogro[id]])
len += formatex(szText[len], charsmax(szText) - len, "\r0.\w Atras")
show_menu(id, 1 << 9, szText, -1, "Descripcion")
}
// Como el unico boton que podemos tocar es 0 (Atras) mostramos directamente el sub-menu anterior
public MenuLogrosDesc_h(id, key) MenuLogrosCategoria(id)
// Cuando el jugador ingresa al servidor...
public client_putinserver(id)
{
// Seteamos los contadores en 0
g_GlockFrags[id] = 0
g_M4A1Frags[id] = 0
g_HEFrags[id] = 0
// Y los logros en incompletos (Si usa un sistema de guardado, hagalo como y donde corresponda)
arrayset(g_logros[id][LOGROS_TT], 0, sizeof(g_logros[][]))
arrayset(g_logros[id][LOGROS_CT], 0, sizeof(g_logros[][]))
arrayset(g_logros[id][LOGROS_GENERALES], 0, sizeof(g_logros[][]))
}
// Cuando inicia una nueva ronda...
public event_RoundStart()
{
// Hacemos un loop por todos los jugadores reseteando las variables
for (new id = 1; id <= get_maxplayers(); id++)
{
g_GlockFrags[id] = 0
g_M4A1Frags[id] = 0
g_HEFrags[id] = 0
}
}
// Cada vez que un jugador muere...
public event_DeathMsg()
{
new killer = read_data(1) // Obtenemos el index del atacante
new victim = read_data(2) // Obtenemos el index de la victima
new headshot = read_data(3) // Obtenemos si fue de headshot (1 si, 0 no)
new weapon[64]
read_data(4, weapon, charsmax(weapon)) // Obtenemos el nombre del arma con el que se produjo el asesinato xD
// Si se suicido (con una bomba por ejemplo), o lo mato una entidad o una caida, retornamos
if (!is_user_connected(killer) || killer == victim) return
// Obtenemos el team del atacante y de la victima
new team = get_user_team(killer)
new vteam = get_user_team(victim)
// Si el arma del atacante fue una Glock y el atacante es TT y la victima es CT
if (equali(weapon, "glock18") && team == 1 && vteam == 2)
{
g_GlockFrags[killer]++ // Sumamos un kill con Glock al atacante!
// El logro dice lo siguiente "Mata a 3 CTs con Glock en una ronda"
if (g_GlockFrags[killer] >= 3) pCheckLogro(killer, LOGROS_TT, 0) // Otorgamos el logro
}
// Si el arma del atacante fue una M4A1 y el atacante es CT y la victima es TT, y fue HEADSHOT
else if (equali(weapon, "m4a1") && team == 2 && vteam == 1 && headshot)
{
g_M4A1Frags[killer]++ // Sumamos un kill con M4A1 al atacante!
// El logro dice "Mata a 5 TTs en una ronda con M4A1 de HeadShot"
if (g_M4A1Frags[killer] >= 5) pCheckLogro(killer, LOGROS_CT, 0) // Otorgamos el logro
}
// Si el arma del atacante fue una HE Grenade y la victima no es de tu mismo team
else if (equali(weapon, "grenade") && team != vteam)
{
g_HEFrags[killer]++ // Sumamos un kill con HE Grenade al atacante!
// El logro dice "Mata a 3 o mas enemigos con HE Grenade en una ronda"
if (g_HEFrags[killer] >= 3) pCheckLogro(killer, LOGROS_GENERALES, 0) // Otorgamos el logro
}
}
// Funcion dedicada a completar los logros y avisar en el chat quien hizo un logro y cual fue
// id = index del jugador que completo el logro
// Logro = enum LOGROS_TIPO
// LogroNum = el numero del logro (Lo que comentamos como 0 al final de cada linea al crear los nombres y descripcion de los logros)
public pCheckLogro(id, Logro, LogroNum)
{
// Si el logro ya fue completado, retornamos
if (g_logros[id][Logro][LogroNum]) return
// Seteamos la variable en 1 para saber que el jugador completo un logro
g_logros[id][Logro][LogroNum] = 1
// Obtenemos el nombre del jugador
new szName[33]
get_user_name(id, szName, charsmax(szName))
// Mostramos por say el nombre del jugador que completo el logro, y el nombre del logro
client_print(0, print_chat, "El jugador %s completo el logro ^"%s^"", szName,
Logro == LOGROS_TT ? LogrosTT[LOGROS_NOMBRE][LogroNum] : Logro == LOGROS_CT ? LogrosCT[LOGROS_NOMBRE][LogroNum] : LogrosGEN[LOGROS_NOMBRE][LogroNum])
}
Esto es solo una guia, ustedes pueden agregar mas logros, y lo unico que deben hacer es saber como y donde usar la funcion pCheckLogro para otorgar el logro, es algo sencillo dentro de todo.
Espero que les haya servido, salud!