Jump to content

Search the Community

Showing results for tags 'quest'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Metin2 Zone
    • Community
    • Presentations and farewells
  • Private Servers
    • Server Presentations
    • Project showcase
  • General
    • General Discussions
    • Partnerships and Cooperation
    • Services and trading
    • Helps and questions
    • Reviews and advice
    • Offtopic
  • Technical
    • Programming
    • Metin2 Server Modding
    • Web Development
    • Security
    • Operating Systems
    • Computing
  • Art
    • Design and graphic section
    • Gallery of images and videos
    • 3D Modelling
    • Mapping
  • Downloads
    • Client and Server files
    • 3D Models
    • Metin2 Images
    • Maps
    • Translation
  • Archive
    • Offline Servers
    • Temas Links Caidos

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Email


Sitio web


Jabber


Skype


Discord


Location


Intereses

Found 77 results

  1. ¡Hola a todos de nuevo! Este será un tutorial sobre los timers en una dung. Ojo, solo en las dungs. Tutorial nivel intermedio Existen dos tipos de timers: Timers globales: Estos timers son a nivel de la dung. Tenemos: server_timer() server_loop_timer() Timers personales: Estos timers son a nivel de personaje. Tenemos: timer() loop_timer() server_timer() server_timer() es generalmente utilizado para tiempos globales en las dungs. Un tiempo global quiero decir, por ejemplo, cuando entras a la dung y te dice: "Te quedan 45 minutos para matar al jefe". Y es fácil de identificarlo porque ese tiempo es el mismo para todos. server_timer() es una función y también es un disparador (when) que se activa cuando pasa el tiempo determinado. Pero no siempre se usa para poner un anuncio de tiempo, sino que hay muchas funciones que se pueden usar. Y ojo a lo siguiente que es donde más se cometen errores: Al ser una función global, no puedes poner funciones personales Funciones que NO puedes poner en un server_timer(): - say(), chat(), syschat(), notice() o derivadas. - pc.mount(), y cualquiera que tenga pc... ya que "pc" es "personal character", no es global - game.drop_item() porque el objeto cae bajo el pj Funciones que puedes usar dentro de un server_timer(): - d.notice(), notice_all(), notice_multiline(), - clear_server_timer() - game.set_event_flag(), game.get_event_flag() - server_loop_timer() - Todas las que sean de dung, o sea, las que empiecen por d., ejemplo d.count_monster() - Todas las que no tengan que ver con afectar a algún carácter, ejemplo tonumber(), table.getn(), string.len(), etc. Estructura de un server_timer() Para crearlo: En el nombre, es el mismo nombre que le vas a poner al when. En tiempo, procura ponerlo en esta estructura, 60*60*2 (2 horas), por ejemplo. Si el server_timer no está dentro de otro, se pone en el 3° parámetro el index del mapa. Yo pongo d.get_map_index() pero es igual que con pc.get_map_index(). Esto mismo se aplica para la función clear_server_timer(). server_timer("nombre", tiempo, d.get_map_index()) Si el server_timer está dentro de otro, se pone get_server_timer_arg(), así: server_timer("nombre", tiempo, get_server_timer_arg()) Cuerpo de un server_timer(): when nombre.server_timer begin if d.select(get_server_timer_arg()) then -- aquí pones tu contenido con las funciones válidas end end En nombre, puse el mismo de cuando lo creé. Luego, en vez de poner use, chat, y esas cosas, puse server_timer. Sí o sí para dungs hay que poner ese bloque if así tal cual está. Esto es para identificar la dung. Pongo los dos casos a continuación: when login begin server_timer("nombre", 60, d.get_map_index()) --cuando pongo un server_timer() en un when normal end when nombre.server_timer begin if d.select(get_server_timer_arg()) then server_timer("nombre2", 30, get_server_timer_arg()) --cuando pongo un server_timer() en un when server_timer end end Parar un server_timer: En el caso de que esté en un when distinto a un server_timer: clear_server_timer("nombre", d.get_map_index()) En el caso de que esté dentro de un when server_timer: clear_server_timer("nombre", get_server_timer_arg()) Cuándo se detiene un server_timer? - Cuando necesitas parar un server_loop_timer - Cuando necesites detenerlo y crear otro con diferente tiempo. Como en el caso de Catacumbas cuando destruyes a Caronte, te crea un nuevo tiempo para matar a Azrael. - Cuando terminas la dung y antes de transportar a todos, limpias todos los server_timer. Cómo crear un server_timer imitando un ciclo: when login begin server_timer("nombre", 60, d.get_map_index()) end when nombre.server_timer begin if d.select(get_server_timer_arg()) then server_timer("nombre2", 30, get_server_timer_arg()) end end when nombre2.server_timer begin if d.select(get_server_timer_arg()) then server_timer("nombre", 1, get_server_timer_arg()) --llamo al server_timer anterior en 30 seg, y éste llamará de nuevo al server_timer y así... end end Esta estructura sirve como ciclo, en este caso para que cada 30 segundos haga algo. La siguiente estructura es para anunciar los tiempos de duración de la dung: when login begin server_timer("nombre", 10, d.get_map_index()) --en 10 segundos empezará a avisar que faltan 60 min end when nombre.server_timer begin if d.select(get_server_timer_arg()) then d.notice("Quedan 60 minutos") server_timer("nombre2", 60*30, get_server_timer_arg()) --en 30 min avisará que quedan 30 min end end when nombre2.server_timer begin if d.select(get_server_timer_arg()) then d.notice("Quedan 30 minutos") server_timer("nombre3", 60*20, get_server_timer_arg()) --en 20 min avisará que quedan 10 min end end when nombre3.server_timer begin if d.select(get_server_timer_arg()) then d.notice("Quedan 10 minutos") server_timer("nombre4", 60*5, get_server_timer_arg()) --en 5 min avisará que quedan 5 min end end when nombre4.server_timer begin if d.select(get_server_timer_arg()) then d.notice("Quedan 5 minutos") server_timer("nombre5", 60*5, get_server_timer_arg()) --en 5 min transportará a todos end end when nombre5.server_timer begin if d.select(get_server_timer_arg()) then d.exit_all() end end server_loop_timer() server_loop_timer() es igual al server_timer() pero cíclico. Loop significa ciclo, repeticiones cada cierto tiempo. Mientras que server_timer() hace algo una vez en x tiempo, server_loop_timer() hace algo cada x tiempo (en segundos) hasta que lo detengas forzosamente. Las funciones que se utilizan son las mismas que en el server_timer(). Estructura de un server_loop_timer() Para crearlo: Se crea exactamente igual que el server_timer(), solo cambia el tiempo. Si pones 5, cada 5 segundos hará lo que pongas dentro del when. Cuerpo de un server_loop_timer(): La única diferencia es que el when es el mismo. Veamos: when login begin server_loop_timer("nombre", 5, d.get_map_index()) end when nombre.server_timer begin --aquí se pone server_timer if d.select(get_server_timer_arg()) then -- aquí pones lo que va a hacer cada 5 seg end end Los server_loop_timer se detienen igual que un server_timer. Combinar server_loop_timer con server_timer: El tiempo de un server_loop_timer debe ser mayor al de un server_timer anidado. Anidado significa que está dentro, o sea, el server_timer dentro del server_loop_timer. Veamos qué sucede si NO cumplo con esta regla: when login begin server_loop_timer("nombre", 5, d.get_map_index()) end when nombre.server_timer begin if d.select(get_server_timer_arg()) then server_timer("nombre2", 10, get_server_timer_arg()) end end El ciclo cada 5 segundos va a ejecutar un ciclo de 10 segundos. Entra al ciclo, ejecuta el server_timer(), y en el segundo 5 vuelve a entrar al ciclo, impidiéndole cumplir sus 10 segundos para entrar al server_timer. Así que la regla es no poner un server_timer() con un tiempo mayor al del server_loop_timer(). Pero toda regla tiene sus excepciones, así que vamos con esta: Si el ciclo tiene una condición que permite que el server_timer() cumpla con su tiempo, entonces sí es válido. Como en el siguiente ejemplo: when login begin server_loop_timer("nombre", 5, d.get_map_index()) end when nombre.server_timer begin if d.select(get_server_timer_arg()) then if d.getf("bloqueo") == 0 then server_timer("nombre2", 10, get_server_timer_arg()) d.setf("bloqueo", 1) end end end Puse un d.getf() que cuando entra y ejecuta el server_timer(), solo lo hace una vez porque le cambié el valor al d.getf() al final. Es claro que el código así como lo tenemos no va a funcionar, tendríamos que hacer que el personaje logre cambiar de nuevo el valor del d.getf("bloqueo") a 0 para que se ejecute de nuevo el ciclo (si es lo que buscamos). Digamos que, cuando mate al jefe, ponga d.setf("bloqueo", 0) y se ejecutará de nuevo el ciclo. timer() Los timer() se usan cuando necesitas ejecutar funciones a nivel de personaje. La ventaja es que son más sencillas de usar, incluso puedes usar cualquier función, hasta las globales. Crear un timer: timer("nombre", tiempo) Cuerpo de un timer: when login begin timer("nombre", 10) end when nombre.timer begin -- end En el when solo pones nombre.timer Ya no hay que poner el if Detener un timer: cleartimer("nombre") Prácticamente no se usa en las dungs porque generalmente cualquier acción en las dungs afectan a todos los personajes que están ahí. Por lo tanto, si usas un timer() en una dung, y el personaje se desconecta antes de pase el tiempo, no se ejecutará el when timer. El timer() se muere cuando lo detengas o cuando el personaje se desconecta. A diferencia del server_timer o server_loop_timer que se sigue ejecutando sin importar si los personajes se desconectaron. Un ejemplo crítico para esto, es que mates un jefe y te ponga un timer() donde los lleve a todos a una sala, pues si el pj se desconecta antes de que ocurra el timer, nadie se transportará a la sala. Los timer() se pueden anidar en los server_timer() y server_loop_timer(). Así que la regla es, si las funciones son a nivel personaje debes usar timer(), si son a nivel global (a nivel dung, de hecho) se usan los server_timer() y server_loop_timer(). Un posible uso es que cuando mates a un jefe, en un determinado tiempo te de algo (a ti solo) pero no le veo mucho sentido. loop_timer() Llegamos al nivel más complejo del tutorial. Un loop_timer() es como un server_loop_timer() pero a nivel personaje. Crear un loop_timer: loop_timer("nombre", tiempo) Cuerpo de un loop_timer: when login begin loop_timer("nombre", 5) end when nombre.timer begin -- end Detener un loop_timer: Se detiene igual que un timer. Un loop_timer famoso es el de cuando el personaje se muere y haga algo when login begin loop_timer("muerto", 5) end when muerto.timer begin if pc.get_hp() <= 0 then chat("Se murióooo (8)") end end El tiempo del loop_timer() debe ser menor al tiempo en que hace respawn el pj o sino no aparece cuando le de al botón de respawn cuando ya pueda aparecer. Cuando el pj muere, en pocos segundos aparecerá en el chat ese mensaje, y si sigue muerto, cada 5 segundos seguirá apareciendo. Pero bueno, en una dung no le veo mucho sentido usar un loop_timer() independiente porque vuelvo y repito, las funciones de las dung afectan a todos los personajes salvo la creatividad que quieras darle que necesite de algo más exclusivo... Combinar loop_timer() con server_timer() y server_loop_timer(): El objetivo es usar funciones personales con funciones globales, así hacemos más diversa la dung. El problema está en que es no es tan sencillo combinarlas y menos cuando vamos a meter un loop_timer(), así que vamos a ver lo que yo llamo semáforos, que básicamente es usar los d.getf() y d.setf() como banderas. Vamos a hacer que el personaje cuando muera (loop_timer() porque la muerte es personal y además debe evaluar cada ciertos segundos porque no es when) lo lleve a city: when login begin loop_timer("muerto", 3) end when muerto.timer begin if pc.get_hp() <= 0 then timer("enviar_a_city", 1) end end when enviar_a_city.timer begin warp_to_village() end Puse un timer de 1 segundo para que al morir no transporte de una vez (se ve horrible). Ahora haré que cuando no hayan monstruos, invoque otros monstruos más después de 60 segundos: when login begin d.spawn_mob(blablabla) --aquí invoco los primeros mobs loop_timer("muerto", 3) server_loop_timer("timer_inv", 3, d.get_map_index()) --ciclo cada 3 segundos para evaluar si hay monstruos end when muerto.timer begin if pc.get_hp() <= 0 then timer("enviar_a_city", 1) end end when enviar_a_city.timer begin warp_to_village() end when timer_inv.server_timer begin if d.select(get_server_timer_arg()) then if d.count_monster() <= 0 and d.getf("bloqueo") == 0 then --si no hay monstruos, entonces... y de una vez pongo mi bloqueo que expliqué antes server_timer("invocar", 60, get_server_timer_arg()) --en 60 seg invocará de nuevo d.setf("bloqueo", 1) --fin bloqueo end end end when invocar.server_timer begin d.spawn_mob(blablabla) --aquí invoca de nuevo d.setf("bloqueo", 0) --pongo bloqueo en 0 para que pueda volver a invocar por el server_loop_timer end Ahora buscaré la manera de hacer que en cada oleada se monten automáticamente los personajes en alguna montura. Aquí aplicaré una función personal (pc.mount()) pero a todos. when login begin d.spawn_mob(blablabla) loop_timer("muerto", 3) server_loop_timer("timer_inv", 3, d.get_map_index()) end when muerto.timer begin if d.getf("montar_todos") == 1 then --esta es la bandera que les decía d.setf("montar_todos", 0) --toca bloquearla para que no se repita de nuevo hasta que se lance de nuevo la oleada quest.montarTodos() --aquí va a la function... end if pc.get_hp() <= 0 then timer("enviar_a_city", 1) end end when enviar_a_city.timer begin warp_to_village() end when timer_inv.server_timer begin if d.select(get_server_timer_arg()) then if d.count_monster() <= 0 and d.getf("bloqueo") == 0 then server_timer("invocar", 60, get_server_timer_arg()) d.setf("bloqueo", 1) end end end when invocar.server_timer begin d.spawn_mob(blablabla) o d.setf("bloqueo", 0) d.setf("montar_todos", 1) --pongo en 1 esta bandera para que arriba en el loop_timer entre a la condición que hace que todos monten end function montarTodos() -- aquí se usa el partyMembers y todo eso de las dungs... pc.mount() --lo que quiero que entiendan acá es que ese pc.mount() se aplicará en todos los pjs con q.begin_other_pc_block() y q.end_other_pc_block() end El resumen de esta parte es que utilicé los d.setf y d.getf para poder activar y desactivar las entradas a ciertas condiciones de los server_timer o server_loop_timer. Así que si necesitas usar una función personal en un server_loop_timer debes activar una bandera, en el loop_timer poner la condición, desactivar la bandera y luego hacer las funciones. Notas: - Se puede usar funciones dungeon (las que empiezan por d.) dentro de cualquier when (timers globales, personales, use, chat, todo eso) - Las líneas de código se ejecutan inmediatamente. No hay que esperar x tiempo del timer para que se ejecute las siguientes líneas. - El /rel q, mata todos los timers del mapa. Así que al testear debes cambiar de pj. Y bueno, esto solo se entiende practicando xD Si no entendiste ni madres, estás bien. Probablemente en dos semanas no entenderé lo que puse acá Esto lo apliqué en mi quest de "Arena Mob" que es una mazmorra infinita. Y al agregarle complejidad a la mazmo, había funciones que sí o sí debía poner en el server_loop_timer algunas funciones que eran personales, como pc.give_item2(), pues al pasar de cada ciertas oleadas tenía que dar unos premios y no podía usar pc.give_item2() en el server_loop_timer, así que me tocó en el loop_timer. Tampoco quería que reclamaran los premios dándole clic al NPC, yo quería que se dieran automáticamente y ahí está la complejidad. Arena Mob Consiste en una mazmorra de gremio donde se entra en grupo (la idea es que vayan los 8 mejores del gremio) y deben vencer las oleadas de monstruos que aparecen. Una vez dentro del mapa, aparecerá en anuncio que el gremio x se está enfrentando a la Arena Mob. Personaje que muere, será transportado a la ciudad y aparecerá un anuncio diciendo que x persona del gremio y murió en la oleada z. En cada oleada los monstruos se vuelven más fuertes y más resistentes. Cada ciertas oleadas todos los personajes que sigan vivos en la dung van a recibir un premio. En cada ciertas oleadas aparecerá un jefe un poco más fuerte. Cuando destruyan la oleada, pueden hacer aparecer otra inmediatamente, pero si no lo hacen, en 60 segundos aparecerá. Cuando muera el último personaje, aparecerá en anuncio que el gremio x terminó la Arena Mob en la oleada y. Luego, hay un ranking donde aparecerá la lista de gremios que llegaron a la oleada más alta. Precio de la quest: 15 usd Discord: Camilo#0869 Un gusto ayudarlos, ¡saludos amigos!
  2. --------------------------------------------------- UPDATE! He puesto multilanguage la quest. En el momento está en español e inglés pero está en variables de translate, así que se puede usar en cualquier servidor internacional, solo se agregan las variables de los otros idiomas. Esta quest es para que se pueda pescar todo lo que quieras en el mar sin tener que modificar ningún archivo en la base! Otra actualización que hice fue que, mientras el evento esté activo y yo como GM agregue o elimine un pez (objeto) va a avisar a todos en un anuncio. ¿La quieres? ------------------------------------------------------- ¡Hola a todos! He sacado de mi baúl de quests un evento de pesca El evento consiste en pescar objetos que el GM agregue a la lista de peces. Saludos a mi amigo @Anthony's que aparece en el vídeo. Vídeo: Instrucciones: El GM activa el evento y asigna la duración. Hay un menú donde aparecen todos los objetos posibles para pescar, y al seleccionar alguno, se puede elegir como modelo para agregar el objeto que se quiera. Una vez agregado, queda en la lista de Objetos especiales que se puede ver en el Pescador y en el NPC donde se activa el evento. Los objetos agregados se pueden eliminar desde la lista de Objetos especiales. Se puede terminar el evento forzadamente. FAQ: ¿Si agrego un objeto, se pueden seguir pescando los peces normales? Sí ¿Qué sucede cuando agrego un pez? ¿en dónde queda? Queda arriba del pez modelo, o sea, del pez elegido. Si elegiste Pez pequeño como modelo, en el fishing.txt va a quedar tu nuevo objeto arriba de esa línea. ¿Si se termina el evento, no saldrán los objetos especiales? Por supuesto que no. Y tampoco se eliminarán los objetos especiales sino que seguirán guardados en la lista. ¿Por qué al pescar objetos con socket aparece una rozadura en un socket? Ya no recomiendo esto, por favor no poner objetos equipables para pescar ¿Si elimino un pez de los normales, lo puedo volver a agregar después? No. Hay que hacer una copia de fishing.txt ¿Por qué vi un tiempo de 30 segundos cuando se iba a activar el evento? Porque era para hacer pruebas, eso ya no estará. ¿Por qué hay que tomar como modelo otro objeto? Porque los parámetros de los peces son muy complejos, y para más facilidad solo se copia y se pega la línea. ¿Cuánto cuesta? Escríbeme para hacer un trato. El servicio cuenta desde la instalación hasta las actualizaciones que haga del evento. Esto fue todo amigos Discord: Camilo#0869
  3. Holaaaaaaaaaaaaaa Vengo a compartir un programa que hice en Python sencillo, que consiste en "traducir" el locale_string.txt. Contexto: cuando descargas una base turca, por ejemplo, viene el locale_string.txt en turco, y no puedes pasar tu locale_string.txt traducido porque resulta que la base turca tiene algunas líneas diferentes que dependen de sistemas, y si pones tu locale_string.txt traducido, te va a dar error. Lo mostraré mejor: Este es el locale_string.txt turco. " %s 군주 후보에서 삭제하였습니다"; "%s Savas arasindan ?kartildi "; " %s 군주로 입명 했습니다."; "%s ?parator aday?olarak g?terildi. "; " %s 군주르 제거 하였습니다.."; "%s ?paratorluk g?evini b?akt? "; "´?¸? °?·ˇAß(?˘°i,±ł??,≫oAˇ)?ˇ´A °ł?I≫oAˇ?≫ ≫c?eC? ?o ??˝?´?´?."; "Bir market a汚k iken baka bir market a?mazs?."; " %s 군주를 제거 할수 없습니다."; "%s ?paratoru g?evi b?akamaz. "; "Kendi marketinizden herhangi bir ey sat? alamazs??."; "Kendi marketinizden herhangi bir ey sat? alamazs??."; "20?? łE?≫ ??°uC??ⓒ ≫oAˇ?≫ ?­?o°ˇ ??˝?´?´?"; "Envanterinizdeki Yang maksimum seviyeye ulam詰. L?fen envanterdeki Yang'lar?k??lere d?淆t?? tekrar deneyiniz."; Este es el locale_string.txt tuyo, el traducido: " %s 군주 후보에서 삭제하였습니다"; "%s is deleted as Emperor Candidate."; " %s 군주로 입명 했습니다."; "%s nominated as Emperor."; " %s 군주르 제거 하였습니다.."; "The %s Emperor gets driven out."; " %s 군주를 제거 할수 없습니다."; "The %s Emperor cannot be driven out."; " %s 는 군주 후보가 아닙니다."; "%s is no Candidate to become Emperor."; " %s 는 군주로 입명할수 없습니다 ."; "%s cannot be nominated as Emperor."; " (만료일 : %d년 %d월 %d일)"; "(Procedure: %d y- %d m - %d d)"; Si te das cuenta, el 4° texto del locale_string.txt turco no existe en el locale_string.txt traducido. ¿Qué hubiese pasado si lo reemplazas en el servidor? probablemente te da error o se pierde ese texto para el sistema que pertenece ese locale. Aquí te lo explico mejor. Turco vs Inglés Por eso he creado un programa en Python que compara las líneas de tu locale_string.txt con las del locale_string.txt del otro servidor y reemplaza el texto. Dejo el código de Python aquí para las personas dev: (más abajo dejo el programa completo) compare_locale_string.py import array def getArrayFile(path): content = [] with open(path) as f: line = f.readline() content.append(line) while line: line = f.readline() content.append(line) f.close() return content print("You should have your locale_string within this directory") print("Type name file translated locale_string.txt (ex. locale_string_en.txt)") other_file = input() locale_string_content = getArrayFile("locale_string.txt") other_file_content = getArrayFile(other_file) count_1 = 1 for i in other_file_content: if '"' in i: count_2 = 1 for j in locale_string_content: if i == j: locale_string_content[count_2] = other_file_content[count_1] break count_2 = count_2 + 1 count_1 = count_1 + 1 with open('new_locale_string.txt', 'w') as f: for i in locale_string_content: f.write(i) print("New file: new_locale_string.txt") Requisitos: debes tener instalado Python versión 3+ Programa completo: archivo adjunto al final ¿Cómo se usa? Luego de tener Python 3+ instalado, vas a hacer esto: 1. Descomprime el rar y pon la carpeta en un lugar donde la identifiques 2. Abrir cmd.exe y poner cd ruta/de/la/carpeta/compare_locale_string 3. Pon py compare_locale_string.py 4. La consola te pedirá el nombre del archivo tuyo. Yo dejé un locale_string_en.txt ahí. 5. Abrir el archivo generado new_locale_string.txt y verificar que todo esté bien. El resultado de las primeras líneas de mi archivo new_locale_string.txt: Saludos amigos! compare_locale_string.rar
  4. Buenas una pregunta al traducir el locale_string se puede traducir las dos lineas o siempre las segundas. es q las letras chino o japones salen para traducir no se si traducir el idioma japones al español se dañe algo . no se si me hago entender bien o siempre es traducir la segunda lineas. locale_string.txt
  5. caanmasu

    RETO quest #1

    ¡Bienvenidos nuevamente, cracks! Espero que se encuentren muy bien porque voy a lanzar un reto. Antes de eso, voy a presentarme de nuevo: soy Camilo Martínez, y conozco Metin2 como desde 2009. Nunca fui bueno, así que me dio la curiosidad de saber cómo se montaba ese juego localmente para acabar el juego y de paso volverme GM. Luego de aprender lo básico de los servidores, me especialicé en quest/lua. Entre esos años han pasado muchas cosas y ahora no puedo dar detalles. Mi experiencia con las quest: llevo 3 años programando quests. He visto todos los posts de quest de este foro y he resuelto todas las quest (para mí mismo) que han pedido. También he analizado y creado quests muy grandes turcas e incluso he aprendido de trabajos muy bien elaborados. Empecé con un say("Hola mundo") y ahora puedo crear mundos con este lenguaje. He aportado quests en este foro que han llegado a tener buena fama, e incluso las he visto en servidores. En total diría que he analizado más de 1000 quests con sus correcciones. Mi valor agregado con las quest aparte de crear cosas exclusivas es personalizarlas, es decir, que solo cambiando números como "nivel_mision = 50" puedas cambiarla según tus necesidades sin tener que modificar código abajo. También me enfoqué en crearlas de manera profesional, y hasta acá llega mi avance. Mi objetivo del reto es obviamente compartir conocimiento para usar este exquisito programa creado por todos para sus servidores o lo que quieran si así lo desean. Les estaré ayudando, dando pistas y trucos, corrigiendo errores. Yo no daré la solución sino ustedes. No hay fecha de caducidad porque esto va a ser para ustedes, y quizá pueda haber premios luego... Este post puede quedar muerto, no pasa nada. La intención es lo importante. Lo que deben hacer es comentar haciendo preguntas, poniendo código en lua, pidiendo pistas, etc. Así es como veo la participación. Reto #1 Elaborar una quest donde: - Un GM desde un NPC pueda dar un objeto X y una cantidad Y a todos los personajes que se encuentren en el mapa donde estás. ¡Let's gooo!
  6. Bueno. aquí les dejo la carpeta Spain. osea la carpeta de locale con map, quest etc. tiene las quest originales limpias sin editar, [Hidden Content] Post Original
  7. Buenas Alguno sabe de como implementar el Baúl de Aprendiz I cuando creo Nueva cuenta no sale.
  8. Buenas Alguno alguno sabe como puedo resolver. SYSERR: May 8 12:52:41 :: ReadQuestCategoryToDict: QUEST couldnt find QuestIndex for name Quest: collect_quest_lv30 (4) SYSERR: May 8 12:52:41 :: ReadQuestCategoryToDict: QUEST couldnt find QuestIndex for name Quest: collect_quest_lv40 (4) SYSERR: May 8 12:52:41 :: ReadQuestCategoryToDict: QUEST couldnt find QuestIndex for name Quest: collect_quest_lv50 (4) SYSERR: May 8 12:52:41 :: ReadQuestCategoryToDict: QUEST couldnt find QuestIndex for name Quest: collect_quest_lv60 (4) SYSERR: May 8 12:52:41 :: ReadQuestCategoryToDict: QUEST couldnt find QuestIndex for name Quest: collect_quest_lv70 (4) SYSERR: May 8 12:52:41 :: ReadQuestCategoryToDict: QUEST couldnt find QuestIndex for name Quest: collect_quest_lv80 (4) SYSERR: May 8 12:52:41 :: ReadQuestCategoryToDict: QUEST couldnt find QuestIndex for name Quest: collect_quest_lv85 (4) SYSERR: May 8 12:52:41 :: ReadQuestCategoryToDict: QUEST couldnt find QuestIndex for name Quest: collect_quest_lv90 (4) SYSERR: May 8 12:52:41 :: ReadQuestCategoryToDict: QUEST couldnt find QuestIndex for name Quest: collect_quest_lv92 (4) SYSERR: May 8 12:52:41 :: ReadQuestCategoryToDict: QUEST couldnt find QuestIndex for name Quest: collect_quest_lv94 (4) SYSERR: May 8 12:52:41 :: ReadQuestCategoryToDict: QUEST couldnt find QuestIndex for name Quest: collect_quest_lv96
  9. Hola comunidad de Metin2Zone quien me podria hacer el favor y me podria editar esta quest para que escoja si quiere corporal o mental etc, y si es posible que pida 50kk de yang por hacerte las p muchisimas gracias y disculpen si los incomodo when 50512.use begin if pc.get_level() < 50 then say_title("Debe De Ser Nivel 50 Para Poder Subir Sus Habilidades Ha Perfect") return end say_title ("Subir Ha Perfect Master") say ("") say ("¿Husted Desea Subir Sus Habilidades Ha Perfect?") say ("") a = select ("Subir A Perfect" , "Cerrar") if a == 2 then elseif a == 1 then pc.set_skill_level (1,59) pc.set_skill_level (2,59) pc.set_skill_level (3,59) pc.set_skill_level (4,59) pc.set_skill_level (5,59) pc.set_skill_level (6,59) pc.set_skill_level (16,59) pc.set_skill_level (17,59) pc.set_skill_level (18,59) pc.set_skill_level (19,59) pc.set_skill_level (20,59) pc.set_skill_level (21,59) pc.set_skill_level (31,59) pc.set_skill_level (32,59) pc.set_skill_level (33,59) pc.set_skill_level (34,59) pc.set_skill_level (35,59) pc.set_skill_level (36,59) pc.set_skill_level (46,59) pc.set_skill_level (47,59) pc.set_skill_level (48,59) pc.set_skill_level (49,59) pc.set_skill_level (50,59) pc.set_skill_level (51,59) pc.set_skill_level (61,59) pc.set_skill_level (62,59) pc.set_skill_level (63,59) pc.set_skill_level (64,59) pc.set_skill_level (65,59) pc.set_skill_level (66,59) pc.set_skill_level (76,59) pc.set_skill_level (77,59) pc.set_skill_level (78,59) pc.set_skill_level (79,59) pc.set_skill_level (80,59) pc.set_skill_level (81,59) pc.set_skill_level (91,59) pc.set_skill_level (92,59) pc.set_skill_level (93,59) pc.set_skill_level (94,59) pc.set_skill_level (95,59) pc.set_skill_level (96,59) pc.set_skill_level (106,59) pc.set_skill_level (107,59) pc.set_skill_level (108,59) pc.set_skill_level (109,59) pc.set_skill_level (110,59) pc.set_skill_level (111,59) pc . remove_item("50512",1) elseif a == 2 then end end end end
  10. Hola Comunidad de metin2zone, me e encontrado un archivito en otro foro (Just4Metin-Donici Cătălin) y me vi en la necesidad de compartirlo :D porque esta muy PRO! Bueno dejo el tuto :D depronto este postiado pero aqui lo revivimos :v aclaro el tuto no es mio. 1-Vamos a la carpeta de las quest usr/home/game/share/locale/xxxx/quest Alli buscamos el siguiente archivo Questlib.lua, bajamos y pegamos las siguientes lineas 2- nos devolvemos a usr/home/game/share/locale/xxxx/quest y buscamos el archivo quest_functions y pegamos las siguientes lineas y listo con eso ya tenemos la funcion de la quest de colores :D say_rosu(“rojo”) say_verde(“verde”) say_portocaliu(“naranja”) say_negru(“negro”) say_alb(“blanco”) say_galben(“amarillo”) say_verde(“verde claro”) Aclaro la guia funciona perfectamente :D
  11. Aqui traigo esta quest que encontre por ahi, que cambie tu nick, a algunos les servira, a otros no, igualmente aqui la tiene ^-^ quest cambio_nombre begin state start begin when item que desea usar.use begin if pc.is_married() then say("Usted no puede cambiarse su nombre si está casado.") say("") return end if pc.is_polymorphed() then say("Usted no puede cambiar su nombre si está transformado.") say("") return end if pc.has_guild() then say("Usted no puede cambiar su nombre si está en un gremio. ") say("") return end if party.is_party() then say("Usted no puede cambiar su nombre si está en grupo.") say("") return end if pc.get_level() < 35 then say("Necesitas ser nivel 35 o mas para cambiar tu nombre!") say("") return end if get_time() < pc.getqf("next_time") then say("No puede utilizarce ahora.") say("") if is_test_server() == true then say("Puede irse") say("") else return end end say("Introdusca su nombre nuevo") ; local name = pc.name ; local str = input() ; if string.len(str) > 16 then say("El nombre es demasiado largo, intentelo de nuevo.") say("") return end local ret = pc.change_name(str) ; if ret == 0 then say("Debe relogear despues de cambiar su nombre.") say("please re-log in.") say("") char_log(0, "CHANGE_NAME", "HAVE NOT RE-LOGIN") elseif ret == 1 then say("Ha ocurrido un problema.") say("Por favor uselo de nuevo.") say("") char_log(0, "CHANGE_NAME", "ITEM USE PROBLEM") elseif ret == 2 then say("Este nombre no está disponible.") say("Por favor ingrese otro nombre.") say("") char_log(0, "CHANGE_NAME", "CAN NOT USE NAME") elseif ret == 3 then say("Este nombre no está disponible.") say("Por favor ingrese otro nombre.") say("") char_log(0, "CHANGE_NAME", "ALREADY USING NAME") elseif ret == 4 then say("Ha cambiado su nombre con exito.") say("Por favor, inicie sesión de nuevo.") say("") item.remove() ; pc.setqf("next_time", get_time() + time_hour_to_sec(24*15)) char_log(0, "CHANGE_NAME", "SUCCESS: from "..name.." to "..str) else say("Error desconocido.") say("") char_log(0, "CHANGE_NAME", "UNKNOWN NAME") end end end end si yasé que ya estaba por ahi, pero solo le puse las lineas al español(que dificil no? XD)
  12. Alguien tiene esta quest. traducida? Yo la estoy traduciendo pero no sé si es así tal cual. Gracias Por su atención. gmpanel.quest
  13. wenas a todos!! He estado haciendo una quest para los que les da pereza andar con comandos de mutear y esas cosas, tambien puse todos lo que se me ocurrieron, si se me paso alguno, decirlo y lo añado. Para poder usar la parte de banear gente, hace falta tener lo del mysql para quest, podeis encontrarlo aqui , no se si funcionara la quest sin eso... Click aqui para descargar la quest Descripcion de opciones: Halloween: Lo que hace es invocar unos npcs para halloween, deben ser configurados en la quest. Como usar el comando "/m" Dia/noche: creo que no hace falta explicacion xD Rates: para poner cualquier rate para reinos o por separado. Pronto rates para gremios xD Bloquear chat: como su nombre dice, es para silenciar el chat, para quitar el silencio o ver la lista de silenciados. Navidad: Para activar/desactivar cualquier evento de navidad, como la nieva, el arbol de navidad, los villancicos, Santa Claus, venta de fuegos artificiales, etc Banear: Banea/Desbanear la cuenta de la persona que quieras, pero necesitas implementar mysql para quest, aqui el post. Teleport: Para que te teletrasportes hacia una persona, o para traerlo hacia ti. Recordad: No os olvideis de poner vuestros datos y esas cosas en las funciones de mysql_query() al final de la quest hay 4 funciones parecidas a la siguiente, en "root" es el usuario del navicat(suele ser root), en PassNavicat, pos eso, la pass xD, en account no tocarle, y en ipNavicat, es la ip del server, los datos esos, van entre comillas como estan puestos ahy, si las quitais os dara error. mysql_query("Update account.account set account.status = 'OK' WHERE account.id ="..id.account_id[1].."" ,"root","PassNavicat", "account", "IPNavicat") Si teneis alguna duda, preguntaros, y recordad que nunca esta de mas dar las gracias xD Saludos!!
  14. Hola amigos soy novato en esto me gustaría si me pueden ayudar tengo files rain cliente omega me podrían dar las quest del oficial y decirme como borrar quest que ya tengo es que cuando lo ago me da error muchas gracias.
  15. Hola gente, hace unos dias pasaba por UJ y me encontre con esto, ustedes diran "hab a p wao ._." pero lo que hace esto es que tambien te sube las habilidades secundarias como Poliformismo, las habilidades de monta, etc. Creditos: Clawdi
  16. ¡Hola a todos! Esta es una guía para crear quest como un profesional. ¿Has editado una quest desde bloc de notas y parece muy difícil? realmente lo es. De hecho, yo no puedo hacer quest ahí ¿Has editado quest por Notepad++ y parece muy difícil? al principio cuando era nuevo y no configuraba Notepad++ sí. Ahora que tengo experiencia puedo decirte que existen ciertas configuraciones y reglas para facilitar la programación de quests. Esta guía tiene el objetivo de facilitar la programación de quests, a tal nivel que, ahorrarás bastante tiempo haciéndolas sin cometer errores porque los verás al instante. Empecemos: 1. Configurar Notepad++ Abre Notepad++ y haz lo siguiente: 1.1 Haremos que al darle a Nuevo, nos cree un archivo con la codificación correcta (ANSI) para que el servidor lea las tildes. Además, el nuevo archivo tendrá por defecto el lenguaje Lua donde resaltará las palabras reservadas (como if, for, etc) Procedimiento: Configuración -> Preferencias -> Archivo nuevo -> Codificación: ANSI, Lenguaje: Lua 1.2 Dejaremos por defecto el tamaño del tabulador en 4. Procedimiento: Configuración -> Preferencias -> Lenguaje -> Tamaño: 4 1.3 Para que se vean los tabuladores y espacios. Ver los espacios nos ayuda a diferenciar de los tabuladores cuando son muy reducidos. Los tabuladores nos ayudarán a indentar el código (ya lo veremos más adelante) Procedimiento: Vista -> Mostrar símbolo -> Mostrar espacios y tabulaciones Finalmente verás los espacios y tabuladores así: 1.4 Crearemos una extensión del lenguaje Lua. Como sabemos, el lenguaje Quest es un derivado del lenguaje Lua y cuando abrimos un archivo .quest no lo va a reconocer como Lua. Procedimiento: Configuración -> Configurador de estilo... -> Lenguaje: Lua -> Ext. Usuario: quest Nota: no cierres la ventana aún 1.5 Vamos a agregar la palabra reservada with a nuestro lenguaje quest. La palabra with está dentro de los conjuntos if, else, elseif, then, etc. Solo que esas están en Lua, y with está en quest porque se usa en el bloque when. Lo que hacemos es meter los conjuntos de palabras reservadas del mismo tipo de Lua en quest. Procedimiento: Configuración -> Configurador de estilo... -> Lenguaje: Lua -> Estilo: INSTRUCTION WORD: with, Tipo de fuente: Negrita 1.6 Vamos a hacer lo mismo que el paso anterior pero con las funciones. Procedimiento: Ir al FTP ir a la carpeta quest y copiar el contenido que tengas en quest_functions. Luego: Configuración -> Configurador de estilo... -> Lenguaje: Lua -> Estilo: FUNC1: (pegar todas las funciones de quest_functions), Tipo de fuente: Negrita 1.7 Haremos lo mismo pero con las palabras reservadas de quest. Procedimiento: Configuración -> Configurador de estilo... -> Estilo: FUNC2: quest begin state end when, Tipo de fuente: Negrita 2. Hacer una quest profesional probando este entorno de desarrollo mejorado Cuando hablo de indentar me refiero a jerarquizar el código. Es decir, un programa quest tiene una estructura de bloques. El bloque más poderoso, más sobresaliente, es el bloque quest. Bloque quest: Pero necesita un state para funcionar, y además tiene un state que se ejecuta por defecto que es el start. ¿Por qué puse los tabs y por qué ahí? Porque el bloque quest y state no van en la misma jerarquía. Tú no puedes poner primero el state y luego el quest. Quest identifica la quest, y state identifica el estado, o sea, el conjunto de disparadores (when) que afectan al personaje. Si el personaje está en otro state, los when de los otros state no funcionarán. Vamos a crear un when: Cada vez que abrimos un bloque, las siguientes líneas van con un tab nuevo. ¿Cuáles son los bloques? aquí los dejo a continuación: No es difícil, apenas son el quest, state, when, function (que son típicos de Quest), y los if-elseif, if, for (hay otro que es repeat pero lo omitiré) que son de Lua. Todo bloque termina en end, y ese end va en la misma jerarquía que el bloque obviamente. ¿Por qué indentar? Después de ver tantas quest me di cuenta que podías buscar un error durante 4 horas y no encontrarlo cuando era un end que faltaba o que estaba de más. Indentar las quest te hace tener el código más ordenado y así vas a tener éxito haciendo esto, lo digo por experiencia. Tips que nadie te los dirá: - El bloque function puede ir en cualquier state y lo puedes llamar sin problema. Si function está en state start y el personaje está en state run, puedes llamarlo desde run y funciona. - Regla de los say, select: no debes tener ciertos caracteres especiales como tildes como último caracter y tampoco te pases de 49 caracteres (50 ya te da un salto de línea). - Regla del with. El with sirve para separar las instrucciones de disparadores de las otras. Es decir, when login or levelup with pc.level > 10 begin, lo que está antes del with son disparadores (es decir, se activan una vez suceda) y se ponen antes del with. Nunca va un and porque es imposible que sucedan dos disparadores al mismo tiempo. Luego lo que va después del with son instrucciones en Lua normales, allí puedes jugar con las funciones sin problema. - Abreviaciones básicas: en la parte anterior puse pc.level, esto es porque en el questlib.lua hay unas asignaciones. Puedes ver que pc.level = pc.get_level(), lo cual quiere decir que cuando pones pc.level hará referencia a lo que está después del igual. Y así con otras funciones. Puedes probar tu nuevo entorno en Notepad++ y estarás confiado si te quedó bien una función si te aparece de color morado. Esto fue todo por hoy. Ofrezco mis servicios de quest/lua y tengo una buena promoción de una misión de caza súper buena con un buscador de ítems en cofres :3 [Hidden Content] ¡Que tengan muchos éxitos!
  17. ¡Hola a todos! Les traigo una quest de cacería personalizada hecha por mí. Mi objetivo, aparte de entregarles algo de calidad, es pedirles una colaboración monetaria para un proyecto de emprendimiento que voy a realizar. Mi misión de caza está valuada en 15 USD la quest + 5 USD los datos (toda la parte de los niveles, los jefes, recompensas, etc). El método de pago es PayPal. La diferencia de mi misión con las otras de caza es que es personalizada. Primero unos gif y pantallazos para que no te pierdas: Aceptar la misión [Hidden Content] Contenido de la misión [Hidden Content] En batalla [Hidden Content] Recompensa [Hidden Content] Esa fue solo la misión de nivel 1. Luego la misión de nivel 10 es esta: No me dejó subir la otra imagen... Recompensas misión nivel 10. [Hidden Content] Detalles de la misión El personaje cuando empieza, le aparece un pergamino donde hay que aceptar que vas a hacer las misiones. Luego te envía a la primera misión. El sistema asigna los monstruos según lo que tengas en tu quest. El sistema solo asigna uno por cada categoría para matar. Por eso vas a ver que en monstruos hay como 20 pero solo aparece 1 en la misión, al azar. Cada vez que mates a uno, aparecerá en el chat y te mostrará cuántos llevas y cuántos te quedan. Cuando ya hayas alcanzado el máximo, no volverá a aparecer. Cuando completas la cantidad de monstruos de la categoría, te aparece en blanco, sino, en rojo. Para las recompensas, recibes exp, yang e ítems, dependiendo de cómo lo tengas en tu quest. Yo puse que a partir de la de nivel 10 aparezcan ítems, por eso no los vieron en el gif. Si el Yang se pasa de 2kkk cuando terminas la misión, no te deja recibir recompensas sino que te toca vaciar un poco tu Yang para poder recibir toda la recompensa. Las misiones son continuas, una vez terminas la misión, te aparece la siguiente siempre y cuando cumplas con el nivel requerido. Cuando se acabe la última misión y se reclama la recompensa ya no vuelve a salir el pergamino. Cómo personalizar: El [1] es el nivel de la misión. Más arriba están las categorías, dejé que 1 fuera metines, 2 monstruos normales y 3 jefes. Así que aquí puedes ver que en metines pide 1 metin de dolor. En monstruos normales pide perros... En recompensas puse que diera exp, yang e ítems. Pon true la variable current_level_quest para dar el % de exp según el nivel del personaje. Pon false si quieres que de el % de exp según el nivel de la misión. En exp_perc pues el % de exp. Al final de las tablas nunca va la coma, cuidado allí. Si no quieres dar exp, pon 0 en exp_perc. Si no quieres dar yang pon 0 en yang. Si no quieres dar ítems déjalo así como lo tengo allí. Todos estos valores se pueden cambiar. Yo los hice según mi jugabilidad pero creo que está bien. La última misión: Aquí tomé los metines de Bosque Encantado. Los monstruos del Templo Ochao y Bosque Encantado. En jefes puse Meley y Jotun. Recompensas allí pueden verlo. Cómo obtener esta misión de caza? hagamos un trato por privado aquí en Zone o Discord: Camilo#0869 Cualquier consulta puedes escribirme al Discord Camilo#0869, yo ayudo mucho con quest/lua, así que no lo dudes. ¡Muchas gracias por llegar hasta acá!
  18. Buenas noches Zone alguien me puede ayudar compartiendo la quest de boda gracias
  19. Hola Tuve un bug que al matar un metin no podía entrar al when de la quest. when kill with npc.get_race() == 8001 begin chat("Acá debería entrar cuando mato el Metin de Dolor") end Cuál es el problema? pues que no puedes hacer una misión con metines porque simplemente no los puedes identificar. Algunos files vienen con errores en el mob_proto.txt Los files que uso son Arrival2 y tenía otros files donde también tenía el bug pero no recuerdo cuáles eran... Solución: ponerle exp al metin. En la columna exp del mob_proto.txt ponerle un número mayor a 0. De nada
  20. Hola gente! Hoy les traigo un material de traducción, el archivo Npc_talk, de que va esta quest? La quest trata de cuando apretas sobre un Npc te pone como una "conversación" y te cuenta lo que piensa o sucede. La traducción esta basada en el Metin2.es cada renglón. Si tiene algún fallo ortográfico por favor díganme así lo corrijo. Enlace a la quest: [Hidden Content] Solo para Mt2Zone. Espero que les haya servido esta quest para traducir un poco mas el server, por favor darle Un Me Gusta al tema y un Gracias! Saludos!
  21. Buenas, agradesco desde ya su apoyo y ayuda, la cosa es la siguiente: 1.- Al llegar al nivel 150 se active una quest para elegir una facción, que seria "lycano o vampiro". 2.- NPC con activar/desactivar evento "guerra de facciones", este NPC debe servir como teleport a mapa de dicho evento. 3.- una vez dentro del mapa, aparece un pequeño icono (dependiendo de la facción elejida) junto al nombre del personaje. 4.- una vez iniciando la batalla, no se podra hacer " daño entre reinos" sino "entre facciones". 5.- una vez termine el "tiempo designado" para el evento, se active un anuncio tipo "/B" diciendo; "batalla terminada..." x faccion" ha matado "tantos" "x facción". (entiéndase "x facción", como "Lycano o vampiro" / "tantos" como el numero de pj que mataron en total) 6.- todos los PJs que participaron del evento y que pertenecen a la faccion ganadora, reciben "x" item y el "icono" de su correspondiente faccion activos por "X" tiempo Espero haberme explicado bien, y espero de verdad que esto no sea tan complicado. Gracias
  22. Buenas, agradesco desde ya su apoyo y ayuda, la cosa es la siguiente: 1.- Al llegar al nivel 150 se active una quest para elegir una facción, que seria "lycano o vampiro". 2.- NPC con activar/desactivar evento "guerra de facciones", este NPC debe servir como teleport a mapa de dicho evento. 3.- una vez dentro del mapa, aparece un pequeño icono (dependiendo de la facción elejida) junto al nombre del personaje. 4.- una vez iniciando la batalla, lo unico no se podra hacer " daño entre reinos" sini "entre facciones". 5.- una vez termine el "tiempo designado" para el evento, se active un anuncio tipo "/B" diciendo; "batalla terminada..." x faccion" ha matado "tantos" "x facción". (entiéndase "x facción", como "Lycano o vampir"o" / "tantos" como el numero de pj que mataron en total) 6.- todos los PJs que participaron del evento y que pertenecen a la faccion ganadora, reciben "x" item y el "icono" de su correspondiente faccion activos por "X" tiempo 7.- to
  23. Hola amigos, cordial saludo la molestia es, si me podrían colaborar con un poco de su conocimiento en una quest para que un item sea la llave por decirlo así del dopador automático.
  24. Hola! ¡Al grano! Crear un archivo llamado borrar.sh y agregar este contenido. #!/bin/sh echo Por favor, introduce nombre archivos quest a borrar sin .quest read NOMBRE find . -type f -name "$NOMBRE*" echo borrar S/N read borrar if [ $borrar = "s" ]; then find . -type f -name "$NOMBRE*" -exec rm -v {} \; fi Después meterlo en la carpeta quest/object Para ejecutarlo debes ir a la consola y poner: cd ruta/quest/object && sh borrar.sh o si ya estás en object solo pones: sh borrar.sh Nota: ese archivo me lo encontré en los files Ethernia, creo. No es mío. Explicación: Si pensabas que eliminar una quest era borrar el archivo de quest pues ¡It's wrong! Si eliminabas la quest desde la carpeta object buscando cada when tal vez se te hacía fácil pero imagínate una quest bien compleja... buscando cada when. Para que tenga sentido los comandos que te doy, voy a explicarte cómo funciona bien el árbol de las quest compiladas Cuando haces ./qc nombre_quest, se crean ciertos archivos en la carpeta quest/object. Míralo de esta forma, quest es un bloque que en jerarquía es el mayor de todos y se almacena en quest/object en varios archivos que mencionaré a continuación. quest nombre_quest begin end Luego el siguiente nivel de jerarquía es state y un archivo se almacena en quest/object/state/nombre_quest quest nombre_quest begin state start begin end end Ese archivo describe los id de cada state (el state start es obligatorio y siempre entra a ese state primero antes que a otro, por lo tanto el id siempre será 0) y cada función. Así para el ejemplo de la quest de arriba: nombre_quest={["start"]=0} Si la quest tiene otro state, se agrega separado por coma y se le asigna un id aleatorio, así: nombre_quest={["start"]=0, ["state_dos"]=12434543, ["state_tres"]=3453434} Si la quest tiene funciones, se agregan así. nombre_quest={["start"]=0, ["state_dos"]=12434543, ["state_tres"]=3453434,nombre_funcion= function() todo_el_contenido_aquí} Después el siguiente nivel de jerarquía es when y cada when se almacena en un archivo diferente en quest/object/ Si el when está llamando a un objeto, entonces se crea una carpeta. Por ejemplo: quest nombre_quest begin state start begin when 101.kill begin end when 20095.chat("Hola") begin end when mi_timer.timer begin end when kill begin end end end Voy a explicar cada caso por cada when en orden Caso 1: se crea el archivo quest/object/101/kill/nombre_quest.start. El kill está llamando al objeto 101 que es el perro salvaje. Caso 2: se crea el archivo quest/object/20095/chat/nombre_quest.start. El chat está llamando al objeto 20095, obviamente chat solo está configurado para mob tipo NPC. Caso 3: se crea el archivo quest/object/mi_timer/timer/nombre_quest.start. El timer está llamando a mi_timer que fue un timer creado en un when así: timer("mi_timer", tiempo_en_segundos) Estos tres casos tienen algo en común y es que cuando el when llama a un objeto se crea una carpeta con el nombre del objeto o el id, luego adentro crea otra carpeta con la acción (kill, chat, timer, loop_timer, server_timer o server_loop_timer) ¿Qué sucede si la acción no llama a un objeto? Se crea el archivo en una carpeta llamada notarget en quest/object. Caso 4: se crea el archivo quest/object/notarget/kill/nombre_quest.start Como ya se han dado cuenta, el archivo que se crea es de extensión .state El árbol de archivos y carpetas tienen una estructura específica para describir las quest una vez se compilan. ¿Qué contenido traen los archivos nombre_quest.state? Adivinaste. El mismo contenido del when que pertenecen a ese state. El árbol queda así para la quest de ejemplo: Puede ser más complejo meter más state, complicar el when poniendo muchos or combinando acciones llamando a objetos y otras no, pero no es el objetivo profundizar esto. La conclusión es simple, todos los archivos creados tienen algo en común: el nombre Por eso el archivo en bash (líneas de comandos para la consola) borra lo que digites sin el .quest para que se borre también el state. Si has llegado hasta aquí no has perdido el tiempo. Ahora entiendes un poco más cómo está estructurado esto. Si te preguntas por qué hay un perro que dropea barras de oro y no encuentras el archivo en quest, puede que no esté allí pero sí esté compilado en object. Anexo: Si al hacer una acción implica dos when, siempre hará el primero e ignorará a los demás, ejemplo: when 101.kill begin chat("Rojo") end when kill begin chat("Negro") end Si matas un perro te va a decir Rojo Si cambiamos el orden de los when, pasará esto: when kill begin chat("Negro") end when 101.kill begin chat("Rojo") end Al matar un perro va a decir Negro Saludos!
  25. Saludos a todos, le dejo esta quest que modifique (no se mucho de quest) La quest trata de un libro que estaba oculto en una cueva de las tierra del fuego, y que al abrirlo les pedira ser lvl 125, tener una esfera de cristal y listo, como premio por comprender el libro te da un atuendo de lvl 125... En mi caso el ítem: 9030 era Libro Coraza Dragón Al abrirlo me indicaría lo que necesito para leer ese libro, todo es totalmente editable y por lo que veo fácil de entender... 9015 era Esfera Cristal Solar, que es lo que necesito para leer el libro en question... Ustedes lo adaptan como quieran, le cambian el "vnum-de-item.use" a "vnum-de-NPC.chat" para usarlo en NPC (ojo que no se mucho de quest, si alguien sabe mas agradezco que me corrija!! ) Le cambian el lvl si quieren o simplemente le borran el " if pc.get_level() < 125 then " Puede ser un Baul, Cofre, Libro, Pelota, ETC... Lo que se les venga a la mente mientras tengan un linea valida. mas un icono para ver el item y que sea type 18.... Espero que alguien le sirva y de verdad si hay algo mal en la quest agradezco que me corrijan y si la dejan mejorada, genial, asi tambien la arreglo yo jajaj SUERTE!!!
×
×
  • Create New...