Jump to content

caanmasu

Members
  • Posts

    347
  • Joined

  • Last visited

  • Days Won

    25

caanmasu last won the day on November 9

caanmasu had the most liked content!

Recent Profile Visitors

7,357 profile views
  1. Te ves serio. Espero que todo te salga súper bien, saludos.
  2. Hola EDITADO: encontré una manera más sencilla. Poner un número muy grande en regen_cycle y el 1 en regen_percent. :v Así haremos que cada 255 (es el máx) segundos regenere 1% Sé que algunos ponen a veces eventos donde los mobs solo reciben 1 punto de daño por golpe y también sé que en el evento de attendance (cazajefes) el jefe no se recupera la vida hasta donde tengo entendido. Este fix es para concretamente hacer que cuando pones en el mob_proto en el regen_percent un 0, no regenere la vida. Digo esto porque todavía se sigue regenerando y la razón es porque en el código fuente hay una función que acota el rango de valores de 1 a x, siendo x el % de la regeneración. Solo debemos cambiar ese 1 por un 0. char.cpp Buscar este bloque: EVENTFUNC(recovery_event) Ir más bajo dentro del bloque y adaptar: if (!ch->IsDoor()) { #ifdef ENABLE_REGENPERCENT_0 ch->MonsterLog("HP_REGEN +%d", MAX(0, (ch->GetMaxHP() * ch->GetMobTable().bRegenPercent) / 100)); ch->PointChange(POINT_HP, MAX(0, (ch->GetMaxHP() * ch->GetMobTable().bRegenPercent) / 100)); #else ch->MonsterLog("HP_REGEN +%d", MAX(1, (ch->GetMaxHP() * ch->GetMobTable().bRegenPercent) / 100)); ch->PointChange(POINT_HP, MAX(1, (ch->GetMaxHP() * ch->GetMobTable().bRegenPercent) / 100)); #endif } Es opcional ponerle defines pero la idea es que entiendas que cuando se va a hacer el cambio de HP (aumentar en % por la reg) originalmente viene desde 1 hasta el regen_percent que hay en el mob_proto. Solo cambié el 1 por el 0. Solo de este modo se regenerará 0% cuando esté en 0 el regen_percent. La condición del if indica que eso va a ocurrir en toda entidad caracter (mobs, metines, personajes, etc) menos puertas.
  3. Hola He hecho un fix a una función, es algo sutil pero verán la diferencia. Cuando usas en una quest la función: game.drop_item(item_vnum, count) o su variante game.drop_item_with_ownership, es para que caiga un objeto al suelo, ya sea sin nombre o con nombre. Pero encontré un problema, resulta que en un evento había que matar a un jefe, y el jefe botaba objetos sin nombre para el que pudiera tomarlos. Se supone que el jefe bota los objetos debajo de él, pero el problema es que si alguien mata al jefe desde lejos, van a caer los objetos debajo de él y tendrá ventaja sobre los demás al recoger los objetos. La razón es esta: questlua_game.cpp ALUA(game_drop_item) { // // Syntax: game.drop_item(50050, 1) // LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); DWORD item_vnum = (DWORD) lua_tonumber(L, 1); int count = (int) lua_tonumber(L, 2); long x = ch->GetX(); long y = ch->GetY(); LPITEM item = ITEM_MANAGER::instance().CreateItem(item_vnum, count); if (!item) { sys_err("cannot create item vnum %d count %d", item_vnum, count); return 0; } PIXEL_POSITION pos; pos.x = x + number(-200, 200); pos.y = y + number(-200, 200); item->AddToGround(ch->GetMapIndex(), pos); item->StartDestroyEvent(); return 0; } La instancia de quest recoge el personaje seleccionado, es decir, el personaje que dropea. Donde dice AddToGround, envía en el 2° parámetro la posición pero la posición la saca de ch->GetX(), es decir, las coordenadas del personaje. En otras palabras, el objeto caerá por debajo del personaje que mató al monstruo y no debajo del monstruo. En este caso la solución es preguntar si hay un npc seleccionado, ya que si hacemos un game.drop_item() en un when login no interesa porque el objeto no tiene un objetivo distinto que del personaje. Pero si es un when kill, tiene que caer en el personaje seleccionado. Fix: Cambia la función por esta: ALUA(game_drop_item) { // // Syntax: game.drop_item(50050, 1) // LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); DWORD item_vnum = (DWORD) lua_tonumber(L, 1); int count = (int) lua_tonumber(L, 2); long x = ch->GetX(); long y = ch->GetY(); LPITEM item = ITEM_MANAGER::instance().CreateItem(item_vnum, count); if (!item) { sys_err("cannot create item vnum %d count %d", item_vnum, count); return 0; } CQuestManager& q = CQuestManager::instance(); LPCHARACTER npc = q.GetCurrentNPCCharacterPtr(); PIXEL_POSITION pos; if (npc && (npc->IsMonster() || npc->IsStone())){ pos.x = npc->GetX() + number(-200, 200); pos.y = npc->GetY() + number(-200, 200); } else { pos.x = ch->GetX() + number(-200, 200); pos.y = ch->GetY() + number(-200, 200); } item->AddToGround(ch->GetMapIndex(), pos); item->StartDestroyEvent(); return 0; } Adapta también a la de game.drop_item_with_ownership(). Ya con el código pueden comparar y entender lo que he hecho. Si matan un metin o un monstruo y tienen el drop por game.drop_item... caerá el objeto sobre el mob. Un saludo.
  4. Hola Vi que muchos servidores privados cuando se les caía un core quedaba horas caído y las personas no podían acceder a los mapas de ese core. Había que esperar a que lo reporten al administrador y él se encargue de reiniciar el servidor. Pues esta práctica no es muy buena obviamente. Y aquí traje la solución. Siempre estuvo esto, solo que pocos se han dado cuenta. Deben tener los files Marty Sama o al menos tener la misma estructura, saben que me refiero al archivo admin_panel.sh y relacionados. Al iniciar el servidor normalmente escribimos 1 o 1i, y para cerrarlo 2 o 2i. Esta vez utilizaremos las opciones que están resaltadas en amarillo. 1a: hace lo mismo que el 1 (iniciar todo) con la diferencia de que se creará un proceso demonio donde cada x tiempo se ejecutará el start. 2a. hace lo mismo que el 2 (cerrar todo) con la diferencia de que se creará un proceso demonio donde cada x tiempo se ejecutará el close. Si inicias de esta manera, tu servidor abrirá todos los CHs disponibles. Para evitar esto, debes editar el archivo start.list [ { "serv": "srv1", "path": "srv1/db", "chan": 0, "type": 1, "name": "srv1-db" }, { "serv": "srv1", "path": "srv1/auth", "chan": 0, "type": 2, "name": "srv1-auth" }, { "serv": "srv1", "path": "srv1/chan/ch1/core1", "chan": 1, "type": 5, "name": "srv1-ch1-core1" }, { "serv": "srv1", "path": "srv1/chan/ch1/core2", "chan": 1, "type": 5, "name": "srv1-ch1-core2" }, { "serv": "srv1", "path": "srv1/chan/ch1/core3", "chan": 1, "type": 5, "name": "srv1-ch1-core3" }, { "serv": "srv1", "path": "srv1/chan/ch99/core99", "chan": 99, "type": 5, "name": "srv1-ch99-core99" } ] Simplemente deja los CHs que quieres que se inicien. En mi servidor solo necesito CH1 porque lo uso para pruebas, así que he quitado CH2, 3, 4, 5 y 6. Y siempre haz una copia antes de modificar el archivo. Ya iniciado el servidor con 1a, cada vez que se genere un game.core, el servidor se caerá pero en x tiempo volverá a recuperarse y se podrá volver a entrar. El x tiempo son 10 segundos, lo puedes encontrar en el archivo daemon.sh. Para servidores con muchos jugadores recomiendo aumentar el número a 5 minutos. Siempre que se inicie el servidor con 1a y lo vayas a cerrar, debes cerrarlo con 2a o sino se bugea. Parte técnica (académica) El archivo admin_panel.sh tiene este script en la sección 1a: 1a|startall) cd $v_mt2f sh daemon.sh & cd $v_base cecho "startall completed" ;; Donde vemos que se ejecuta el archivo daemon.sh. Seguido con un &, esto indica que el proceso se ejecutará en segundo plano, es decir, a pesar de que está trabajando, podrás seguir ejecutando comandos en la misma consola. El archivo daemon.sh luce así: #!/bin/sh #### @martysama0134 start scripts #### while true; do ./start.py & sleep 10 done Hace un ciclo infinito pero hace una pausa de 10 segundos. Esto no significa que el servidor se abra cada 10 segundos porque deben morir esos procesos antes de iniciar unos nuevos. Cómo los puedes probar? Una vez el servidor esté encendido, verifica todos los procesos con el comando ps. Revisa que estén todos tus cores. Elige el número de un proceso, por ejemplo, el de core1 y ejecuta el comando kill, así: kill 70176 Una vez matado el proceso, ejecuta de nuevo ps. Ya no aparecerá pero en pocos segundos verás en la consola cómo se ejecuta de nuevo ese core y podrás volver a entrar a los mapas. Si llegaras a cerrar el servidor con el 2 o 2i, se encenderá de nuevo automáticamente porque la opción 2 o 2i no matarán el proceso de daemon.
  5. El 22 de agosto Trinity subió vídeo en YouTube de su versión V120 de los files y son los files Avenor... Yo diría, bueno, si compartiera los files no habría problema, pero que se lucre con el trabajo de otros sí lo veo un problema. Para mí es un estafador. En ninguna parte del vídeo dice de dónde es la fuente. A ver si no me han entendido, yo coger los Wonder y cambiarle el nombre y venderlo. En serio que el diseño, los sistemas, los errores de textura en algunos objetos, todo es igual. No creo que sea un desarrollador ético, está hambriento de buscar incautos. Dejo link del vídeo: https://www.youtube.com/watch?v=yZU9CwHM2sM
  6. Cualquiera sale a vender una base y todos salen a decir que la quieren comprar
  7. Misiones de caza del oficial He renovado la quest de caza del oficial, la mostraré en el siguiente vídeo: Descripción: Quest levelup Cuando fue filtrada la fuente del juego por primera vez, aparecía en quest este archivo levelup.quest. Fue la primera o una de las primeras misiones programadas en el juego. Al intentar instalar esta misión con el archivo original, estaba incompleta y no funcionaba del todo. El código fuente de la misión es demasiado ineficiente, difícil de modificar y su estructura es pésima; es así al ser posiblemente la primera quest programada en el juego y el conocimiento en el lenguaje era nuevo. Mi trabajo fue hacer funcionar esta misión, hacerla completa, mejorar su estructura y código fuente. La misión viene con la quest, la librería de los datos (niveles, monstruos, señales, recompensas, etc) y las imágenes de los monstruos. Parámetros a configurar: Niveles: puedes quitar niveles sin problema. Aunque la misión va desde el nivel 2 al 90 consecutivo, no se recomienda quitar niveles. Puedes agregar niveles siempre y cuando tengas una imagen del monstruo. Cantidad: puedes modificar la cantidad de monstruos que vas a matar. Recompensas: puedes modificar la experiencia, los objetos y el Yang. Tener en cuenta que en algunas partes hay que modificar textos fijos en las recompensas. Recompensas: Las recompensas de experiencia y oro están estructuradas en distribuciones, y cada distribución tiene un rango de niveles. Es decir, si el monstruo está entre el nivel 63 y 83, habrá una tabla donde dará cierto valor de experiencia u oro con una probabilidad de que dé más o menos. En cuanto a la experiencia, hay fija y porcentual. Cuando se da experiencia porcentual, esa experiencia corresponderá al nivel de la misión. Es decir, si hiciste la misión de nivel 5 y eres nivel 30, cuando reclames la recompensa dirá por ejemplo que recibiste el 10% de la experiencia, ese 10% es del nivel 5 y no 30. Imágenes: En el cliente se encuentran las imágenes de los monstruos y el fondo, que es un pergamino. Señales: Son las "burbujas" que aparecen en el mapa grande cuando estás viendo el monstruo seleccionado. Solo aparecerán en los monstruos que pertenezcan a las ciudades. En mapas neutrales no aparecerán señales. Precio de todo: 45 usd
  8. Hola a todos Voy a hablar sobre los event_flag que se inicializan cuando se enciende el servidor. Estos flags son muy importantes, ya verán por qué. Los event flag son banderas que influyen en todo el juego, al ser de tipo event son globales. Para que se entienda, cada vez que se activa un evento, el sistema cambia un valor de un flag de 0 a 1. Donde 0 es desactivado y 1 es activado. Claro que depende de la configuración del evento. Los flags a los que me refiero son estos: mob_dam user_dam user_dam_buyer mob_item mob_item_buyer mob_gold mob_gold_buyer mob_gold_pct mob_gold_pct_buyer mob_exp mob_exp_buyer mob_dam tiene una particularidad y es el único que no tiene par buyer. Buyer se refiere a Premium. 4 flags se refiere a los mismos bonus de los rates que son: drop de ítems, caída de Yang (fija), caída de Yang (en %) y experiencia. Mientras que mob_dam y user_dam corresponde al daño de los monstruos y de los jugadores. Todos los flags se inicializan en 100, que corresponde al 100%. Si queremos duplicar el valor, ponemos 200. Para cambiar el valor del flag hacemos esto en el juego: /e mob_dam 200 En este ejemplo, los monstruos atacarán el doble a TODOS los personajes del juego. La e corresponde a event_flag. Ejemplo con user_dam: Hay una guerra de reinos y todos tienen el daño muy alto. Si ejecutas el comando /e user_dam_buyer 50, todos los personajes de todo el juego (no solo los de la guerra), se sacarán la mitad del daño que suelen hacerse. Así mismo, si dejas el valor en 1, el daño de todos será demasiado reducido. Ejemplo con pruebas de testeo con monstruos fuertes: Si eres ADM y quieres matar monstruos rápido puedes hacer weake. Aunque si quieres matarlos bajando la vida completa, puedes cambiar el flag user_dam_buyer a un valor muy alto. El daño será demasiado alto. Debo decir que este comando es poderoso y muy escondido, y lo acabo de revelar. No quería pero me gusta compartir el conocimiento siempre y cuando lo tomen a beneficio. El problema es que si le dan acceso a un GM con este comando puede sabotear el juego, así que siempre restrinjan los comandos con los rangos de GM.
  9. He agregado un vídeo para entender mejor el evento.
  10. Hola Este post es sobre mi serie de misiones diarias donde voy a subir vídeos de unas misiones que hice hace unos días, con vídeo e información completa de configuración. Todas las quest son adaptadas a multiidiomas. Las misiones se reinician a las 00:00 hora del servidor. Si no aparece, cambia de personaje. Al reiniciar las misiones, tus valores se limpian y la quest crea nuevos. Es decir, si no acabaste la misión de hoy, a las 00:00 sale una nueva donde te pida algo nuevo. 1. Metines consecutivos Consiste en entregar cierta cantidad de cierto objeto a un NPC. Parámetros de configuración: Nivel requerido. Puedes configurar un nivel mínimo y un nivel máximo en que aparezca la misión. NPC. Puedes cambiar el vnum del NPC de la misión fácilmente. Ítems. Puedes agregar las listas objetos que pide el NPC. El sistema asigna solo un ítem con su cantidad y es elegido al azar de la lista. Cada lista tiene un nivel mínimo y nivel máximo, e incluso se pueden cruzar. En el archivo se entiende muy bien. Esto es para que no pida objetos de niveles altos a los niveles bajos. Recompensa. Al final de cada lista de objetos se agrega la cantidad del objeto recompensa que se ganará el personaje. Y en otro apartado aparece el vnum de ese objeto. En caso de que un objeto elegido por el sistema se combine con varias listas, se sacará el promedio de las cantidades del objeto recompensa. El objeto recompensa es uno solo, la cantidad varía según lo configurado.
  11. Hola Como he visto que muchos usan la base Wonder, WonderZ, Wonder2, WoM2, y todo lo que empiece por W, entonces quise hacer esta guía informativa sobre lo que necesitas preparar para tus quest. No voy a dejar todo masticado xD por eso la llamo informativa. Siempre recuerda hacer copia de todo. 1. Prepara una ruta fácil para llegar a tu carpeta quest desde la consola. Pasa muchas veces que tienes que ir a quest, map, germany, etc. y debes ir al WinSCP, buscar la ruta, copiarla y luego pegarla en la consola. Se pierde tiempo y haces pasos innecesarios. Lo que hago es crear un enlace simbólico (análogo al Acceso directo en Windows) de la carpeta quest y la pongo en la raíz. Esto solo lo tengo que hacer una vez. 2. Asegúrate que tengas Python para poder ejecutar el pre_qc.py. Debes tener instalado Python 2 o 3 porque esto nos servirá para ejecutar el pre_qc.py. El pre_qc.py es un archivo que hace pasos antes de pasar por el compilador. Estos pasos son validaciones y comodidades que nos da cuando vamos a compilar. 3. Debes tener tu pre_qc.py de Marty Sama con versión 2 o 3 de Python. Tu pre_qc.py debe ser de Python 2.7 o 3+. Esto se sabe dentro del archivo, ya que Marty Sama comenta el código. ¿Cuál es mejor? la verdad no hay diferencia si solo vamos a compilar, solo es la versión. 4. Debes preparar tu panel de administración para las quest. Solo si usas base Marty Sama, claro. O si tu servidor tiene el panel de admin. Sabes a lo que me refiero, es ese que tiene la opción de 777 para compilar las quest. Los Wonder compila las quest con make.sh que es obsoleto. Debes adaptarlo para que ejecute el pre_qc.py. Además con pre_qc.y de Marty Sama ya podrás compilar las quest con tokens define. 5. Usa un compilador que lea las variables en los when chat. El qc (quest compiler) que vienen en los Wonder no reconocen variables en los when chat. Es por esa razón que cuando revisas las quest, ves los botones del anillo teleport en inglés, mientras que en los demás textos say los ves en tu idioma. La solución es tomar otro qc. Aunque el qc de Wonder tiene comentado en el código fuente un abort donde se ejecuta cuando no encuentra funciones en el quest_functions, lo que quiere decir que cuando vayas a compilar las quest con 777 con tu nuevo qc, te va a pedir muchas funciones pero tampoco es un gran problema, solo las seleccionas de la consola y las pegas en el quest_functions. 6. Pon todas tus traducciones en diferentes archivos según el idioma. Los Wonder tienen el translate.lua con todas las variables en todos los idiomas. Es mejor tenerlo organizado y dejar un translate por cada idioma en una carpeta. Por ejemplo, translate_es.lua, translate_en.lua, translate_ro.lua, etc. 7. Compila quest por quest. Ya que es una base que no has construido tú mismo, es mejor que te asegures que todo ande bien, y para eso lo mejor es compilar quest por quest. Ha pasado muchas veces que una quest pide una función y no la encuentro por questlib.lua ni por el source game. Así que descubro que el sistema es incompleto y me ha tocado eliminarla. Revisar quest por quest hará que tengas el control sobre ellas. 8. Haz que funcione bien tus categorías de quest La base Wonder en la carpeta quest, archivo quest_category.txt, el que se encarga de asignarle la categoría de las quest (misiones principales, secundarias, etc.) de pergamino, tiene un problema, y es que no funciona. En el sistema de Quest Renewal hay una parte donde se lee quest_category.txt, pero al tener su origen Linux, solo leerá bien los archivos creados en Linux. Aunque el quest_category.txt en los Wonder fue creado en Windows, entonces no podrá leer bien los saltos de línea. Recuerda que con Windows los saltos de línea usan retorno de carro, así que van con /r/n. En cambio con Linux es solo el salto de línea /n. La solución es cambiar el salto de línea. Puedes hacerlo desde Notepad++ o creando un archivo desde tu WinSCP ya que es FreeBSD. Una vez hecho esto ya podrás ver tus quest de pergamino en cada categoría que le hayas asignado en el archivo, se ve chido. 9. Deja la codificación correcta en el questlib.lua Si vas a dejar tu servidor con el idioma español, es posible que declares variables con textos en el questlib.lua como las funciones de obtener el tiempo para que muestre horas, minutos, segundos. El questlib.lua en los Wonder viene por defecto con la codificación euc-kr (coreano) la original, y para que los textos se vean en el juego con tilde hay que dejar la codificación en ANSI. Se hace desde Notepad++. Adjunto captura
×
×
  • Create New...