Jump to content

caanmasu

Members
  • Content Count

    48
  • Joined

  • Last visited

  • Days Won

    5

caanmasu last won the day on June 1

caanmasu had the most liked content!

2 Followers

About caanmasu

  • Rank
    Novato

Recent Profile Visitors

546 profile views
  1. Hola a todos! Traje una información útil sobre las quest que resuelve varios problemas pero sobretodo uno: ¿Cómo hago para que no se me reinicie el contador de tiempo de las misiones? Resulta que, por ejemplo, haces una misión de 30 minutos y te quedan 5 minutos, cambias pj y vuelves a entrar, ahora vuelve el contador a 30 minutos. Claramente es un bug. Eso ocurre porque en el state actual, generalmente tienes tres disparadores (when) que son: letter: estos se inician cada vez que el personaje se loguea. Su tarea es mostrar el pergamino de la misión flotante en la parte izquierda. button: estos se inician cuando se le da clic al botón de la misión que está en la interfaz donde aparece carácter, habilidades, emociones, misiones. info: estos se inician cuando se le da clic al pergamino flotante de la izquierda. El error está cuando en alguno de esos disparadores asignas el timer o alguna otra variable inicial. Así que cuando el pj cambia de mapa o se vuelve a conectar, o cuando le das clic al pergamino, el contador (variable) se inicializa de nuevo en el número que pusiste. Así que cuál es la solución? Utilizar el disparador enter. Este disparador ya viene por defecto en el servidor, así que no hay que añadir nada con C++. La función de enter es ejecutarse una sola vez en el state. Es decir, si en un state pones when enter begin, apenas tu pj llegue a ese state, se ejecutará y no se volverá a ejecutar de nuevo. quest prueba begin state start begin when enter begin chat("Esto solo aparecerá una vez") end end end Si esta quest se ejecuta, apenas el pj se loguee, aparecerá el mensaje. Si te vuelves a conectar no aparecerá. La única manera de que vuelva a aparecer el mensaje sería reiniciando el state con set_state(start) Esto es útil para inicializar variables para las misiones. Así que si pones el timer en el enter, así cambien de pj, no se volverá a iniciar el reloj. No cometas el error de poner un timer en el state start porque el tiempo empezará a correr desde ahí, y la idea es que corra el tiempo cuando el personaje acepta la misión. Cuando el pj le dice al NPC "Sí, acepto el reto ahora", enviarlo a un nuevo state donde se ponga el timer, no en ese mismo state. Ocurre lo mismo con cualquier otra variable, no solo timers. Si pones en un letter, button o info, por ejemplo, pc.setqf("cantidad_monstruos", 100) es un error porque cada vez que te loguees va a volver a 100 ese qf. Bueno, en ese caso declara esa variable en el state start y santo remedio. En el caso de los timers ya es más complejo porque no puedes "guardar" un timer en los arreglos iniciales (o en donde guardes tus variables iniciales). Es por eso que me enfoqué en los timers en este post. Y eso es todo amigos. Éxitos!
  2. Hola y bienvenido Me sentí identificado con lo de las quest. A mí también me encantan y eso me llevó a ciertos niveles que no creí llegar. Las cosas se fueron dando. Empecé con un "Hola mundo" al estilo Metin2 quest prueba begin state start begin when 20095.chat."Hola" begin say("Hola amigo") end end end Para hacer eso, tuve muchos problemas. Es normal. No sabía qué significaba "state", me perdía con los "end" y los "begin". Tuve muchos errores de sintaxis. Tuve errores que me costaban días en descubrirlos o volvía a hacer la quest. Muchas cosas no me salían como esperaba. Habían quest que yo compilaba y salían defectuosas en el object. Hice demasiadas pruebas para ver por qué pasaban las cosas. La práctica hace al maestro. Fui ensayando pero mi truco sabio que aplicaba todo el tiempo mientras era novato era hacer una línea y compilar. Si funcionó, entonces hago otra línea, compilo y pruebo. Y así. No te recomiendo hacer todo el código y luego compilarlo. Siempre has una pequeña estructura, compila y prueba. Con la práctica te vas volviendo un crack y terminas haciendo quest sin errores. Para aprender adquirí conocimientos de: - Lua, buscando en internet sobre ese lenguaje (sintaxis) - Descargando muchas carpetas quest de muchos files y aprendiendo la forma de programar de todos ellos. - Foros. Por ejemplo yo me puse a ver todos los post que tengan que ver con quest. Y los post donde pedían quest, las hice todas. Aprendes más cuando haces quest a petición. - quest_function, ahí es donde pones a prueba tu creatividad. Tantas funciones combines, creas cosas que nunca nadie ha hecho. En internet hay unas páginas donde explican cada función sobre cómo se utiliza, qué parámetros reciben, etc. - questlib.lua, de ahí sacas otras funciones que son genéricas. En vez de hacer una función igual para cada quest, haces una función y la metes en questlib, luego esa función simplemente la llamas en las quest que quieras. Hay muchas cosas que vas a ir aprendiendo por el camino. Claro, si quieres meterte de lleno a las quest. Si quieres sacar tu máximo potencial en las quest, te recomiendo que revises mi perfil y mires las quest que he publicado. Yo he tenido que dejar todo esto, no volveré a hacer quest ni nada relacionado con el Mt2. Ánimo pues que esto es fascinante
  3. Por casualidad entré a este post y me topé con esto. Encontré que debía compartir algo importante que aprendí luego de tanto dolor de cabeza Resulta y pasa hay un error al poner un caracter especial al final de un texto de la interfaz de quest. Es decir, no puedes poner, por ejemplo: say("reclamará") ni puedes poner otro tipo de caracteres especiales. Las tildes ni símbolos. Cuando tienes un say así, el compilador va a interpretar hasta esa línea y por supuesto que no te dará error pero tampoco te lo compilará, simplemente quedará igual. Solución: Si deseas poner caracteres especiales, simplemente pon espacio al final, así: say("reclamará ") Ves la diferencia? Lo mismo pasa con el select() y otras funciones de mostrar texto. Sabes lo que yo pienso? es que pusiste tal vez algo así como: say("El Evento de San Valentín empezó") y esa línea ya presenta un error. Puedes poner signos de admiración e interrogación y no presentará error ya que no son caracteres especiales. say("El Evento de San Valentín empezó!") Esto es correcto. Esto me tomó meses descubrirlo. Un dolor de cabeza menos. Un saludo amigos.
  4. Ok. Crearé mi propio anillo teleport y lo posteo. Ahora no puedo hacerlo, estoy en época de exámenes cuando lo suba te aviso
  5. Hola! En la línea local job= {"Guererro","Ninja","Sura","Schaman"})[pc.get_job()+1] encontré un error en el paréntesis que está después del arreglo. La corrección sería la siguiente (y espero que funcione porque no puedo probar) local job= {"Guerrero","Ninja","Sura","Chamán"} notice_all (pc.get_name().." es un nuevo "..job[pc.get_job()+1].." y comienza su aventura en Tuserver")
  6. Hola Esta quest es para mi amigo Clinodina Solo aplica para un solo monstruo Sé que hay varias así pero lo diferente de esta es que es muy fácil de configurar Saludos --[[ QUEST Quest creada por Camilo Martínez Misión de caza. Se acepta a partir de x nivel. Al matar x cantidad de x monstruo dará x cantidad de x objeto. Cada x son las variables que puedes modificar sin necesidad de modificar la quest. Si quieres modificar los says, recuerda no dejar un caracter especial al final de la línea o se bugea. La misión solo se puede realizar una vez por personaje. Nota: es posible que algunos mobs no se identifiquen con npc.get_race(), en ese caso poner id_mob.kill en el when Discord: Camilo#0869 --]] quest caza1 begin state start begin function info() return{ ["level"] = 50, ["id_mob"] = 101, ["count_mob"] = 500, ["id_item_reward"] = 19, ["item_reward"] = 1, } end when login with pc.get_level() >= caza1.info().level begin set_state(run) end end state run begin when letter begin send_letter("Masacre de "..mob_name(caza1.info().id_mob)) end when button or info begin local s = caza1.info() say_title("Masacre de "..mob_name(s.id_mob)) say("[ENTER]Mata "..s.count_mob.." "..mob_name(s.id_mob)) say_reward("[ENTER]Por el momento llevas "..pc.getqf("kills")) q.set_counter("Restantes", s.count_mob-pc.getqf("kills")) end when kill with npc.get_race() == caza1.info().id_mob begin local s = caza1.info() local count = pc.getqf("kills") + 1 if count < s.count_mob then pc.setqf("kills", count) q.set_counter("Restantes", s.count_mob - count) else q.set_counter("Restantes", s.count_mob - count) say_title("Misión terminada") say_reward("[ENTER]Recibes "..item_name(s.id_item_reward).." x"..s.item_reward) say_item_vnum(s.id_item_reward) pc.give_item2(s.id_item_reward, s.item_reward) set_state (__COMPLETE__) end end end state __COMPLETE__ begin end end
  7. no amigo pero igual puedes tomarlo de inventorywindow.py del locale
  8. Hola a todos de nuevo Hoy les traigo una nueva quest creada por mí. Me gusta crear cosas nuevas, originales, y de gran calidad. Esta vez es una herramienta administrativa que será muy útil para los admins, GMs… Lean todo, incluso el encabezado de la quest, ahí están las especificaciones con sus vulnerabilidades. A mí me funciona, espero que también te funcione Vídio random: buscar_id_item.quest from Camilo Martinez on Vimeo. quest_functions get_items_without_plus_zero questlib.lua function get_items_without_plus_zero(items) for i = 1, table.getn(items) do if string.find(items[i], "+0") then local str = string.gsub(items[i], "+0", "") items[i] = str end end return items end buscar_id_item.quest --[[ QUEST Quest creada por Camilo Martínez Consiste en obtener el ID de un objeto a partir del nombre en una búsqueda. Especificaciones: 1. Solo a los GMs les aparecerá el botón "Buscar ID ítem" en las misiones. 2. Al darle clic al botón, aparecerá un cuadro con un input() donde se digitará una palabra para buscar el objeto. Luego aparecerá una lista de objetos y cuando selecciones uno, te mostrará en letras rojas el nombre y el id. 3. Si el objeto es +0, +1, +2... se mostrará el nombre solo y el id de ese objeto +0. Notas: 2. Al digitar la palabra, omite el nivel del ítem (+0, +1...) No sensible a las tildes ni mayúsculas/minúsculas, así que escribe con confianza :) 3. Hago una consulta en la base de datos de la tabla player.item_proto donde recojo los ítems que contengan la palabra y además no terminen en un número del 1 al 9. Tomo el número 0 al final para el conjunto de equipos (+0, +1, +2...) y así mostrar solo uno para mejorar la búsqueda y evitar muchas páginas. (Si tienes un objeto llamado por ejemplo Llave1 o Llave2 no aparecerá) 4. Restringido a 47 botones (8 botones por página y en la última página 7 botones). Más botones en la búsqueda bugea el pj. 6. Agregar la función: get_items_without_plus_zero En el questlib.lua y quest_functions 7. Reportar cualquier error Que aprovechen la quest :) Discord: Camilo#0869 --]] quest buscar_id_item begin state start begin when letter with pc.is_gm() begin send_letter("Buscar ID ítem") end when button or info begin say_title("Buscar ID ítem") say("[ENTER]Escribe una palabra que tenga el nombre") say("del ítem. No escribas +1, +2, +3...") local nombre_item = input() if nombre_item == "" then return end local items = mysql_query("SELECT vnum, locale_name FROM player.item_proto WHERE (UPPER(CONVERT(locale_name USING latin1)) LIKE '%"..nombre_item.."%' and locale_name NOT REGEXP '.*[1-9]+' );") local tam = table.getn(items) if tam == 0 then syschat("No hay coincidencias") end local items, id = items.locale_name, items.vnum items = get_items_without_plus_zero(items) table.insert(items, "Cerrar") if tam > 47 then syschat("Sé más específico con tu búsqueda") return end local sel = select_table(items) if sel != tam+1 then say_size(350, 250) say_title("Resultados:[ENTER][ENTER]") say_item_vnum(id[sel]) say_reward(items[sel]..": "..id[sel]) syschat(items[sel]..": "..id[sel]) end end end end buscar_id_item.rar
  9. Editado, leer lo nuevo y actualizar!
  10. Hola amigos Esta quest consiste en que el líder del grupo al pulsar sobre un objeto (type 18) mostrará/ocultará la ubicación de los miembros del grupo (sin incluirlo a él) en el mapa. Parecido a cuando tenemos misión con un NPC y aparece una flecha arriba y también como una burbuja en el mapa. A medida que los miembros del grupo se mueven, también se moverá el "target", o sea, la "burbuja". Es decir, la ubicación es en tiempo real. No traigo vídeo porque no lo puedo testear en mi server pero sí funciona. Igualmente si no llegase a funcionar me lo escriben por acá. [Hidden Content] (Dejo código en post, código en web y archivo adjunto) --[[ QUEST Quest creada por Camilo Martínez Consiste en que el líder del grupo pueda ver la ubicación en tiempo real de los integrantes. Especificaciones: 1. El líder del grupo al darle click sobre el objeto, le aparecerá la ubicación de cada integrante en el mapa (en tiempo real) 2. Se notificará en el chat grupal cuando se active/desactive el rastreador 3. Cuando se le dé click de nuevo al objeto, se borrarán las ubicaciones. Notas: 1. Si un miembro no está en el mapa simplemente no se muestra su ubicación. 2. Al apuntar el cursor en cualquiera de los integrantes mostrados en el mapa, se verá su nombre. 3. Los targets se eliminan cuando se cierra la sesión 4. Basado en los targets de las misiones oficiales 5. Reportar cualquier error Y disfrutar de la quest! Discord: Camilo#0869 --]] quest ver_miembros begin state start begin function eliminar_targets() pc.setqf("block_target", 0) for i = 1, 8 do target.delete("__MEMBER"..i.."__") end end when 40001.use begin if party.is_leader() then if pc.getqf("block_target") == 0 then pc.setqf("block_target", 1) local pids = {party.get_member_pids()} local partyMembers = table.getn(pids) for i = 1, partyMembers do q.begin_other_pc_block(pids[i]) if pids[i] != pc.get_vid() then local name, pid = pc.get_name(), pids[i] end q.end_other_pc_block() target.vid("__MEMBER"..i.."__", pid, name) end party.chat("<Grupo> El líder está siguiendo las ubicaciones de los integrantes") else party.chat("<Grupo> El líder dejó de seguir las ubicaciones de los integrantes") ver_miembros.eliminar_targets() end else ver_miembros.eliminar_targets() syschat("No eres el líder de un grupo") end end when logout with pc.getqf("block_target") == 1 begin pc.setqf("block_target", 0) end end end ver_miembros.quest
  11. Corregí un pequeño error. Ya compila xD! Actualicen y arranquen!
  12. Hola mi gente! Hoy les traigo una quest elaborada 100% por mí desde la concepción de la idea xD Dale Me encorazona Vídeo demostrativo: go_all_map from Camilo Martinez on Vimeo. Descripción en el archivo de la quest Dale Me encorazona si te gustó EDITADO: Y agreguen la quest, las funciones en el questlib y por último agregar las funciones xx_coords_town_folder_map y list_folder_maps en el quest_functions (Revisa si tu objeto es type 18) Quest go_all_map.quest --[[ QUEST METIN2 Quest creada por Camilo Martínez Es un anillo teleport donde se puede acceder a la totalidad de los mapas del juego. Especificaciones: 1. Al darle clic al objeto, aparecerán botones de nombres página #, donde cada página muestra 43 mapas y la última los restantes mapas. 2. Al seleccionar una de las páginas y luego uno de los mapas, transportará al personaje a ese mapa en las coordenadas centrales Notas: 1. Recomendable para solo uso GM, esto es administrativo. Pero igual pueden usarlo a su antojo, solo es una recomendación :) 2. La cantidad máxima de botones por defecto puse 44 porque se bugeaba a los 45+ 3. No olvidar cambiar el país (locale/xx) por el de tu servidor 4. Se enlistan todas las líneas del index de la carpeta map. No debe haber ninguna línea vacía en ese archivo. Se toma el index y el nombre del mapa (nombre de la carpeta) por aparte. Luego con el nombre del mapa se va a la ruta del mapa y en Town.txt tomará la primera coordenada. Posteriormente se hace un warp_local donde se le envía el id del mapa y las coordenadas del Town*100 5. Si los separadores son espacio y tabulador, se tomará sin problema los datos de los archivos. Si hay varios espacios simulando un tabulador, no se tomará en cuenta. Es decir: Si tienes en Town.txt las coordenadas 433 542, habrá un error porque tienes dos espacios. Lo correcto es que haya un solo espacio o un solo tabulador. 6. Si no te transporta es porque el mapa puede estar mal implementado 7. No olvides poner la parte del questlib.lua 8. Tampoco olvides poner las funciones en quest_functions xx_coords_town_folder_map list_folder_maps 7. Cualquier error reportar 8. Que lo disfruten :) y como siempre, mi Discord: Camilo#0869 --]] quest go_all_map begin state start begin function info() return{ ["max_button"] = 44, ["country"] = "hungary", } end when 40004.use with pc.is_gm() begin local s = go_all_map.info().max_button local t = go_all_map.info().country local nombres_mapas, index_mapas = list_folder_maps(t) local cant_pags = math.ceil(table.getn(nombres_mapas)/(s-1)) local tabla_madre, tabla_select = {}, {} local tabla_madre_index = {}, {} local aux = 1 for i=1, cant_pags do table.insert(tabla_madre, {}) table.insert(tabla_madre_index, {}) table.insert(tabla_select, "Página "..i) for j=1, s-1 do tabla_madre[i][j] = nombres_mapas[aux] tabla_madre_index[i][j] = index_mapas[aux] aux = aux + 1 end table.insert(tabla_madre[i], "Cerrar") end table.insert(tabla_select, "Cerrar") local sel1 = select_table(tabla_select) if sel1 != table.getn(tabla_select) then local sel = select_table(tabla_madre[sel1]) if sel != table.getn(tabla_madre[sel1]) then local x, y = xx_coords_town_folder_map(t, tabla_madre[sel1][sel]) pc.warp_local(tabla_madre_index[sel1][sel], x*100, y*100) end end end end end Parte del questlib.lua function xx_coords_town_folder_map(country, map) local det, tab, spc = io.open('locale/'..country..'/map/'..map..'/Town.txt'), ' ', ' ' local x, y = 0, 0 for line in det:lines() do if table.getn(split(line, tab)) == 2 then x = split(line, tab)[1] y = split(line, tab)[2] return x, y elseif table.getn(split(line, spc)) == 2 then x = split(line, spc)[1] y = split(line, spc)[2] return x, y else return "ERROR" end end end function list_folder_maps(country) local map, index = {}, {} local det, tab, spc = io.open('locale/'..country..'/map/index'), ' ', ' ' for line in det:lines() do if table.getn(split(line, spc)) == 1 then table.insert(map, split(line,tab)[2]) table.insert(index, split(line, tab)[1]) else table.insert(map, split(line,spc)[2]) table.insert(index, split(line, spc)[1]) end end return map, index end go_all_map.rar
  13. El lenguaje Lua no tiene la propiedad de identación, o sea, que ignora si está tabulada o no, por lo que puedes usarla así pero tendrías que arreglarle partes donde hay palabras pegadas como "endend" Te recomiendo siempre identar todo el código para que puedas editarlo cómodamente si prefieres. Toma, te regalo mi quest. Esta quest es configurable, es decir, puedes agregar las perlas que quieras con su respectivo valor en trozos de piedra. Puedes agregar perlas doradas, moradas, plateadas, etc. tan solo agregándolas en las listas. Como siempre, haré una descripción de cómo funciona: si el jugador tiene el mínimo de trozos de piedra para comprar la perla de menos valor, le mostrará las perlas que puede cambiar y les aparecerá el nombre con la cantidad de trozos a cambiar. En este caso: Si tienes 100 trozos te aparecerá: Perla Blanca (50 trozos) Perla Azul (100 trozos) Si tienes 200 trozos te aparecerá: Perla Blanca (50 trozos) Perla Azul (100 trozos) Perla Roja (200 trozos) Si tienes 88 trozos de piedra te aparecerá: Perla Blanca (50 trozos) Y ya, el resto solo elimina los trozos correspondientes y te da la perla correspondiente, una sola. (Nota: es posible que al copiar este código aparezcan signos de interrogación al final de alguna línea, solo quítalos) --Camilo Martínez --Discord: Camilo#0869 quest cambiar_trozos_piedra begin state start begin function info() return { ["item"] = 27990, ["perlas"] = {27992, 27993, 27994}, ["valor"] = {50, 100, 200}, } end when 9009.chat."Cambiar Trozos de Piedra" begin local s = cambiar_trozos_piedra.info() local tabla_menu, tabla_perlas, tabla_valor = {}, {}, {} local cantidad = pc.count_item(s.item) if cantidad < s.valor[1] then setskin(0) syschat("No tienes suficientes "..item_name(s.item)) return end for i = 1, table.getn(s.perlas) do local perlas_desc = table.getn(s.perlas)-i+1 if cantidad/s.valor[perlas_desc] >= 1 then for j = 1, perlas_desc do tabla_perlas[j] = s.perlas[j] tabla_valor[j] = s.valor[j] tabla_menu[j] = item_name(s.perlas[j]).." ("..s.valor[j].." trozos)" end break end end table.insert(tabla_menu, "Cerrar") say_title(mob_name(npc.get_race())) local sel = select_table(tabla_menu) if sel == table.getn(tabla_menu) then return end pc.remove_item(s.item, tabla_valor[sel]) pc.give_item2(tabla_perlas[sel]) syschat("Cambio realizado") end end end
×
×
  • Create New...