Jump to content

Ayuda NPC Ranking


kiova

Recommended Posts


  • Group:  Members
  • Topic Count:  23
  • Topics Per Day:  0.01
  • Content Count:  59
  • Reputation:   0
  • Joined:  09/02/12
  • Last Seen:  

Hola.

Me podrian ayudar a crear un script de ranking pero que se base en una variable?? os explico

Imaginaos que mediante quest un npc os da un punto ejemplo:

set punto,punto+1 a un personaje.

 

Se podria crear un ranking de por ejemplo los 10 personajes con mas puntos???

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  1
  • Topics Per Day:  0.00
  • Content Count:  182
  • Reputation:   36
  • Joined:  01/26/12
  • Last Seen:  

Sí, pero tienes que usar SQL para obtener el ranking y consultas SQL con algún JOIN (búsqueda simultánea en varias tablas) para determinar el nombre de un personaje a partir de su Char ID, porque supongo que con el char ID no te bastará.

 

Estoy bastante oxidadillo con esto de consultas SQL en scripting (y más si hay que usar JOINs, pero si con esta ayudita pequeña que apenas sirve de nada no puedes, puedo intentar repasarme un poco de scripting y echarte una mano algo más directamente.

 

¡Un saludo!

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  23
  • Topics Per Day:  0.01
  • Content Count:  59
  • Reputation:   0
  • Joined:  09/02/12
  • Last Seen:  

Aunque se me da fatal todo lo que sea script con consultas SQL no me preguntes por que pero jamas me a quedado muy claro eso XD. Si me puedes ayudar te lo agradeceria, igualmente intentaré haber si puedo conseguirlo pero lo dudo XD



Creo que debería comprobar la variable en Global Reg Value y el Char ID y convertirlo a nombre y numero en el NPC supongo no?



Estas cosas no las llevo por la mano por desgracia... T_T

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  1
  • Topics Per Day:  0.00
  • Content Count:  182
  • Reputation:   36
  • Joined:  01/26/12
  • Last Seen:  

¡Buenas! Siento tardar en la respuesta, pero ayer la tenía redactada al completo y se me borró justo cuando la iba a enviar, me enfadé porque la hice bastante completita. Soy consciente de que es una respuesta larga, pero además pretendo ser didáctico.

 

(Antes de que lo que redacté durante alrededor de una hora se desvaneciera) Te propuse una segunda solución, mucho más sencilla y rápida de hacer pero menos elegante, la cual usé en mi último servidor sin ningún problema y me simplificaba muchísimo la creación de rankings. Además facilitaba también el visionado de los mismos rankings desde la propia web del servidor.

 

Esta segunda solución pasa por crear un nuevo campo en la tabla `char`, de valor entero, el cual para este ejemplo llamaré `puntosranking`. Esto deberías hacerlo desde PhpMyAdmin con un usuario que tenga privilegios para alterar tablas de la base de datos que uses en el emulador (supongo que ya sabes que es la que por defecto se llama `ragnarok`). Entonces, deberías ejecutar esto en la base de datos `ragnarok`:

ALTER TABLE `char` ADD `puntosranking` INT NOT NULL DEFAULT '0';

Tranquilo, a menos que actualicen las bases de datos no tendrás nunca ningún problema con esto. Este es el primer motivo por el que no se trata de una solución elegante.

 

Entonces ya con esto tienes las dos variables que necesitas (nombre y puntos) en la misma tabla, de tal manera que ya puedes olvidarte por completo de usar JOINs (que no es tan complicado pero a veces se las trae). Ahora necesitamos una consulta SQL que recoja la información que buscamos de la forma que queremos. Entonces podemos usar un SELECT básico para recoger los datos que queremos. En este caso la consulta sería:

SELECT `name`, `puntosranking`
FROM `char`
ORDER BY `puntosranking` DESC, `name` ASC
LIMIT 10

La cual devuelve el nombre y los puntos del ranking almacenados en nuestra tabla, ordenada primero por puntos del ranking y en caso de empate se ordena alfabéticamente (podrías ordenarlo por account_id ascendente si quieres dar esa ventaja a los usuarios más viejos o incluso pasar de esta segunda ordenación, pero siempre conviene mantener un orden estricto en los resultados de las consultas). Ahora necesitamos implementarlo en una consulta SQL que pueda usar un NPC y recoger sus resultados. ¿Como? Suponiendo que sabes usar la estructura del script command query_sql, la cual es:

query_sql "your MySQL query", <array variable> {,<array variable>, ...};

Y teniendo cuidado de que la consulta se mantenga en una sola línea, nos queda:

query_sql "SELECT `name`, `puntosranking` FROM `char` ORDER BY `puntosranking` DESC, `name` ASC LIMIT 10", .@nombres$, .@puntos;

Donde .@nombres$ es un array que contiene los nombres de los 10 usuarios con más puntos y .@puntos es otro array que contiene sus respectivos puntos. Ya puedes usar esos arrays para lo que necesites a través de scripting.

 

Pero... ¿cómo añades o restas puntos a un jugador si las variables permanentes de PJ normales no funcionan así? Pues estamos ante el otro motivo por el que tampoco esta solución es elegante. Hay que usar otra consulta SQL para esto (a menos que sepas modificar el source y usarlo directamente como variable de PJ, en cuyo caso te pediría que compartieras el resultado si puedes porque también lo necesitaría). Afortunadamente, las consultas SQL para añadir o restar puntos son sencillas y directas, aunque estas pueden ejecutarse solo a través de scripting desde el juego, si quieres hacerla directamente en la base de datos es más rápido hacerlas a través de PhpMyAdmin.

query_sql "UPDATE `char` SET `puntosranking` = `puntosranking` + 1 WHERE `char_id` = " + getcharid(0) + " LIMIT 1";

Esta consulta SQL añade un punto para el ranking al PJ desde el que se ejecute el script. Para variar la cantidad de puntos o añadir puntos a otros jugadores que no sea el que ejecuta el script el procedimiento es análogo.

 

Supongo que sabiendo esto ya podrás integrarlo sin problemas en tus scripts.

 

Si aún así prefieres la solución elegante, intentaré echarle un vistazo. ¡Un saludo!

  • Upvote 1
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  23
  • Topics Per Day:  0.01
  • Content Count:  59
  • Reputation:   0
  • Joined:  09/02/12
  • Last Seen:  

El problema de todo esto es que esos puntos ya están otorgados a usuarios y imagino que implantar una nueva tabla SQL no se si daría resultado ya que actualmente tienen puntos otorgados mediante quest.

Creo que haciendo todo esto funcionaria perfectamente siempre y cuando se dieran los puntos despues de aplicar la nueva tabla o eso creo... Funcionaria ahora si la gente ya tiene esos puntos otorgados??



PD: No te preocupes por tardar XD yo intenté hacerlo pero por desesperación lo deje XD

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  1
  • Topics Per Day:  0.00
  • Content Count:  182
  • Reputation:   36
  • Joined:  01/26/12
  • Last Seen:  

Hay una consulta SQL que pueda hacerse desde la tabla `char` ampliada que pueda recoger los valores de los puntos otorgados, pero ahora mismo no doy con la tecla. Hay que pelearse con consultas SQL anidadas que sepan hacerlo o bien genera un web script que te las inserte.

 

Voy a intentar buscar cómo se hacía para obtener esas 10 posiciones sin "trampa". Mientras tanto mantén activa la petición en scripting Support a ver si alguien logra encontrar la solución antes que yo. Simplemente para responder diciendo que no sirve di que no valía o algo.

Edited by jaBote
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  23
  • Topics Per Day:  0.01
  • Content Count:  59
  • Reputation:   0
  • Joined:  09/02/12
  • Last Seen:  

Ok Muchas gracias por tu ayuda, yo igualmente seguiré intentando una solución, por que creo que también se puede hacer sin consultas SQL, o eso creo. Existe un script de ranking MVP que tengo por aquí que basicamente es lo mismo que quiero hacer, pero como ya estan otorgados esos puntos de variables no se si es posible hacerlo ya...

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  1
  • Topics Per Day:  0.00
  • Content Count:  182
  • Reputation:   36
  • Joined:  01/26/12
  • Last Seen:  

No sé si he dado con lo que tenía que dar, parece que sí. Prueba a usar esto en tu casero desde PhpMyAdmin (o en tu servidor después de hacer un backup), que no puedo testearlo ahora mismo en un casero porque no dispongo de nadie con quien usarlo. Aun así un SELECT no debería nunca fastidiarte la base de datos:

SELECT `char`.`name` AS `nombre`, `global_reg_value`.`value` AS `puntos`
FROM `global_reg_value`
LEFT JOIN `char` ON `global_reg_value`.`char_id` = `char`.`char_id`
WHERE `global_reg_value`.`type` =3
AND `global_reg_value`.`str` = 'punto'
ORDER BY `puntos` DESC, `nombre` ASC
LIMIT 10

Una vez compruebes que funciona (¡Importante!) inserta dicha consulta en un NPC, la cual en una sentencia de scripting sería:

query_sql "SELECT `char`.`name` AS `nombre`, `global_reg_value`.`value` AS `puntos` FROM `global_reg_value` LEFT JOIN `char` ON `global_reg_value`.`char_id` = `char`.`char_id` WHERE `global_reg_value`.`type` = 3 AND `global_reg_value`.`str` = 'punto' ORDER BY `puntos` DESC, `nombre` ASC LIMIT 10", .@nombre$, .@puntos;

 
Y creo que ya sabrías qué hacer con los arrays .@nombre$ y .@puntos.

Ahora cuando pruebes me cuentas. Malditos JOINs y su enrevesada sintaxis...

Edited by jaBote
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  23
  • Topics Per Day:  0.01
  • Content Count:  59
  • Reputation:   0
  • Joined:  09/02/12
  • Last Seen:  

Ok. Lo probaré en mi server de pruebas. Ahora te digo algo y gracias por el esfuerzo que parece que te estoy explotando XD



Muchas gracias 

jaBote

Me ha ido de lujo. Te pondría 1000 puntos si se puediera XD.

He tardado un poquillo por que he tenido que salir pero lo he probado y esta correcto todo.

Mil Gracias!!!

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  1
  • Topics Per Day:  0.00
  • Content Count:  182
  • Reputation:   36
  • Joined:  01/26/12
  • Last Seen:  

Lo importante es que funciona. Y el problema con eso es que estás consumiendo una variable permanente de personaje, y tienes solo 256 a menos que lo edites en mmo.h. Además esa consulta SQL te puede servir para reproducir tu ranking en la web con PHP por ejemplo.

 

Creo que voy a adoptar otra solución cuando haga otro servidor, porque voy a tener rankings incluso para morir xD

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  23
  • Topics Per Day:  0.01
  • Content Count:  59
  • Reputation:   0
  • Joined:  09/02/12
  • Last Seen:  

jajajajaja. Si te puedo ayudar en algo avisame

Link to comment
Share on other sites

  • 2 months later...

  • Group:  Members
  • Topic Count:  1
  • Topics Per Day:  0.00
  • Content Count:  5
  • Reputation:   0
  • Joined:  11/17/12
  • Last Seen:  

usa esta funcion que cree yo, donde se le envian varios argumentos.

el getarg(0), son los puntos actuales de un player.

el getarg(1), es el nombre del pj.

Puedes llamar a esta funcion cada vez que un player consiga un punto de esta manera:

callfunc ("RankPuntTop",K_punt,strcharinfo(0)); //K_punt es la variable donde se el player guarda los puntos

function script RankPuntTop {

set @mtotal, getarg(0);

set @nomb$, getarg(1);

set @reem,0;

for (set .@c, 0; .@c <= getarraysize($top_rank); set .@c, .@c + 1)

{

if (@nomb$ == $topN_rank$[.@c]) //comprobacion de que ya esta en el ranking, si lo esta le damos su nuevo valor

{

set @reem,1;

set $top_rank[.@c],@mtotal;

}

}

set .@c,.@c - 1; //si no esta, preparamos e incluimos este nuevo registro al final del ranking

if (@reem == 0)

{

set $top_rank[.@c],@mtotal;

set $topN_rank$[.@c],@nomb$;

}

// hasta aqui inclusion de datos

// reorganizacion de array // se va haciendo comparaciones hasta que el ranking queda ordenado

set .@t,(getarraysize($top_rank)-1);

for (set .@d,.@t;.@d > 0; set .@d, .@d - 1)

{

set .@actualran,$top_rank[.@d];

set .@siguiran,$top_rank[(.@d - 1)];

set .@plaactual$,$topN_rank$[.@d];

set .@plasigui$,$topN_rank$[(.@d - 1)];

if (.@actualran > .@siguiran)

{

set $top_rank[(.@d-1)],.@actualran;

set $topN_rank$[(.@d-1)],.@plaactual$;

set $top_rank[.@d],.@siguiran;

set $topN_rank$[.@d],.@plasigui$;

}

}

//eliminacion de los que no deben estar en el top

deletearray $top_rank[10],.@t;

deletearray $topN_rank$[10],.@t;

return;

} // End function

dentro de esos dos arrays tienes los nombres y los puntos desde $top_rank[0] a $top_rank[9] y en $topN_rank$

Edited by ratcham
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...