Jump to content

ElRaulxX

Miembro
  • Contador contenido

    49
  • Ingreso

  • Última visita

  • Días ganados

    12

Mensajes publicados por ElRaulxX

  1. Ya hacía tiempo que no me dejaba ver por aquí... que mejor rebienvenida que un nuevo capítulo de nuestro curso quest.

    El curso parece que ha quedado algo muerto, intentaré reavivarlo y mejorarlo con nuevos capítulos y mejoras de los anteriores. Si a keko le apetece que me eche una mano, sino conmigo tenéis más que suficiente. ^^

     

    Bueno, yendo al grano... este capítulo trata de los famosos bucles (loops) tan utilizados en programación y que quizá deberíamos haber tratado antes.

     

    Introducción

     

    Primero de todo, ¿qué es un bucle? Un bucle es un conjunto de sentencias que se repiten un número determinado (o indeterminado - bucles infinitos) de veces en nuestro programa.

    A diferencia de los seres humanos, la mejor característica de un PC no es su inteligencia (al fin y al cabo, no deja de ser una máquina diseñada por nosotros), sino su rapidez. Un ordenador puede procesar en un sólo segundo miles de órdenes; sería poco lógico no aprovechar esta característica en nuestros lenguajes de programación. El método (o mejor dicho, los métodos) que disponemos para utilizar esta característica son los bucles.

    Un bucle repetirá el bloque de sentencias asignadas hasta que la condición asignada sea verdadera.

     

    En lua disponemos de 4 tipos diferentes de bucles. Aunque los 4 tipos no dejan de hacer la misma acción, son diferentes entre si y nos vendrá mejor usar un tipo u otro según la finalidad que tengamos.

    • repeat bloque until condición - bucle repeat
    • while condición do bloque end - bucle while
    • for var = start, stop [, step] do bloque end - bucle for numérico
    • for var_1, ..., var_n in iterador do bloque end - bucle for genérico

    1 - Bucle repeat

    Para los que estéis en el mundillo de la programación, este bucle equivale a la sentencia Do-While en C.

    La estructura del bucle es la siguiente:

    repeat    bloque de sentenciasuntil (condición)

    El bloque (las acciones, funciones que defináis) se ejecutará al entrar al bucle hasta llegar a 'until (condición)'. Entonces se comprobará la condición definida. Si dicha condición no es verdadera se volverá al principio del bucle y se ejecutará de nuevo. Este proceso se repetirá hasta que la condición sea verdadera.

     

    Un ejemplo de uso de éste bucle es el siguiente:

    quest metin2zone begin    state start begin        when 20016.chat."Probando bucle repeat" begin            say_title("Probando bucle repeat")            local i = 0 --definimos una variable a verificar en la condición            repeat                i = i + 1 --modificamos la variable adecuadamente para evitar un bucle infinito                say(i)            until (i == 10) --definimos una condición        end --when    end --stateend --quest

    Este ejemplo mostrará en pantalla lo siguiente:

    Probando bucle repeat12345678910

    Como podéis comprobar, la primera vez que se entra al bucle la variable i se modifica su valor a 1 y, como la condición (1 == 10) es falsa, se repite el bucle. En el momento que el valor de i es 9 (ha ido aumentando en el bucle) nos encontraremos al principio del bucle, lo que hará que se modifique a 10 y, como la condición (10 == 10) es verdadera, el bucle finalizará.

     

    Teniendo todo esto en cuenta, para crear un bucle infinito (en el punto 6 podéis ver su utilidad en quest) con el bucle repeat deberíamos hacer lo siguiente:

    repeat    bloqueuntil false

    A RECORDAR:

    • La condición del bucle repeat se comprueba al final del bloque y las sentencias se repetirán hasta que la condición sea verdadera. Esto significa que el código se ejecutará por lo menos una vez.
    • Para continuar el bucle la condición debe ser falsa.
    • El bucle repeat no necesita ser cerrado con ningún end.

    2 - Bucle while

    Para los que estéis en el mundillo de la programación, este bucle equivale a la sentencia While en C.

    La estructura del bucle es la siguiente:

    while (condición) do    bloque de sentenciasend

    El bloque se ejecutará al entrar al bucle sólo si la condición es cierta. Esto significa que el bucle while será ignorado si la primera vez que se entra al bucle la condición es falsa.

    Tras entrar al bucle y llegar al final del bloque se comprobará la condición. Si dicha condición es verdadera se volverá a ejecutar el bloque. Este proceso se repetirá hasta que la condición no sea verdadera.

     

    Un ejemplo de uso de éste bucle es el siguiente:

    quest metin2zone begin	state start begin		when 20016.chat."Probando bucle while" begin			say_title("Probando bucle while")			local i = 0 --definimos una variable a verificar en la condición			while (i != 10) do --definimos una condición				i = i + 1 --modificamos la variable adecuadamente para evitar un bucle infinito				say(i)			end --while		end --when	end --stateend --quest

    Este ejemplo mostrará en pantalla lo siguiente:

    Probando bucle while12345678910

    Como podéis comprobar, se entra al bucle porque la variable i es diferente a 10. Al entrar al bucle la variable i se modifica su valor a 1 y, como la condición (1 != 10) es verdadera, se repite el bucle. En el momento que el valor de i es 9 (ha ido aumentando en el bucle) nos encontraremos al principio del bucle, lo que hará que se modifique a 10. Entonces (a diferencia del repeat) vuelve a comenzar el bucle pero, como la condición (10 != 10) es falsa, el bucle finalizará.

     

    Teniendo todo esto en cuenta, para crear un bucle infinito (en el punto 6 podéis ver su utilidad en quest) con el bucle while deberíamos hacer lo siguiente:

    while true do    bloqueend

    A RECORDAR:

    • La condición del bucle while se comprueba al principio del bloque y las sentencias se repetirán hasta que la condición sea falsa. Esto significa que el bucle puede ser ignorado y su código no ejecutado.
    • Para continuar el bucle la condición debe ser verdadera.
    • El bucle while debe ser cerrado con un end.

    3 - Bucle for numérico

    La estructura del bucle es la siguiente:

    for var = start, stop [, step] do    bloque de sentenciasend

    donde var es una variable, y start, stop y step son constantes.

     

    El bucle for es una abreviación de acciones que podrían hacerse con los anteriores dos bucles de una manera más tediosa.

    Veamos un ejemplo de su uso:

    quest metin2zone begin	state start begin		when 20016.chat."Probando bucle for numérico" begin			say_title("Probando bucle for numérico")			for i = 1, 10, 1 do				say(i)			end --for		end --when	end --stateend --quest

    Este ejemplo mostrará en pantalla lo siguiente:

    Probando bucle for numérico12345678910

    Como habéis visto, hemos podido realizar las mismas acciones que en los anteriores bucles pero con una declaración mucho más sencilla.

    Lo que hace este bucle es asignar a una variable local (var) un valor numérico (start). El bucle se irá repitiendo y en cada repetición añadirá (sumará o restará) el valor de step a la variable var. El bucle finalizará cuando el valor de var sea mayor (si step es un número > 0) o menor (si step es un número < 0) que el valor de stop. Igual que pasa en el bucle while, la condición se evalua al principio del bucle.

    El valor de step puede ser omitido (for i = start, end do bloque end). En ese caso, step será siempre 1 (se sumará una unidad a la variable).

     

    La variable var puede tener cualquier identificador (como cualquier otra variable), aunque el nombre más común a poner es i. Esta variable es local, lo que significa que podemos llamarla dentro del bucle pero no fuera. Cuando finalice el bucle no podremos acceder a la variable utilizada.

     

    Este bucle se acostumbra a utilizar para recorrer tablas ya que es fácil de utilizar y de entender, aunque existe una forma más práctica con el bucle for genérico.

    A RECORDAR:

    • Al iniciar el bucle se asigna a una variable un valor numérico. En cada vuelta del bucle se añadirá el valor del tercer argumento hasta que el valor de la variable sea igual al valor del segundo argumento.
    • La sintaxis de este bucle es fácil de recordar ya que siempre es la misma.
    • En caso de omitir el tercer argumento, el valor de este será 1 (se sumará siempre una unidad a la variable).
    • La condición del bucle for numérico se comprueba al principio del bloque.
    • El bucle for numérico debe ser cerrado con un end.

    4 - Bucle for genérico

    La estructura del bucle es la siguiente:

    for var_1, var_2, ..., var_n in iterador do    bloque de sentenciasend

    donde (var_1, var_2, ..., var_n) es un número cualquiera de variables y iterador es una función especial llamada iterador.

     

    Un iterador es aquella función utilizada en un for genérico que devuelve un determinado valor de la estructura que estemos recorriendo con el bucle. El valor que devuelve estas funciones especiales se asigna a (var_1, var_2, ..., var_n). Por lo tanto, el número de variables a declarar depende del iterador.

    Este bucle se utiliza principalmente en las tablas, por eso el uso de éste se explicará en detalle en otro capítulo del curso.

     

    Un ejemplo de uso de éste bucle es el siguiente:

    quest metin2zone begin	state start begin		when 20016.chat."Probando bucle for genérico" begin			say_title("Probando bucle for genérico")			local tab = {"valor1", "valor2", "valor3"}			for k, v in ipairs(tab) do				say(k.." = "..v)			end --for		end --when	end --stateend --quest

    Este ejemplo mostrará en pantalla lo siguiente:

    Probando bucle for genérico1 = valor12 = valor23 = valor3

    Como habéis visto, este bucle viene de perlas para recorrer tablas de una manera más fácil.

    Como ya he dicho, el uso adecuado de este bucle se explicará con más atención en otro capítulo; mientras podéis utilizar el bucle for numérico como os enseñó keko en el capítulo VIII.

     

    5 - La palabra clave break

     

    Hasta ahora hemos visto que un bucle se repetía hasta llegar a una determinada condición. Lua dispone de una segunda manera más controlada por el programador para finalizar el bucle: la palabra clave break.

    Cuando dentro del bloque de sentencias el bucle se encuentre un break, el bucle finalizará automáticamente, independientemente del lugar y estado donde se encuentre el bucle.

     

    Veamos un ejemplo. El siguiente código

    quest metin2zone begin	state start begin		when 20016.chat."Probando bucle while" begin			say_title("Probando bucle while")			local i = 0 --definimos una variable a verificar en la condición			while (i != 10) do --definimos una condición				i = i + 1 --modificamos la variable adecuadamente para evitar un bucle infinito				if i == 3 then					say("Estoy en la posición 3!")				end				say(i)			end --while		end --when	end --stateend --quest

    mostrará en pantalla lo siguiente:

    Probando bucle while12Estoy en la posición 3!345678910

    ¿Qué pasaría si cambiáramos say("Estoy en la posición 3!") por break?

    El código quedaría:

    quest metin2zone begin	state start begin		when 20016.chat."Probando bucle while" begin			say_title("Probando bucle while")			local i = 0 --definimos una variable a verificar en la condición			while (i != 10) do --definimos una condición				i = i + 1 --modificamos la variable adecuadamente para evitar un bucle infinito				if i == 3 then					break				end				say(i)			end --while		end --when	end --stateend --quest

    Y mostrará en pantalla esto:

    Probando bucle while12

    ¿Qué ha pasado? Pues que el bucle a finalizado cuando se ha encontrado el break.

     

    6 - Bucles infinitos en quest

     

    Antes os he hablado de bucles infinitos. ¿Qué utilidad tiene algo que no controlamos (se repetirá siempre)? Ninguna. ¿Pero y si lo combinamos con condiciones y break? Muchísima.

    Veamos un ejemplo:

    quest metin2zone begin	state start begin		when 20016.chat."Probando bucle while" begin			say_title("Probando bucle while")			while true do --definimos un bucle infinito				local s = select("Opción 1", "Opción 2", "Salir") --añadimos un valor a s con la intervención del usuario				if s == 1 then					say("opción 1 seleccionada") --muestra opción 1					wait()				elseif s == 2 then					say("opción 2 seleccionada") --muestra opción 2					wait()				else					break --finaliza el bucle				end			end --while		end --when	end --stateend --quest

    Si lo ejecutamos veréis que nos ha quedado un pequeño menú que, ampliando vosotros mismos, puede llegar a ser un menú dinámico con múltiples opciones. Juntar esta técnica con tablas para obtener grandes resultados. ^^

    Esta es una aplicación de un bucle infinito, podéis hacer con ellos lo que se os ocurra si lo entendéis correctamente.

     

    Changelog

     

    30/08/13 19:26 - Primera publicación oficial del capítulo

     

     

     

    Y aquí llega el final del capítulo. Espero que os haya gustado. ;)

    Cualquier duda que tengáis podéis ponerla en una respuesta a este post.

     

    PD: Más de 2000 palabras en este capítulo. Yeah!

  2. He visto que muchos preguntáis como utilizar querys de sql en quest. Le dije a keko que haría este mini tutorial, y aquí lo tenéis.

    Primero de todo decir que esta función no viene por defecto en el metin y es por eso que algunos usuarios la han hecho ellos mismos, pues la utilidad de esta función es muy grande.
    Tengo contado tres personas que han publicado esta función: Hanashi, mijago y yuko. Quizá han sido publicadas más, pero solamente recuerdo estas.
    A mi parecer, la más practica que he visto hasta ahora es la última versión de mijago y es la que utilizaremos en este Minicurso.


    Primero de todo, debemos declarar estas dos funciones en nuestro questlib.lua

     

    mysql_query = function(query)	if not pre then		local rt = io.open('CONFIG','r'):read('*all')		pre,_= string.gsub(rt,'.+PLAYER_SQL:%s(%S+)%s(%S+)%s(%S+)%s(%S+).+','-h%1 -u%2 -p%3 -D%4')	end	math.randomseed(os.time())	local fi,t,out = 'mysql_data_'..math.random(10^9)+math.random(2^4,2^10),{},{}	os.execute('mysql '..pre..' --e='..string.format('%q',query)..' > '..fi) -- für MySQL51	-- os.execute('mysql '..pre..' -e'..string.format('%q',query)..' > '..fi) -- für MySQL55	for av in io.open(fi,'r'):lines() do table.insert(t,split(av,'t')) end; os.remove(fi);	for i = 2, table.getn(t) do table.foreach(t[i],function(a,b)		out[i-1]			   = out[i-1] or {}		out[i-1][a]			= tonumber(b) or b or 'NULL'		out[t[1][a]]		   = out[t[1][a]] or {}		out[t[1][a]][i-1]	  = tonumber(b) or b or 'NULL'	end) end	return outendfunction split(str, delim, maxNb)	if str == nil then return str end	if string.find(str, delim) == nil then return { str } end	if maxNb == nil or maxNb < 1 then maxNb = 0 end	local result = {}	local pat = "(.-)" .. delim .. "()"	local nb = 0	local lastPos	for part, pos in string.gfind(str, pat) do		nb = nb + 1		result[nb] = part		lastPos = pos		if nb == maxNb then break end	end	if nb ~= maxNb then result[nb + 1] = string.sub(str, lastPos) end	return resultend

     



    ATENCION! Si en nuestro servidor tenemos instalado la versión 5.5 de MySQL debemos borrar esto:

    	os.execute('mysql '..pre..' --e='..string.format('%q',query)..' > '..fi) -- für MySQL51

    y quitar las -- de aquí:

    	--os.execute('mysql '..pre..' -e'..string.format('%q',query)..' > '..fi) -- für MySQL55

    La razón es simple, la sintaxis de esta versión de MySQL es distinta.

    Ahora tenemos que añadir en quest_functions la función:

    mysql_query

    La función split no hace falta añadirla en este archivo ya que se utiliza internamente en mysql_query.

    Bien, ahora ya tenemos instalada la función de mysql.
    Ahora lo más importante: ¿cómo se usa?

    Tenemos esta tabla:
    Imagen enviada
    Como vemos, la tabla se llama 'tablatest' y se encuentra en la db 'test'. Esta tabla posee tres campos, que son 'campo1', 'campo2' y 'campo3'.
    Con la función mysql_query llamaremos, añadiremos o modificaremos valores de esta tabla. La sintaxis de mysql_query es la misma que cualquier otra query de mysql que utilicemos (de navicat, php...). Sino sabéis la sintaxis os aconsejo que miréis cursos para aprender. La sintaxis es muy sencilla y no tiene complicación, solo se necesita mirar un poco y lo dominaréis perfectamente. Existen miles de cursos y tutoriales por internet de mysql, tan solo debéis buscarlos.

    ATENCION: Para utilizar sentencias que retornen algún tipo de valor (select) debemos asignar la función a una variable. Las demás (update, insert into...) tan solo tenemos que utilizarla como cualquier otra función.

    Bien, empecemos. Comenzaremos llamando toda la tabla.

    local read = mysql_query("SELECT * FROM test.tablatest")

    Esto almacenará en la variable la siguiente tabla:

    local read = {[campo1] = {"texto1","texto2","texto3"},[campo2] = {"texto4","texto5","texto6"},[campo3] = {"texto7","texto8","texto9"}}

    Teniendo esto en cuenta, y sabiendo un poco de tablas y arrays en lua está todo solucionado.
    Queremos mostrar en pantalla 'texto5' que está almacenado en nuestra tabla. Lo llamaremos de esta manera.

    local read = mysql_query("SELECT * FROM test.tablatest")say(read.campo2[2])--esto muestra texto5

    Ahora queremos llamar 'texto9':

    local read = mysql_query("SELECT * FROM test.tablatest")say(read.campo3[3])--esto muestra texto9

    Ahora queremos llamar 'texto1':

    local read = mysql_query("SELECT * FROM test.tablatest")say(read.campo1[1])--esto muestra texto1

    Aquí no voy a ponerme a explicar arrays porqué no trata de eso el curso, pero creo que mirando los ejemplos y pensando un poco lo entenderéis.

    Ahora también podemos añadir una condición:

    local read = mysql_query("SELECT * FROM test.tablatest WHERE campo2 = 'texto5'")

    Esto almacenará en la variable la siguiente tabla:

    local read = {[campo2] = {"texto4","texto5","texto6"}}

    Y ahora podemos llamarlo de la misma manera que en el ejemplo anterior.
    Esto nos mostrará 'texto6' en pantalla.

    local read = mysql_query("SELECT * FROM test.tablatest WHERE campo2 = 'texto5'")say(read.campo2[3])--esto muestra texto6

    Y para hacerla verdaderamente útil podemos llamar a variables o funciones.

    local var = "texto5"local read = mysql_query("SELECT * FROM test.tablatest WHERE campo2 = '"..var.."'")say(read.campo2[3])--esto muestra texto6

    Algo importante que hay que decir es que esta función siempre crea tablas y por lo tanto siempre deberemos llamarlo de la misma manera, aunque haya seleccionado un solo valor.

    local read = mysql_query("SELECT campo1 FROM test.tablatest WHERE campo1 = 'texto1'")say(read.campo1[1])--esto muestra texto1

    Creo que con estos ejemplos ya podéis ver como funciona un select (la verdad es que es bastante difícil explicarlo teniendo en cuenta que no tenéis conocimientos de tablas, pero al menos lo he intentado xd). La mejor manera que veáis su uso es que vayáis haciendo pruebas en navicat y luego trasladarlo a una quest.

    Y ahora la segunda parte.
    Si queremos añadir nuevos valores lo hacemos de esta manera:

    mysql_query("INSERT INTO test.tablatest VALUES ('texto10','texto11','texto12')")

    o como hemos hecho antes:

    local v1 = "texto10"local v2 = "texto11"local v3 = "texto12"mysql_query("INSERT INTO test.tablatest VALUES ('"..v1.."','"..v2.."','"..v3.."')")

    Y nos quedará la tabla así:
    Imagen enviada

    Y si queremos modificar valores:

    mysql_query("UPDATE test.tablatest SET campo1='prueba' WHERE campo1='texto10'")
    local x = "prueba"local y = "texto10"mysql_query("UPDATE test.tablatest SET campo1='"..x.."' WHERE campo1='"..y.."'")

    Y nos quedaría esto:
    Imagen enviada

    Sabiendo de mysql no debería ser ninguna complicación, el problema es que no sepáis :huh:
    Cuando publiquemos el capítulo de arrays y tablas lo entenderéis todo mejor, no os preocupéis.

    Y creo que eso es todo. Saludos!

  3. Para utilizar las funciones mysql (al menos las de Mijago) debes asignar el select a una variable y llamar a la tabla que sea crea con los datos recibidos.

    Por ejemplo, esta query ' local test = mysql_query"SELECT * FROM tabla" ' recibe dos campos, uno llamado campo1 con dos valores y otro campo2 con tan solo uno.

    Debes llamarlo de esta manera:

    test.campo1[1] --recibirá el primer valor del campo1

    test.campo1[2] --recibirá el segundo valor del campo1

    test.campo2[1] --recibirá el valor del campo2

     

    Aunque reciba tan solo un valor debes poner el 1 obligatoriamente, pues crea siempre una tabla a la que debes llamar para mostrar el resultado de la query.

     

    Lo demás no le doy importancia... me pones una query, qf... no sé lo que quieres hacer sino te explicas mejor xd

  4. Mi pequeño padawan por fin aprendió :D

     

    Hacer tal multiidioma es tan sencillo como guardar un valor como qf, en un campo nuevo en la db o incluso en un archivo en el servidor asociado a la id del personaje o cuenta. Lo más lógico sería el campo en player/account, pero eso viene a gusto. Tan solo sería utilizar arrays asociando un mismo valor a cada idioma en cada quest, tal como dice keko, o declararlas globalmente en un archivo lua del servidor. Lo mejor, las declaras en el locale.lua y queda to' profesional :fuckyeah:

  5. Si quieres que no se repita debes cambiar el state al que has dejado vacío y has nombrado _COMPLETE_

    Tan solo debes añadir

    set_state("__COMPLETE__")
    
    Al final de la primera parte de la quest.

    Es decir, así sería:

    quest give_basic_weapon begin
    		state start begin
    				when login begin
    					   say_title ( "Bienvenido" )
    					   say_title ( "A Metin2Neocon" )
    					   say ( "" )
    					   pc . give_exp2 ( )
    					   pc . give_item2 ( "70042" , 1 )
    					   pc . give_item2 ( "70007" , 1 )
    					   pc . give_item2 ( "27003" , 200 )
    					   pc . give_item2 ( "27003" , 200 )
    					   pc . give_item2 ( "27003" , 200 )
    					   pc . give_item2 ( "27006" , 200 )
    					   pc . give_item2 ( "72701" , 1 )
       pc . give_item2 ( "71150" , 1 )
    					   pc . give_item2 ( "50052" , 1 )
    					   horse . advance ( 1 )
    					   horse . advance ( 1 )
    					   horse . advance ( 1 )
    					   horse . advance ( 1 )
    					   horse . advance ( 1 )
    					   horse . advance ( 1 )
    					   horse . advance ( 1 )
    					   horse . advance ( 1 )
    					   horse . advance ( 1 )
    					   horse . advance ( 1 )
    					   horse . advance ( 1 )
    					   say_reward ( "" )
    					   say_reward ( "" )
    					   say_reward ( "Recibes 600 Pociones Rojas(G)." )
    					   say_reward ( "Recibes 200 Pociones Azules(G)." )
    					   say_reward ( "Recibes Caballo Armado" )
    					   clear_letter ( )
    					   if pc . job == 0 then
    					   pc . give_item2 ( "11209" , 1 )
    					   pc . give_item2 ( "11219" , 1 )
    					   pc . give_item2 ( "13007" , 1 )
    					   pc . give_item2 ( "14007" , 1 )
    					   pc . give_item2 ( "15007" , 1 )
    					   pc . give_item2 ( "19" , 1 )
    					   pc . give_item2 ( "3009" , 1 )
    					   pc . give_item2 ( "12207" , 1 )
    					   pc . give_item2 ( "16007" , 1 )
    					   pc . give_item2 ( "17007" , 1 )
    					   say_reward ( "Bienvenido a Metin2neocon" )
    					   elseif pc . job == 1 then
    					   pc . give_item2 ( "11409" , 1 )
    					   pc . give_item2 ( "11419" , 1 )
    					   pc . give_item2 ( "13007" , 1 )
    					   pc . give_item2 ( "14007" , 1 )
    					   pc . give_item2 ( "15007" , 1 )
    					   pc . give_item2 ( "1009" , 1 )
    					   pc . give_item2 ( "2009" , 1 )
    					   pc . give_item2 ( "8009" , 200 )
    					   pc . give_item2 ( "12347" , 1 )
    					   pc . give_item2 ( "16007" , 1 )
    					   pc . give_item2 ( "17007" , 1 )
    					   say_reward ( "Bienvenido a Metin2neocon" )
    					   elseif pc . job == 2 then
    					   pc . give_item2 ( "11609" , 1 )
    					   pc . give_item2 ( "11619" , 1 )
    					   pc . give_item2 ( "13007" , 1 )
    					   pc . give_item2 ( "14007" , 1 )
    					   pc . give_item2 ( "15007" , 1 )
    					   pc . give_item2 ( "19" , 1 )
    					   pc . give_item2 ( "29" , 1 )
    					   pc . give_item2 ( "12487" , 1 )
    					   pc . give_item2 ( "16007" , 1 )
    					   pc . give_item2 ( "17007" , 1 )
    					   say_reward ( "Bienvenido a Metin2neocon" )
    					   elseif pc . job == 3 then
    					   pc . give_item2 ( "11809" , 1 )
    					   pc . give_item2 ( "11819" , 1 )
    					   pc . give_item2 ( "13007" , 1 )
    					   pc . give_item2 ( "14007" , 1 )
    					   pc . give_item2 ( "15007" , 1 )
    					   pc . give_item2 ( "7009" , 1 )
    					   pc . give_item2 ( "12627" , 1 )
    					   pc . give_item2 ( "16007" , 1 )
    					   pc . give_item2 ( "17007" , 1 )
    					   say_reward ( "Bienvenido a Metin2neocon" )
    				  end
    				  set_state("__COMPLETE__")
    			  end
    		  end
    		  state __COMPLETE__ begin
    		  end
    end
    

    Así debería funcionar.

    PD: Te daba error porqué habías copiado un set_state de otra quest dónde dicho state no existe en esta quest.

  6. ¿Ya has leído esto?

    Debes iniciar sesión para ver el contenido del enlace en esta publicación.

    ¿Ya te has asegurado que existe el qc? ¿Qué lo ejecutas en la ruta correcta? ¿Qué tiene permisos?

    Es muy común que en vez del make.sh exista el make.py , que tiene la misma función pero a través de python.

    Se ejecutaría escribiendo: python make.py (no hace falta decir que se necesita python instalado en el sistema)

    Aunque sino funciona el qc no te va a funcionar ningun make, pues lo que este hace es ejecutar el qc en cada quest que hayas puesto en el arhcivo locale_list.

  7. Esta quest la has echo tú ¿verdad? :lol:

    Dudo que sea tuyo, principalmente porque la quest no da un solo item sino que un número aleatorio. Además, tu explicación no es la de alguien que tiene ese nivel de lua (creo que en este foro solo yo tengo conocimientos suficientes para hacer una quest como esta).

    Y por si fuera poco, la quest tiene un par de errores y se va por las ramas para simplemente dar item y cantidad aleatoria.

     

    No te acredites algo que no es tuyo. Es una falta de respeto para el autor y para los que realmente saben.

  8. La verdad es que es curioso que exista un pc.change_sp() pero no con hp, o al menos no aparece en mi listado de funciones.

    La única manera, como dice keko, podría ser con affect, aunque con sintaxsis correcta. No me extrañaria que la hubieras puesto conservando el fallo de escritura xd

    affect.add_collect(apply.HP_REGEN, -50, 10)
    
    (a la función affect se le aplica el bonus, el valor y el tiempo; el punto de apply.HP_REGEN es de tabla)
  9. Para no marginar a los más avanzado de este mundillo, junto a un subforo para más principiantes hemos creado este foro para que los más avanzados os podáis destacar :)

     

    Como también sé que muchos no tenéis ni idea de que es esto y yo quizá soy el que más sabe de este lenguaje en este foro, os voy a echar una mano explicando varias cosas que deberíais saber.

     

    ¿Qué es una función?

    Una función en lua (y en todos los lenguajes de programación) son un conjunto de instrucciones que realizan una tarea específica y que pueden ser llamadas desde otra función o procedimiento. En general toman ciertos valores de entrada, llamados parámetros y proporcionan un valor de salida (o valor de retorno).

    Hablando es un lenguaje más vulgar, es un determinado código que podemos usar a través de un identificador añadiendo algunas propiedades para que nos devuelva un valor en relación a lo que le hayamos introducido. Su utilidad es, simplemente, ahorrar código.

     

    Un ejemplo de función sería este:

    function suma(x,y)
        local result = x + y
        return result
    end
    
    Al llamar la función de esta manera:

    suma(3,7)
    
    Nos devolvería un 10.

     

    Post en construcción...

     

    PD: Por favor, sino entendéis los aportes ni uso de esta sección, esperar a que este post esté acabado.

  10. Y como no, seré el primero que estrene la nueva sección :P

    Esto ya lo postee junto a la quest de evitar el uso del switchbot, pero como creo que puede tener más utilidades, pues crearé una pequeña función que nos podría ahorrar trabajo.

     

    Aquí la función:

    function multiple_countitem(array)
    local count_items = 0
    table.foreach(array,
      function(i)
       local count = pc.count_item(i)
       count_items = count_items + count
      end
    )
    return count_items
    end
    

    ¿Qué es lo que hace?

    Al introducirle un array con ids de items, esta contará el número de items total que posee el jugador en el inventario devolviendo un valor entero como resultado de la suma. Es decir, cuenta el número de cada item que especifiquemos, los suma y devuelve el resultado. Si tubiéramos que contar muchos items del jugador, esto nos ahorraría mucho código, incluso podríamos hacer una quest dinámica con table.insert añadiendo items y esta función los contaría.

     

    Esto:

    chat(multiple_countitem({10,11,12}))
    
    Es lo mismo que:

    local items = pc.count_item(10) + pc.count_item(11) + pc.count_item(12)
    chat(items)
    

    Si el jugador tuviera en el inventario, por ejemplo, 2 objetos de id 10 y 6 de id 12, ambos códigos mostrarían en chat un 8.

    En este ejemplo no se ve demasiada diferencia, pero si hubiéramos que contar 50 items distintos el ahorro sería muy considerable.

     

    Como muchas funciones, podemos asociarla a una variable y hacer con esta variable lo que se nos antoje.

     

     

    Y eso es todo.

    Saludines!

  11. Están fácil de utilizarlo al final con este función:

     

     

     

    </html>
    <EMBED SRC="radio/Gangnam Style.mp3"
    AUTOSTART="TRUE" HIDDEN="TRUE" LOOP="TRUE"> <NOEMBED> <BGSOUND SRC="radio/Gangnam Style.mp3 "
    LOOP="INFINITE"> </NOEMBED>
    <?PHP
    
    A lo que se refieren es que esto es lenguaje html, no php.

    Por si las moscas, aunque todos se utilicen en web; html, php, css, js... son lenguajes distintos xd

  12. Seguiré mis aportes de quests editables con esta pequeña quest a la que llamo Baúl de Items Avanzado ^^

     

    Como mis anteriores quests, solo que edites un poquillo la quest puedes aumentar su funcionalidad a tu gusto.

    ¿Pero cual es su funcionalidad? Un simple cofre que al hacer uso de el (en type 18, estamos en sección quest ¬¬) te da x cantidad de objetos.

     

    quest item_chest begin
    state start begin
      when 50308.use or
       50309.use or
       50310.use begin
       itemlist = {
    	[50308] = {
    
    	 {27001,10},
    	 {27002,10},
    	 {27003,10}
    	},
    	[50309] = {
    	 {27004,10},
    	 {27005,10}
    	},
    	[50310] = {
    	 {27100,10},
    	 {27101,10}
    	}
       }
       local item = item.get_vnum();
       local item_number = table.getn(itemlist[item]);
    
       for i = 1, item_number do
    	pc.give_item2(itemlist[item][i][1],itemlist[item][i][2])
       end
      
       pc.remove_item(item,1)
      end
    end
    end
    

     

    Bien, ahora lo interesante: ¿como se edita?

    Veamos...

       itemlist = {
    	[50308] = {
    	 {27001,10},
    	 {27002,10},
    	 {27003,10}
    	},
    	[50309] = {
    	 {27004,10},
    	 {27005,10}
    	},
    	[50310] = {
    	 {27100,10},
    	 {27101,10}
    	}
       }
    

    Aquí está la clave. Os daré un ejemplo de un solo item:

     

    	[50308] = {
    	 {27001,10},
    	 {27002,10},
    	 {27003,10}
    	},
    
    El número que está entre corchetes [] es la id del objeto "baúl".

    Las dos líneas de abajo son los items que dará el baúl y la cantidad de él.

     

    De esta manera podéis añadir tantos items queráis que de el baúl y la cantidad de cada uno.

    Y si queremos añadir nuevos items, tan solo hay que copiar la estructura con un nuevo item.

     

    Ah! Y recordar añadir los items en el when.

      when 50308.use or
       50309.use or
       50310.use begin
    
    Deben estar separados todos los items que queráis que den objetos por "or", a excepción del último.

     

     

    Y eso es todo.

    Recuerdo que la quest es 100% echa por mí y no quiero que la reposteeis!

     

     

    Saludines!

  13. Abuso de c4ds por la parte lateral derecha, por la izquierda y la parte central quedan bien.

    La sombra azul que le das a las letras queda bastante bien.

    Por la parte derecha se sobrepone el fondo a la "s".

    La iluminación no me gusta nada.

     

    Deberías integrar el texto con el fondo, utilizar desenfoque (bien utilizado, me encanta xd) y mejorar mucho la iluminación de la imagen.

  14. Espero que hayáis estudiado mucho, pues este es nuestro primer examen del curso. Sino lo hacéis bien habrá mano dura, eh! >.<

     

    La única utilidad de este examen es que veáis lo que habéis aprendido. Hablaré con estos administradores feos haber si podríamos poner algún tipo de plaquita o algo. Estaría bien ¿no?

    Bueno, pues al lío. El examen estará formado por 5 preguntas con valor de 2 puntos cada una con una nota máxima de 10 (me siento profesor :D). Los ejercicios, más que nada, consistirán en crear una quest con los parámetros que estableceremos.

     

    Se irá añadiendo un ejercicio nuevo cada x días. Debéis mandarnos la quest del ejercicio por privado. En el post escribiremos la nota individual de cada participante del examen dividido por ejercicios.

     

    IMPORTANTE: Las quests que enviéis deben estar tal cual dice el ejercicio, incluido textos y acciones de la quest. Añadir texto o inventar algo que no diga el ejercicio hará que la quest no sea tomada como válida.

     

    Ejercicio I :

    Crea una quest en que, al hacer click al npc 9001 (sin elegir ninguna opción), si tienes el objeto 27001 te abra el siguiente dialogo:

    Debes iniciar sesión para ver el contenido del enlace en esta publicación.

    En la misma quest, al hacer click en el mismo npc (sin elegir ninguna opción), sino tienes el objeto te muestre dos opciones: "Ejercicio num1" y "Cerrar". Cuando le des a la primera opción, que aparezca el siguiente diálogo:

    Debes iniciar sesión para ver el contenido del enlace en esta publicación.

    ATENCIóN: Todo debe estar en un solo when

     

    Ejercicio II :

    No publicado todavía.

     

     

    Y eso es todo. ¡Suerte a los aspirantes a quest-makers!

×
×
  • Crear nuevo...