Jump to content

Blesse

Miembro
  • Contador contenido

    7
  • Ingreso

  • Última visita

Actividad de reputación

  1. Me Gusta
    Blesse reacted to Croqueta in Funciones de Quests 90% de todos [español]   
    disculpanme por mi espanol, no e escrito mas que 11 anos :DD
    en espanol y para todos una data para cargar
     

    item.get_cell() no se tiene que escribir nada en las parentesis Beschreibung: -- gibt bei take und use das Aktuell benutzte Item aus. esplicasion: --para el "take" y "use" de el actual item volver: false wenn ein fehler aufgetreten ist ansonsten die Zellennumer im Inventar quando es false tienes que escojer un lugar del invantario item.select_cell(slot) selectiona el slot de el inventario esplicasion: --selectiona el item y ase que los comandos lo selectiona revolver: Boolean item.get_socket(socketid) sockel nummemero 0 asta 2 sockel0 hueco1 , sockel1 hueco2 ... asta 3 esplicasion: -- esa funcion qiere desir que te da el "id" del item que esta en el hueco revolver: false o el vnum del item item.remove(void) no se tiene que escribir nada en las parentesis esplicasion: -- borra el item selectionado revolver: nada item.get_id(void) no se tiene que escribir nada en las parentesis esplicasion: -- te da el id del item selectionado revolve: false o el id del item item.select(itemid) en las parentesis da el ID del item esplicasion: -- selectiona el item con el id y ase que los comandos lo selectiona revolve: Boolean item.get_count(void) no se tiene que escribir nada en las parentesis esplicasion: -- cuenta la cantidad de el selectionado item como 50 perlas revuelve: false o count item.get_level(void) no se tiene que escribir nada en las parentesis esplicasion: --te pregunta si el item es arma+1=1 devolver: +0= 0; +1=1 item.get_name(void) no se tiene que escribir nada en las parentesis revolver: nombre del item selectionado item.get_refine_vnum(void) no se tiene que escribir nada en las parentesis revolver: refined_vnum del item selectionado item.get_size(void) no se tiene que escribir nada en las parentesis revolver: tamaño del item selectionado -> en la database size item.get_sub_type(void) no se tiene que escribir nada en las parentesis revolver: subtype del item selectionado item.get_type(void) no se tiene que escribir nada en las parentesis revolver: type del item selectionado item.get_value(value) no se tiene que escribir nada en las parentesis revolver: el valor del item selectionado (value= value1 -> value5) item.get_vnum(void) no se tiene que escribir nada en las parentesis revolver: el vnum del item selectionado item.has_flag(flag) valor: flag esplicasion: -- chequa qual flag el item tiene revolver: Boolean item.set_socket(socketnum, value) valor: el numero del hueco y el valor que se qiera poner esplicasion: -- se pone en el hueco un item del selectionado item (sockelnum max =2) game.drop_item_with_ownership(item_vnum, anzahl) esplicasion: -- soltar objetos con su nombre ariba(el nombre se ve 10 segundos) game.drop_item(item_vnum, anzahl) esplicasion: -- solta un item __give_char_priv(rate_type, rate) esplicasion: -- le da el jugador selectionado un Bonus como yang, exp, caer objetos o yangbombas valor: rate_type = 1 asta 4 (YANG, DROP, YANGBOMB, EXP) rate= valor __get_empire_priv_string() esplicasion: -- le pregunta el actual bunus de un mondo en un string __give_empire_prive(empire, rate_type, rate, time) -- le da un mundo un bonus esplicasion: -- le da a 1 o a todo los mundos un bonus valor: rate_type= 1-4 (DROP, GOLD_DROP,TEN_GOLD_DROP, EXP) empire= 0-3 ; 0= todos los mundos __getnpcid(npc_name) esplicasion: -- te da el ID del npc si escribes el valor del npc is_test_server() esplicasion: -- te pregunta con un boolenvalor si es un testserver o no kill_all_in_map(mapindex) esplicasion: -- mata a todos los npc y monstros en la mapa puede ser que jugadores tambien valor: mapindex de la mapa bool_to_str() esplicasion: --transforma el boolinvalor en un string (si o no)("true" o "false") cmdchat(clientCMD) esplicasion: -- manda un comando en el chat channel del cliento se usa para abrir una tienda o para desir si el item fallo o esas cosas Wird genutzt für Sachen wie das öffnen eines Privaten Ladens oder die Meldungen beim Uppen command(cmd) esplicasion: -- como el comando "/" jugadores no pueden usar todos enable_over9refine(int, int) esplicasion: -- / valor: / regen_in_map(mapindex, path) esplicasion: -- carga la data de regen con el path y activa la en la mapindex de la mapa say_in_map(mapindex, text) esplicasion: -- como say pereo solo en la mapindex de la mapa (todos que esta en la mapa lo puede leer) set_quest_state(questname, state) esplicasion: -- pone en la quest un state y la activa(la quest con el nombre comienza) set_skin(skin_type) esplicasion: -- pone el estilo de la quest (como se ve en el juego) syschat(text) esplicasion: -- el texto que escribes se ve en el metin2 ventana para el jugador syserr(text) esplicasion: -- escribe en el chat algo falso de la quest si es un test_server time_to_str() esplicasion: -- da el actual tiempo en un string warp_all_to_village(mapindex, time) esplicasion: -- teleporta todo los jugadores en su mapa1 con el mapindex -- timer: da el tiempo que necesita para teleportar warp_to_village() esplicasion: -- teleporta el actual jugador en su mapa1 affect.add(applytype, applyvalue, time) esplicasion: -- te da un affect con el tipo 1000 asi se puede dar mas affect -- applytype son de 1 a 80 (los bonus ID) affect.remove() esplicasion: -- borra los affext type (223 no se puede borrar) Tip:210 = GM Stun 211 = GM Slow 203 = invisible 223 = chatbloc 500 asta 509 = EXP Bonus ... 514 = cabello 532 = caballo affect.remove_all_collect() esplicasion: -- borra todos los affect= bio quest affect affect.remove_bad() esplicasion: -- borra todos los negativos efectos como beneo, quemar ... affect.remove_good() esplicasion: --borry todos los positivos effectos como los buffs affect.remove_hair() esplicasion: -- borra el cabello building.get_land_id() -- te da el Id de el reino building.get_land_info() -- te da informasion de el reino building.has_land() -- tiene reino 0 o 1? building.set_land_owner() -- se pone el senor del reino char_log() -- escribe algo en el log tablo? clear_server_timer() -- borra el tiempo del server clearmapsignal() -- borra el punto de la map cleartimer() -- borrar el timer color(r,g,b) -- color rgb complete_quest() -- cierra la quest complete_quest_state() -- complete sate confirm() -- confirmar si no? sys_log() -- escribe algo en el system log? d.check_eliminated() -- controla si todos los monstros estan eliminados solo en los dungeons. d.clear_regen() -- para los respawns en los dungeons. d.count_monster() -- cuenta los monstros en el dungeon d.exit() -- jugador sale del dungeon d.exit_all() -- todos los jugadores salen del dungeon d.exit_all_to_start_position() -- todos enpiezan de start d.get_kill_mob_count() -- te da un numero de los eliminados monstros en el dungeon d.get_kill_stone_count() -- te da un numero de los eliminados metins en el dungeon d.get_map_index() -- Dungeon Map Index d.getf() -- Dungeon Flag d.is_unique_dead() -- se murio algien? d.is_use_potion() -- uso uno un pott? d.join() -- entrar un gruppo en el dungeon d.jump_all() -- teleportart todos a un punto de el Dungeon d.jump_all_local() -- teleporta todos local en el dungeon d.kill_unique() -- murio solo uno? d.new_jump() -- nuevo Warp d.new_jump_all() -- todos los jugadores teleportan de nuevo. d.purge() -- borrar todos los monstros en el dungeon como(/purge) d.purge_unique() -- uno o unos monstros borrarlo en el dungeon d.regen_file() -- cargar el regen file de monstros del dungeon d.revived() -- revivido d.select() -- selectionar el dungeon d.set_dest() -- pone un fin al dungeon d.set_exit_all_at_eliminate() -- cuando un enemigo murio todos salen del dungeon d.set_regen_file() -- pone el regen file del dungeon d.set_unique() -- pone solo uno en el Dungeon d.set_warp_at_eliminate() -- teleporta cuando enemigo murio d.setf() -- pone a el dungeon una flag d.spawn() -- llama un monstro en el dungeon d.spawn_goto_mob() -- llama un monstro en el dungeon y te teleportas donde el esta d.spawn_group() -- llama un grupo en el dungeon d.spawn_mob() -- llama un mostro en el grupo d.spawn_move_group() -- llama un grupo y move? d.spawn_move_unique() -- llama un monstro y move? d.spawn_name_mob() -- llama un monstro con nombre? d.spawn_stone_door() -- llama una puerta de piedra d.spawn_unique() -- llama uno d.spawn_wooden_door() -- llama una puerta de madera d.unique_get_hp_perc() -- te da el nombre de un monstro o jugador no se d.unique_set_def_grade() -- poner la defensa de un monstro o jugador d.unique_set_hp() -- poner la vida de un monstro o jugador no se d.unique_set_maxhp() -- poner maximal vida de un monstro o jugador no se delay() -- esperar find_npc_by_vnum() -- buscar un npc con el vnum find_pc_by_name() -- burca un jugador con el nombre find_pc_cond() -- buscar un jugador que tiene la condicion game.drop_item() -- soltar objetos game.get_event_flag() -- preguntas por el event_flag game.get_guild_name() -- preguntas por el nombre de gremio game.get_safebox_level() -- preguntas por el tamano de eö almacen game.get_warp_guild_war_list() -- te da la lista de gremio guerra game.open_mall() -- abrir el itemshop almacen game.open_safebox() -- abrir el almacen game.request_make_guild() -- te pregunta die qieres aser un gremio game.set_event_flag() -- pone el event_flag game.set_safebox_level() -- poner el tamano del almacen get_global_time() -- pone el global timepo get_locale() -- te da la selectionada locale get_server_timer_arg() -- te da el servertimer get_time() -- te da el tiempo guild.around_ranking_string() -- te da el guild ranking en uns string guild.get_any_war() -- te da todos los gremios que estan en guerra guild.get_ladder_point() -- te da los puntos del lider guild.get_name() -- te da el nombre del gremio guild.get_rank() -- te da el rank del gremio guild.get_reserve_war_table() -- lista de guerra guild.get_warp_war_list() -- liste de guerra warplist guild.high_ranking_string() -- Highscore al String (gremio) guild.is_bet() -- se aposto al el gremio? guild.is_war() -- preguntar si el gremio entra en guerra guild.level() -- pregunta qual nivel el gremio tiene guild.name() -- te da el nombre del gremio guild.war_bet() -- posta al gremio de guerra guild.war_enter() -- entrar en guerra con el gremio horse.advance() -- poner el caballo 1 lvlup horse.feed() -- darle el caballo algo de comer horse.get_grade() -- darle el rank del caballo horse.get_health() -- darle vida a el caballo horse.get_health_pct() -- vida de caballo en por cineto horse.get_hp() -- te da la vida de el caballo horse.get_level() -- te da el nivel del caballo horse.get_stamina() -- te da el sp del caballo (resistencia) horse.get_stamina_pct() -- t da el sp del caballo en por ciento horse.is_dead() -- el caballo esta muerto? horse.is_mine -- es mi caballo horse.is_riding() -- estoi ariba del caballo horse.revive() -- revivir el caballo horse.ride() -- monatar el caballo horse.set_level() -- poner el nivel de el caballo horse.summon() -- llamar el caballo horse.unride() -- decmontarse del caballo horse.unsummon() -- retirar el caballo input() -- input donde puedes escribir algo is_test_server() -- te pregunta soe es un testserver loop_timer() -- Loop Timer npc.is_quest() -- pregunta si un npc esta usado en una quest pc.change_gold() -- cambiar el yang pc.change_money() -- cambiar el yang pc.change_sp() -- cambiar el sp pc.changealignment() -- cambiar el rango pc.changegold() -- cambiar el yang pc.changemoney() -- cambiar el yang pc.clear_skill() -- borrar habilidad pc.clear_sub_skill() -- borrar sub habilidad pc.clear_one_skill() -- borrar una habilidad pc.count_item() -- contar un item del jugador pc.countitem()-- contar un item del jugador pc.delqf() -- borrar lo que esta en la quest tabale pc.destroy_guild() -- borrar el gremio pc.enough_inventory() -- controla si en el inventario ai espacio pc.forget_my_attacker() -- el monstro no te ataquea pc.get_armor() -- te da la armadura que usas pc.get_empire() -- te da el mundo en que estas pc.get_equip_refine_level() pc.get_exp() -- el exp que tienes en momento pc.get_gold() -- el yang que tienes en momento pc.get_guild() -- el gremio que estas en momento pc.get_horse_level() -- el nivel de tu caballo pc.get_hp() -- la vida que tienes en momento pc.get_job() -- tu categoria ninja, sura... pc.get_leadership() -- el lider pc.get_level() -- el nivel que tienes en momento pc.get_local_x() -- tu coordinacion x pc.get_local_y() -- tu coordinacion y pc.get_map_index() -- map index pc.get_max_hp() -- max hp del jugador pc.get_max_sp() -- max sp del jugador pc.get_money() -- el exp del jugador en momento pc.get_name() -- nombre del jugador pc.get_next_exp() -- cuanto exp para lvl up pc.get_part() pc.get_playtime() -- tiempo del jugador pc.get_sex() -- sexo del jugador pc.get_skill_level() -- habilidad nivel pc.get_sp() -- sp del jugador en momento pc.get_start_location() pc.get_vid() pc.get_war_map() pc.get_weapon() -- arma del jugador pc.get_x() pc.get_y() pc.getarmor() pc.getcurrentmapindex() pc.getempire() pc.getf() pc.getgold() pc.getguild() pc.gethp() pc.getleadership() pc.getmaxhp() pc.getmaxsp() pc.getmoney() pc.getname() pc.getplaytime() pc.getqf(name) pc.get_skill_group() pc.getsp() pc.getweapon() pc.getx() pc.gety() pc.give_exp(exp) pc.give_exp2(exp) pc.give_exp_perc(percent) pc.give_gold(gold) pc.give_item(vnum)-- te da el rango revuelvo pc.give_item2(vnum) -- le das un item (vnum) pc.give_item_from_special_item_group(is_item?) pc.give_lotto() pc.has_guild() -- es en un gremio si(1)o no(0) pc.has_master_skill() -- tienes algo en M1 si(1) o no(0) pc.hasguild() -- es en un gremio si(1)o no(0) pc.have_map_scroll() pc.have_pos_scroll() pc.in_dungeon() -- es en un dungeon si(1) o no(0) pc.is_guild_master() -- es el lider del gremio si(1) o no (2) pc.is_horse_alive() -- el caballo bive si(1) o no(0) pc.is_married() -- esta casado si(1) o no(0) pc.is_mount() -- esta monteado pc.is_polymorphed() -- transformado si(1) o no(0) pc.isguildmaster() -- es el lider del gremio si(1) o no (2) pc.mount(vnum,time) -- montar al caballo (vnum, tiempo) 60*60*24*.. (segundos*minutos*horas*dias*semanas*meses*anos) pc.pc_attract_ranger() -- distancia pc.polymorph(mob_vnum) -- transformar el jugador pc.refine_equip() -- mejorar el objectivo pc.remove_from_guild() -- borrar un jugador de gremio pc.remove_item(item_vnum) -- borrar un item del inventario pc.remove_polymorph() -- revolver la transformasion pc.removeitem() -- borrar un item del inventario pc.reset_point() -- borrar puntos de status? pc.revive_horse() -- revivir el caballo pc.select() -- selectional pc.set_part() -- poner un part como cabello pc.set_warp_location() pc.set_warp_location_local() pc.setf() -- lo mismo como setqf pc.setqf(name,value) pc.set_skill_group() --cambiar la clasificion pc.set_skill_level() -- cambiar la nivel de habilidad pc.unmount() -- demontarse pc.warp() -- teleportarse pc.warp_exit() -- teleportarse para salida pc.warp_local() -- teleportarse local como Tele-Hack pc.warp_to_guild_war_observer_position() -- teleportarse para el npc de gremio pc.is_clear_skill_group() pc_find_skill_teacher_vid() -- clasicasion de maestro pc_find_square_guard_vid() pc_get_exp_bonus() --te da el exp bonus pc_get_village_map_index() -- te da el mapindex de mapa1 pc_is_novice() -- si el jugador es principante no mas que 15 y no menos que 5 raw_script() restart_quest() -- se pone el state de la quest a start say() -- simple [sAY] say_npc_name() -- dise el nombre del npc say_pc_name() -- dise el normbre del jugador say_reward() -- dise un texto en rojo say_title() -- dise el titulo say_item() -- dise el nombre del item say_item_vnum()--ensena el item con imagine select() -- para selectionar optiones target.clear() target.delete() target.id() target.npc() target.pc() target.pos() target.vid() test_chat() time_hour_to_sec() time_min_to_sec() type() pc.is_engaged() -- esta el jugador casado string.format() pc.is_gm() -- es el jugador un gm si(1) no (2) pc.get_gm_level() -- qual nivel tiene el gm implemen.. pc.get_alignment() -- cambia el rango del jugador pc.get_real_alignment() -- cambia el rango a normal pc.learn_grand_master_skill() -- poner la habilidad a G1 o P (sube siempre a 1) pc.is_skill_book_no_delay() -- si el jugador uso una exxo si(1) no(2) pc.remove_skill_book_no_delay() -- borra el efecto de exxo

    Debes iniciar sesión para ver el contenido del enlace en esta publicación.
  2. Me Gusta
    Blesse reacted to Santy!. in Explicasion errores generales que marca el syser   
    Solo para este foro.
     
    Hola buenas a todos a pedido de kohaku are este post explicando un poco el syser y a solucionar sus problemas mas principales.
     
    antes de nada debemos saber que el syser:
    el syser es el registro de los channel donde se marcaran errores del servidor.
     
    ¿Donde lo podemos localizar?
     
    bueno el se localizara en la siguiente ruta:
     

    cd /home/game/channel1 cd /home/game/channel2 cd /home/game/game99 cd /home/game/g1/db cd /home/game/g1/auth claramente esta el de channel 1 registrara los de dicho canal.
     
    Errores mas comunes:
     
     

    SYSERR: Aug 17 21:09:04 :: GetMotionFileName: Motion: boar2 have not motlist.txt vnum(20115) folder(boar2) este error dice que que bicho 20115 no tiene movimiento como os solucionaremos fácil accedemos a navicat tabla player mob_proto 1 ves hay buscamos el mob 20115 y en aiflag debemos seleccionar el tipo de movimiento que le daremos puede ser agresivo, atak con movimiento, sin movimiento, etc obviamente al lado de aiflag hay mas columnas llamadas set_race_flag, etc fíjense de rellenar esas correctamente.
     
    siguiente error:
     
     

    SYSERR: Aug 17 22:09:52 :: SpawnMob: SpawnMob: no mob data for vnum 10828 SYSERR: Aug 17 22:09:52 :: regen_load: No mob data by vnum 10829 esto dice que no se recibe data de el mob 1089 lo solucionamos de la misma manera nos fijamos que en el mob_proto del navicat estén todas las columnas correctamente.
     
    siguiente:
     
     

    SYSERR: Jul 17 20:40:00 :: ChildLoop: AsyncSQL: query failed: Unknown column 'vnum' in 'field list' (query: INSERT DELAYED INTO log (type, time, who, x, y, what, how, hint, ip, vnum) VALUES('ITEM', NOW(), 0, 1, 0, 90001178, 'SET_SOCKET', '', '', 3090) errno: 1054) Según collado metemos esta query en log:
     

    -- ---------------------------- -- Table structure for `log` -- ---------------------------- DROP TABLE IF EXISTS `log`; CREATE TABLE `log` ( `ID` int(11) DEFAULT NULL, `type` varchar(20) COLLATE big5_bin DEFAULT NULL, `time` datetime DEFAULT NULL, `who` int(11) DEFAULT NULL, `x` int(11) DEFAULT NULL, `y` int(11) DEFAULT NULL, `what` int(11) DEFAULT NULL, `how` varchar(20) COLLATE big5_bin DEFAULT NULL, `hint` varchar(20) COLLATE big5_bin DEFAULT NULL, `ip` varchar(30) COLLATE big5_bin DEFAULT NULL, `vnum` int(50) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=big5 COLLATE=big5_bin; -- ---------------------------- -- Records of log -- ---------------------------- siguiente:
     

    SYSERR: Aug 17 22:51:01 :: socket_connect: HOST localhost:15000, could not connect. SYSERR: Aug 17 22:51:02 :: hupsig: SIGHUP, SIGINT, SIGTERM signal has been received. shutting down. SYSERR: Aug 17 22:51:02 :: socket_block: fcntl: nonblock: Bad file descriptor SYSERR: Aug 17 22:53:33 :: socket_connect: HOST 220.95.239.40:7120, could not connect. SYSERR: Aug 17 22:53:33 :: heart_idle: losing 75 seconds. (lag occured) solo lag borrar logs
    siguiente:
     
     
     

    SYSERR: Aug 17 23:53:22 :: DirectQuery: AsyncSQL::DirectQuery : mysql_query error: Column 'name' in field list is ambiguous query: SELECT pid, name, date FROM monarch_candidacy a, player b where a.pid = b.id aqui tenemos mal la tabla monarca
     
    [02:00:24 p.m.] .Angel Collado: lo de monarca tiene solucion modificando el archivo db o la tabla monarch
    [02:00:35 p.m.] .Angel Collado: en mi virtual cambie lo de db y no me ha dado error ninguna vez as
    [02:00:36 p.m.] .Angel Collado: mas*
     
    siguiente:
     

    SYSERR: Aug 17 21:16:26 :: ChildLoop: AsyncSQL: query failed: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) (query: REPLACE INTO quest (dwPID, szName, szState, lValue) VALUES(1, 'event_map', '__status', -2107478168) errno: 2002) SYSERR: Aug 17 21:16:26 :: ChildLoop: AsyncSQL: retrying en esta nos esta fallando la conexion a mysql.
     
    Bueno ahora ya saben un poco mas de estos feos errores que tantos dolores de cabeza nos dan que tengan suerte!
     
    Agradecimiento: collado.
  3. Me Gusta
    Blesse reacted to KeKo in Nuevo subforo: Creacion de quests   
    Hola a todos, como os habreis fijado hay un nuevo subforo dentro de la seccion quests.
     
    Este nuevo subforo es una iniciativa de ElRaulxX y mia (KeKo) en el que haremos un curso de creacion de quests para que todos podais aprender sobre el lenguaje lua, que (modificado para metin2) es el que se usa en la quests, y que podais editar, entender y crear quests.
     
    El curso se compondrá de una serie de capítulos en los que raul y yo os iremos desentrañando los interesantes misterios del mundo de las quest de metin2 :acepted:
     
    Dentro de poco publicaremos el primer capítulo del curso, y esperamos que a todos os guste el nuevo subforo y os sea útil.
     
    Un saludo, raul y keko.
  4. Me Gusta
    Blesse reacted to ElRaulxX in Capí­tulo V - Los states   
    Buenas foreros de Metin2 Zone!
    Os vengo a traer la quinta entrega de nuestro fantástico curso de quests. En este capítulo trataremos los states, algo básico que tenéis que tener en cuenta a la hora de crear una quest. La verdad es que esto formaría parte del capítulo II, pues los states estructuran las quests, pero hemos aplazado este capítulo para que lo podáis entender mejor ahora que ya habéis avanzado un poco.

    Supongo que habréis visto ya en todas las quests la estructura state start begin. Efectivamente, eso es un state. Pero antes de todo debemos entender qué es realmente un state.


    1 - ¿Qué es un state?

    Podríamos decir que un state es la "división" de una quest. Las acciones de cada quest se dividen en bloques independientes: los states.
    Cuando el usuario inicia la quest empezará en el state inicial (start). A partir de entonces el creador de la quest puede ir cambiando de states a su conveniencia. De esta manera podemos hacer que el usuario sufra diferentes acciones en cada uno de los states.
    Algo importante a saber es que los states son totalmente independientes los unos de los otros. Las acciones que ocurren dentro de un state sólo ocurrirán en este state, es decir, cuando el usuario se encuentre dentro de este state.

    Un ejemplo, para que lo entendáis, son las misiones de búsqueda de un npc o de matar un determinado mob, las misiones de toda la vida que utiliza ymir. Cuando empieza la quest aparece un determinado pergamino. Conforme vamos avanzando la quest, este pergamino irá cambiando; en un state podemos abrir un determinado texto en un npc, en otro no. Esto no lo podríamos hacer sin nuestros states.
     
    Podemos entender mejor los states si los comparamos con un conjunto de habitaciones unidas a través de puertas.
    Empezamos entrando a la primera habitación (state start - inicio de la quest). En ella nos encontramos una alfombra y una silla. Por lo tanto podemos caminar sobre la alfombra y sentarnos en la silla. Ahora decidimos ir a una segunda habitación.
    En esta segunda habitación nos encontramos un sillón y una mesa. En esta habitación podemos sentarnos en el sillón y poner una baso sobre la mesa, pero no podemos caminar sobre la alfombra ni sentarnos en la silla ya que eso pertenece a la habitación anterior.
    De esta manera podemos entender los states. Cada state es independiente de los otros; podemos realizar las acciones que se encuentran dentro de un state independientemente de los otros. Para cambiar de state deberemos atravesar una puerta que, en términos de quest, correspondería a una función para cambiar el state en que se encuentra el usuario.

    Una quest puede tener un número indeterminado de states. Eso, como ya dije, va a conveniencia del creador de la quest.
    Cuando compilemos la quest (implementamos en el servidor) aparecerá en object la quest dividida/fragmentada. Esa división será en función de los states. Por ejemplo, si implementamos la quest tutorial.quest que contiene los states start, run y final, en object nos aparecerán los archivos tutorial.start, tutorial.run y tutorial.final (todo dividido en mobs, timers..., claro está). Esto lo trataremos a fondo en otro capítulo.


    2 - ¿Cómo cambiamos de state?
     
    El state del jugador puede cambiarse a partir de funciones creadas para ello.
    Los states se almacenan en la db y permanecerán hasta que sea modificado con cualquiera de las funciones creadas para ello.
    Existen dos maneras de cambiar un state: internamente o remotamente.
     
    Internamente:
    La función de cambio de state principal es la función set_state() o setstate(). Su uso es muy sencillo: tan solo debemos introducir como único argumento el nombre del state al que queremos cambiar cuando queramos realizar el cambio de state interno de la quest (por si no se entiende, entre paréntesis tenemos que poner el nombre del state al que queremos ir).
    set_state(string $state) Ejemplo:
    quest tutorial begin state start begin when 9012.chat."Aprendamos los states 1" begin say("Actualmente te encuentras en el state start") say("¿Quieres cambiar de state?") local s = select("Si","No") if s == 1 then say("Has cambiado de state correctamente") set_state("run") end end end state run begin when 9012.chat."Aprendamos los states 2" begin say("Actualmente te encuentras en el state run") say("¿Quieres cambiar de state?") local s = select("Si","No") if s == 1 then say("Has cambiado de state correctamente") set_state("start") end end endend Como veis en el ejemplo, cada state es independiente de los otros.
    También debo recordar que TODOS los states se cierran con un end.
    Los states pueden tener cualquier nombre, el que queramos. Aún así, para evitar cualquier tipo de error, es aconsejable utilizar nombres sencillos sin caracteres especiales.

    Remotamente:
    Los states de una quest también podemos cambiarlos remotamente, es decir, desde otra quest ajena. ¿Cómo hacemos eso? Pues con la función: set_quest_state(). Esta función toma dos argumentos: el primer argumento debe ser el nombre de la quest a la que queramos cambiar el state (IMPORTANTE: el nombre de la quest es el definido en la primera línea quest x begin donde x es el nombre de la quest; no confundir con el nombre del archivo quest) y el segundo el nuevo state al que queremos ir.
    set_quest_state(string $quest, string $state) Ejemplo:
     
    Quest1:
    quest tutorial1 begin state start begin when 9012.chat."Aprendamos los states 1" begin say("Actualmente te encuentras en el state start") end end state run begin when 9012.chat."Aprendamos los states 2" begin say("Actualmente te encuentras en el state run") end endend Quest2:
    quest tutorial2 begin state start begin when 9012.chat."Aprendamos los states - cambiar state" begin say("¿A que state quieres cambiar?") local s = select("start","run") if s == 1 then say("Has cambiado de state correctamente") set_quest_state("tutorial1", "start") elseif s == 2 then say("Has cambiado de state correctamente") set_quest_state("tutorial1", "run") end end endend 3 - States en los when - enter y leave
     
    Existen dos maneras de activar un when a través de los states: enter y leave.
    Enter: Se ejecutará el when cuando entremos en el state. Leave: Se ejecutará el when cuando salgamos del state. A través de estos dos whens podemos aumentar mucho la funcionalidad de una quest en las ocasiones en que podamos cambiar los states.
    He visto programadores quest que utilizan mucho esta táctica para conseguir solucionar problemas que de otra manera serían mucho más difíciles de solucionar, ¡incluso lo utiliza nuestra madre ymir!
     
    Aquí tenéis un ejemplo explicativo:
    quest tutorial begin state start begin when 9012.chat."Aprendamos los states - 1" begin say("¿Realmente quieres cambiar de state?") local s = select("si","no") if s == 1 then say("Has cambiado de state correctamente") set_state("run") end end end state run begin when enter begin chat("Has entrado al state.") end when leave begin chat("Has salido del state.") end when 9012.chat."Aprendamos los states - 2" begin say("¿Realmente quieres cambiar de state?") local s = select("si","no") if s == 1 then say("Has cambiado de state correctamente") set_state("start") end end endend Cuando entremos al state run se ejecutará chat("Has entrado al state.") y cuando salgamos del mismo chat("Has salido del state."). Este ejemplo es muy sencillo pero estoy seguro que de aquí os pueden salir grandes ideas que mejorarán mucho vuestro código.
     
     
     
    Con todo esto podemos ir jugando con los states y hacer miles de cosas.
    Algo muy útil es poner un state sin ninguna acción. Así podemos dar por finalizada la quest, ¡muy útil para quests con recorrido!
    Recordar que los states es lo principal de las quest. Si sabéis utilizarlos serán buenos aliados, sino tan solo serán neutrales. Siempre es mejor tener aliados, ¿no creéis?
     
     
    Changelog
    31/07/12 20:18 - Primera publicación oficial del capítulo. 04/09/13 11:35 - Correcciones varias. 04/09/13 14:33 - Correcciones varias. 04/09/13 15:31 - Correcciones varias, Añadida sección 3 - States en los when - enter y leave
  5. Me Gusta
    Blesse reacted to KeKo in Capitulo IV - Profundicemos en las condiciones   
    Buenas zone!
    De nuevo tras otro emocionante capítulo del curso brindado por el gran raul es mi turno de seguir con el curso. El capítulo de hoy tratará sobre las condiciones en las quests, lo que popularmente conoceis todos como usar if en una quest.
     
    Esta vez también nos vamos a centrar en el cuerpo de una quest, y como mi colega raul empezare con la estructura básica de un if. Recordad esto primero:
     
    De nuevo la idea es la misma que con los whens:
     
     
     
    Por lo tanto la estructura es asi:
     

    if [X] then accion end Como veis cada if le corresponde un end y para que nos os de error al cargar tiene que ir un then al final del if, si no os saltara este error:
     

     
    Bien si ya tenemos claro la estructura vamos a profundizar un poco en el uso de las condiciones. Lo primero de todo me gustaría hacer una pequeña distinción entre varios tipos de condiciones:
     
    - Condiciones simples: Son aquellas que solo tienen un unico if (con sus posibles elseifs).
     
    - Condiciones compuestas: Son aquellas que se dan en las quests en las que si superamos la primera condicion se nos pone otra condición. Ojo! Son 2 condiciones diferentes, que llevan dos if y dos ends.
     
    - Condiciones opuestas: Que son las que usan habitualmente un else, o si no un return+end (ya os explicare como funcionan en el capi), y que son aquellas en las que ponemos una condicion y lo que pasara si se cumple lo contrario a esa condicion.
     
    Bueno vamos aver un pequeño ejemplo de una quest que usa una condicion:
     

    quest capicuatro begin state start begin when login with pc.get_map_index() == 41 begin if pc.get_empire() == 1 then say("No estas en el mapa de tu reino") end end end end Hasta aquí todo bien no? Como veis es una quest que se activa si te logeas en el mapa de city1 de jinno, pero te pone la condicion de que si eres del reino 1 (shinsoo) te aparece un mensaje diciendo que no estas en el mapa de tu reino.
     
    Respecto a los ends, como hay un if lleva un end y los otros tres son del when y de la apertura.
     
    Por lo tanto hagamos un resumen: cuando quieres poner una condicion en una quest primero pones el when [X] begin al que queremos ponerle la condicion, luego escribimos la condicion en si, la accion que se realiza una vez cumplida la condicion y el end.
     

    if [X] then accion end  
    Ahora pongamos otro ejemplo con esta misma mision pero ya con algunos elseif:
     

    quest capicuatro begin state start begin when login with pc.get_map_index() == 41 begin if pc.get_empire() == 1 then say("No estas en el mapa de tu reino") elseif pc.get_empire() == 2 then say("No estas en el mapa de tu reino") elseif pc.get_empire() == 3 then say("Estas en el mapa de tu reino!") end end end end Ahora ya tenemos 3 condiciones, pero como os fijais solo 1 lleva if, ya que son continuacion de la primera y por lo tanto solo llevan un end por las tres.
     
    Y también otro ejemplo del uso de un elseif, con un local select que es cuando mas vais a ver un elseif:
     

    quest capicuatro begin state start begin when 70042.use begin say_title("Tienda portatil") say("Con este objeto podras comprar") say("Potas donde quiera que estes.") say_reward("Quieres algunas?") local tienda = select ("Potas rojas" , "Potas azules" , "Superpotas" , "Cerrar") if tienda == 1 then say("Toma 200 potas rojas") pc.give_item2("27003", 200) pc.change_money(-30000) elseif tienda == 2 then say("Toma 200 potas azules") pc.give_item2("27006", 200) pc.change_money(-45000) elseif tienda == 3 then say(" Usted ha sido trolleado") say("no hay superpotas") elseif tienda == 4 then return end end end end  
     
    A estas alturas ya os habreis dado cuenta de como funciona el uso de un elseif:
     

    if [X] then accion elseif [X] then accion elseif [X] then accion end Al igual que cuando usabamos un solo if, ponemos el when [X] begin, luego la condicion if [X] then y esta vez las otras posibilidades que queremos que haya unidas al primer if [X] then (podemos poner las que queramos) con la estructura elseif [X] then. Por último cerramos el if con un end.
     
    Vayamos ahora a un caso de condicion compuesta, por ejemplo un teletransportador para un mapa:
     

    quest capicuatro begin state start begin when 20095.chat."Teleporter" begin if pc.get_level() < 50 then say("Lo siento eres muy bajo") say("vuelve cuando seas mas lvl") return end if pc.count_item("50084") == 0 then say("Valla, no tienes sello") say("Asi que no puedes entrar") return end if pc.get_map_index() == 190 then say("No puedes ir al mapa nuevo") say("Si ya estas en el") return end say("Pues lo siento ahora no quiero") say(" llevarte al mapa nuevo.") end end end Ahora en vez de usar condiciones unidas a la primera (el if [X] then) ponemos diferentes condiciones, cada una de estilo if [X] then y con su respectivo end.
     
    Usando las condiciones compuestas conseguimos que para llegar a la accion propia del when [X] begin haya que ir cumpliendo cada una de las condiciones. Es decir, si cumplimos la primera condicion el juego mirará aver si cumplimos la segunda.
     
    Si no cumplimos la segunda no se ejecutará, y si la cumplimos mirará aver si cumplimos la tercera. Si cumplimos todas las condiciones, la accion principal se ejecutará.
     
    Otra cosa a tener en cuenta es que podemos meter condiciones dentro de otras condiciones, y para eso os pondré un ejemplo en el que mezclaré condiciones simples con condiciones opuestas (hare mas compleja la quest de antes de las potas):
     

    quest capicuatro begin state start begin when 70042.use begin say_title("Tienda portatil") say("Con este objeto podras comprar") say("Potas donde quiera que estes.") say_reward("Quieres algunas?") local tienda = select ("Potas rojas" , "Potas azules" , "Superpotas" , "Cerrar") if tienda == 1 then if pc.gold < 30000 then say("Vaya no tienes suficiente dinero") return end say("Toma 200 potas rojas") pc.give_item2("27003", 200) pc.change_money(-30000) elseif tienda == 2 then if pc.gold < 45000 then say("Vaya no tienes suficiente dinero") return end say("Toma 200 potas azules") pc.give_item2("27006", 200) pc.change_money(-45000) elseif tienda == 3 then say(" Usted ha sido trolleado") say("no hay superpotas") elseif tienda == 4 then return end end end end end Ahora hemos metido una condición dentro de otra: primero metemos la condicion de elegir la opcion 1 (la de potas rojas) y luego dentro de esa hacemos que el juego mire si tenemos 30k para comprar las potas.
     
    Os habreis fijado que ahi usamos una condición opuesta:
     

    if pc.gold < 45000 then say("Vaya no tienes suficiente dinero") return end say("Toma 200 potas azules") pc.give_item2("27006", 200) pc.change_money(-45000) Ponemos la condicion:
     

    if pc.gold < 45000 then Luego lo que pasa si la cumplimos:
     

    say("Vaya no tienes suficiente dinero") Y para cerrar la condicion ponemos:
     

    return end De esta manera, lo siguiente que pongamos se cumplirá EN CUALQUIER CASO EN EL QUE NO CUMPLAMOS LA CONDICION ANTERIOR. Y como veis si tenemos mas de 45k de yang (es decir, no cumplimos la condicion) pues nos da las potas:
     

    say("Toma 200 potas azules") pc.give_item2("27006", 200) pc.change_money(-45000) Para acabar me gustaría hablarlos de la palabra else. Esta palabra se utiliza para hacer una condicion opuesta, ya que implica que si la cumplimos estará pasando cualquier cosa contraria a la de la condicion anterior. Veamos un ejemplillo, y os recalco que UN ELSE NO TIENE QUE LLEVAR SU CORRESPONDIENTE END.
     

    quest capicuatro begin state start begin when 70044.use begin if pc.count_item("70042") == 0 then pc.give_item2("70024", 1) chat("Toma un 5o bonus") pc.remove_item("70024" , 1) else say("Lo siento pero ya tienes") say("el 5o bonus") end end end end En este caso la condicion primera es que no tengamos ningun 5o bonus en el inventario, y si no la cumplimos (es decir, si que tenemos 5o bonus) pues nos dice que ya lo tenemos. Como usamos un else no especificamos una cantidad de bonus que tenemos que tener, si no que en cualquier caso contrario a que no tengamos ninguno nos dirá que sí lo tenemos.
     
    Y bueno eso es todo en el capítulo de hoy, espero que lo hayais disfrutado y que os ayude a la hora de hacer nuevas quests .
  6. Me Gusta
    Blesse reacted to ElRaulxX in Capítulo III - Profundicemos en los Whens   
    En el anterior capítulo, keko os explico más o menos como podemos estructurar una quest. En este capítulo nos centraremos en el cuerpo, exactamente en los whens.
    El uso de los whens es lo más básico dentro de una quest. A partir de aquí podremos desarrollar cualquier acción de una quest.
     
    Estructura básica de un when.
     
    Antes de todo, tenemos que recordar la estructura de un when:

    when [x] begin -- end *Esta es la estructura básica. Podemos añadirle muchísimas más cosas que explicaré en este capítulo, pero de momento, no nos avancemos. Llamaremos [x] a una variable que nos sirva para todos los casos. 
    ¿Qué pasaría si no siguiéramos esta estructura? Pues que nos saltaría este error:
     

     
    Debéis recordar siempre que todos los whens siguen esa estructura. Sino, no funcionará y no la reconocerá el servidor.
     
    Pero como la variable [X] que nos hemos inventado no existe, tendremos que poner algo en su lugar, ¿no?
    Podemos poner muchas acciones que puede realizar el usuario (pc) dentro del servidor.
    Voy a listarlas todas (o casi todas). Las pondré en orden de uso y dificultad. Es posible que algunas de ellas ahora no les encontréis utilidad en este momento. Es recomendable que dentro de un tiempo las volváis a repasar para acabar de entenderlas y poder darles su debido uso.
     
    *Lo que está en cursiva puede ser sustituido.
    idnpc.chat."texto" : Al utilizarlo se abrirá un dialogo con opciones. Al dar click al texto empieza el contenido del when.
    idnpc.click : Al hacer click en el npc, empieza el contenido del when.
    kill : Cuando el jugador mata un enemigo, comienza el contenido del when.
    idmob.kill : Cuando el jugador mata al enemigo con idmob empieza el contenido del when.
    party_kill : Cuando un miembro del grupo mata a un enemio, comienza el contenido del when.
    idmob.party_kill : Cuando un miembro del grupo mata a aun enemigo con idmob, empieza el contenido del when.
    login : Cuando el jugador se logea, empieza el contenido del when.
    logout : Cuando el jugador se deslogea, empieza el contenido del when.
    letter : Relacionado con las letters (explicación en otro capitulo).
    button : Relacionado con las letters (explicación en otro capitulo).
    info : Relacionado con las letters (explicación en otro capitulo).
    nombre.timer : Cuando el timer llamado con nombre llega a 0, empieza el contenido del when.
    nombre.server_timer : Cuando el server_timer llamado con nombre llega a 0, empieza el contenido del when.
    nombre.target.click : Cuando haces click al tarjet nombre empieza el contenido del when.
    nombre.target.arrive : Cuando llegas al punto con el tarjet nombre empieza el contenido del when.
    ( )
     
    Unos cuantos ejemplos:

    quest cap3_1 begin state start begin when login begin --cuando te logeas say("¡Hola mundo!") -- muestra en dialogo end end end quest cap3_2 begin state start begin when 9012.chat."Quest de prueba" begin --cuando hablas con el npc 9012 say("¡Hola mundo!") --muestra en dialogo end end end quest cap3_3 begin state start begin when 101.kill begin --cuando matas al mob con id 101 say("¡Hola mundo!") --muestra en dialogo end end end Sabiendo todo esto que acabo de explicar ya tenemos una gran parte avanzada, pero ¡aquí no acaba toda la información de los whens!
    Hasta ahora he puesto tan solo un when por quest ¿no se pueden poner más? ¡Claro que sí! Veamos:
    (recordar cerrar todos los whens!)
     

    quest cap3_4 begin state start begin when 9012.chat."Quest de prueba 1" begin --cuando hablas con el npc haciendo click a Quest de prueba 1 9012 say("¡Hola mundo!") --muestra en dialogo end when 9012.chat."Quest de prueba 2" begin --cuando hablas con el npc haciendo click a Quest de prueba 2 9012 say("¡Hola mundo!") --muestra en dialogo end end end quest cap3_5 begin state start begin when 9012.chat."Quest de prueba" begin --cuando hablas con el npc 9012 say("¡Hola mundo!") --muestra en dialogo end when login begin --cuando te logeas say("¡Hola mundo!") -- muestra en dialogo end end end  
    En este momento ya deberíais empezar a entender el funcionamiento básico de las quests. Si no es así, revisa estos 3 capitulos de nuevo antes de continuar el capítulo y el curso restante. Es importante que nunca escribáis algo que no entendáis. Si no, (me cito a mí mismo) pasaría esto en un futuro:
    [/size][/font]
     
    Expandiendo la estructura básica de un when.
     
    Como dije antes, esa tan solo era la estructura básica de un when. Esta estructura podemos complicarla tanto como queramos añadiendo condiciones o juntando varias acciones de distintos whens.
     
    Partiremos de la quest básica: (A partir de ahora tan solo pondré la parte del when. No os olvidéis nunca de poner el inicio de la quest y los states, igual que su correspondiente cierre)
     

    when 101.kill begin --cuando matas al mob con id 101 say("¡Hola mundo!") --muestra en dialogo end Empezaremos poniendo una condición. En este caso, que el usuario sea mayor de nivel 5.
     

    when 101.kill with pc.get.level() > 5 begin --cuando matas al mob con id 101 + con nivel mayor de 5 say("¡Hola mundo!") --muestra en dialogo end De esta manera (utilizando with) podemos añadirle una condición. Si el usuario no coincide con la condición, el servidor omitirá el when en el que estamos trabajando. Esto nos puede ahorrar escribir codigo. En vez de poner una condición dentro del when, la ponemos en el propio when (más información sobre las condiciones en el capítulo IV de keko).
    Más ejemplos:
     

    when 101.kill with pc.get_map_index == 41 begin --cuando matas al mob con id 101 + estando en el mapa con index 41 say("¡Hola mundo!") --muestra en dialogo end when 101.kill with pc.get_max_hp > 5000 begin --cuando matas al mob con id 101 + teniendo un valor de HP mayor de 5000 say("¡Hola mundo!") --muestra en dialogo end when 101.kill with pc.is_mount begin --cuando matas al mob con id 101 + estando montado en una montura say("¡Hola mundo!") --muestra en dialogo end Hasta ahora hemos trabajado con una sola condición ¿podemos añadir más? Claro!
    Cogemos nuestro ejemplo anterior.

    when 101.kill with pc.get.level() > 5 begin --cuando matas al mob con id 101 + con nivel mayor de 5 say("¡Hola mundo!") --muestra en dialogo endAhora queremos que, demás de ser mayor de nivel 5, posea el item con vnum 19:
    when 101.kill with pc.get.level() > 5 and pc.count_item(19) > 1 begin --cuando matas al mob con id 101 + con nivel mayor de 5 + en posesión del item con id 19 say("¡Hola mundo!") --muestra en dialogo endDe esta manera (utilizando and) podemos añadirle todas las condiciones que queramos, poniendo siempre antes un with. 
    Partiremos de nuevo (aunque ahora algo diferente) de dos whens básicos.

    when 101.kill begin --cuando matas al mob con id 101 say("¡Hola mundo!") --muestra en dialogo end when login begin --cuando te logeas say("¡Hola mundo!") --muestra en dialogo end Podemos juntarlos? Claro! Veamos:
     

    when login or 101.kill begin --cuando matas al mob con id 101 / te logeas say("¡Hola mundo!") --muestra en dialogo endDe esta manera (utilizando or) podemos poner que la acción se efectúe en diversas situaciones o con diferentes condiciones.Todo lo que hemos visto hasta ahora podemos combinarlo como queramos.
     

    when 101.kill or 102.kill or 103.kill begin say("¡Hola mundo!") --muestra en dialogo end when login with pc.get_map_index == 41 or 101.kill with pc.get.level() > 5 and pc.count_item(19) > 1 begin say("¡Hola mundo!") --muestra en dialogo end when 101.kill with pc.get_map_index == 1 or 101.kill with pc.get_map_index == 41 begin say("¡Hola mundo!") --muestra en dialogo end Podemos hacer tantas combinaciones de whens como queramos. Tan solo es saber entender el funcionamiento de las quests.
    Y lo más importante! Sin práctica no se aprende!
    La mejor manera de aprender quest es mirar otras quests ya echas e intentar imitarlo, hacer pruebas y pruebas hasta ver el funcionamiento, o leer este curso.
    Pero claro! Solo con este curso no vais a aprender. Recordar que, sin práctica, nada se aprende!
  7. Me Gusta
    Blesse reacted to ElRaulxX in Capitulo I - Introducción al curso de quest   
    ¡Buenas zone!
     
    Como ya os han dicho, nos dedicaremos keko y yo un tiempo a hacer juntos este graaaaan curso de quests (ya veréis como se os hará corto ). Keko me ha concedido el honor de ser el que abra el curso, así que eso haré jeje
    Los que me conozcan ya sabrán que lo que se me da mejor en cuanto a servidores de metin2 son las quests. Así que aquí estoy... dando un curso a unos cuantos ineptos de lenguaje quest (espero que la palabra inepto la dejemos de lado cuando acabéis este curso, mientras tanto, para mi seréis ineptos xd) para ver si alguien más aprende este lenguaje y dejáis tranquilo al pobre keko xdd
     
    A mi parecer, este lenguaje os empezará siendo bastante sencillo. Aún así, esta sencillez puede ir complicándose hasta llegar al punto de que sino entendéis realmente el funcionamiento básico de las quests no entenderéis nada. Aunque, por mucha complicación de una quest, si la analizas detalladamente y entiendes su funcionamiento, cualquier quest puede sernos fácil.
    Como para eso aún falta mucho, empezaremos por el principio.
     
    Algo importante que tenéis que tener en cuenta es que esto no se aprende en un día. Tenemos que recordar que estamos escribiendo en el lenguaje que habla nuestro servidor. El servidor hará lo que nosotros le digamos que haga. Es por eso que es importante que aprendáis a hablar y pensar en lenguaje informático. Ejemplo:
     
    1 - Pienso en levantarme.
    2 - ¿Estoy levantado? Si es así, se cancela la acción. Sino, paso al siguiente punto.
    3 - Si tengo ganas de andar, pasaré al siguiente punto. Sino, no haré nada.
    4 - Acción de levantarse: ¿se ha ejecutado correctamente? Si es así, voy al siguiente punto. Sino, vuelvo al primer punto.
    5 - Andar = mover las piernas
    6 - Cuando muevo las piernas me desplazo, doy una vuelta y vuelvo a sentarme.
    7 - Vuelvo al primer punto.
    8 - No sé si entenderéis eso, cuando os vayáis familiarizando entenderéis porqué pongo eso y que utilidad tiene.
     
    Creo que lo más lógico antes de aprender algo, es decir que es ese algo. Por eso empezaré definiéndoos lo que es una quest.
     
     
    Qué es una quest?
     
    Podríamos decir que una quest es cualquier archivo que utilice el lenguaje quest. Digo "podríamos" ya que no es un lenguaje de programación propiamente dicho. El lenguaje quest es una derivación de LUA (que sí que es un lenguaje informático) con muchas modificaciones con la intención de adaptarlo a Metin2. Es por eso, que si nos fijamos, el servidor utiliza archivos lua.
    A mi parecer, no es el lenguaje más importante del servidor. Aún así, con este podemos realizar cientos de cosas muy variadas y interesantes.
    Lo más común de una quest son las típicas tipo trama (ves a tal sitio, haz esto, haz lo otro...) pero las quests dan muchísimas más opciones a parte de eso, me atrevería a decir que eso es lo menos usado. Con las quests podemos crear dungeons (como la Torre de demonios), podemos corregir bugs (como el bug de hp negativo), podemos informar a la gente (por ejemplo, anuncios automáticos),... podría decir muchísimas más cosas pero tengo una guía que acabar
     
     
    Funciones
     
    Lo más importante de una quests son las funciones, pues las quests trabajan con ellas, pero ¿qué es una función?
    Una función es un carácter o grupo de carácter que corresponden a una acción del servidor o sustituyen un código determinado.
    La función "caminar" (del anterior ejemplo) equivale a mover las piernas con la intención de cambiar de lugar. Si en una quest tuviéramos que desplazarnos (caso hipotético), deberíamos utilizar la función "caminar" para movernos.
    Pero si tengo que definir una función dentro de nuestro lenguaje quest, lo dividiría en dos partes (sería lo mismo, pero uno más visual que el otro):
     
    ·Funciones definidas por el servidor. Serían aquellas funciones que, al ponerlas en nuestra quest, haría una acción. Un ejemplo real, un tipo de estas funciones sería la función "pc.give_item2(19,1)". Al utilizar esta función en una quest, el usuario (al que llamaremos pronto como pc) obtendrá una unidad del objeto con la id 19. Esta función sustituye la acción interna del servidor de dar un objeto al usuario.
     
    ·Funciones no definidas por el servidor. Son aquellas funciones que hemos definido a parte, en un archivo que más adelante del curso diremos, o en la propia quest. Estas funciones sustituye a varias acciones del servidor o de lua. Por ejemplo, si tenemos que escribir varias veces en la quest que se muestre en pantalla un mensaje de error, podemos poner estas funciones para ahorrarnos código.
     
    En concepto, podríamos pensar que son muy distintas, pero vienen a ser lo mismo.
     
     
    Object - Quest ¿Lo mismo?
     
    Lo que es una quest creo que ya lo hemos definido, pero ¿object?
    El object es lo que lee el servidor. El servidor no reconoce nuestra quest, sino que lee fragmentos de nuestra quest (en lenguaje lua).
    Existe un compilador que nos transforma nuestras quests y las deposita en la carpeta object para que las lea el servidor. El compilador crea un directorio con unas ids determinadas que corresponden al item, mob, timer... y al interior nos la separa en states y en la acción que se realiza. De esta manera, el servidor puede hacer uso de las quests.
    Este compilador se llama qc (quest compilator) y se encuentra en el directorio quest de nuestro servidor.
    Por lo tanto, para implementar las questa tendremos que hacer uso de él.
    Aquí os dejo un TIP que os ayudará:
    Debes iniciar sesión para ver el contenido del enlace en esta publicación.  
     
     
    Este capitulo ha sido el más teórico de todos y quizá tenga que añadir más información. Los siguientes capítulos serán más prácticos.
    Poco a poco empezareis a descifrar todos los secretos de las quests.
  8. Me Gusta
    Blesse reacted to KeKo in Capítulo II - Estructura de una quest   
    Buenas zone!
     
    Llega el segundo capítulo del esperado curso de creacion de quests. Tras un primer episodio lleno de aventuras, romance e intriga en esta entrega os voi a explicar como se estructura una quest.
     
    Antes de nada recordaré las palabras de un sabio llamado raul sobre: qué es una quest? Y además tened esto en mente siempre durante este capítulo.
     
     
    Lo primero de todo cuando vas a hacer una quest es crear el archivo de la quest en si. Como es un archivo de una quest debe tener la extension .quest, para lo que le damos a boton derecho -> nuevo -> documento de texto y una vez creado el archivo. txt le cambiamos el nombre a .quest.
     
    Bueno, después de esta ardua tarea nos encontraremos cara a cara con un archivo en blanco en el que tendremos que vertir nuestras ideas para que se convierta en una quest hecha y derecha. Voi entonces a explicaros como se estructura una quest estándar para que sepais como enfrentaros a nuestro terrible enemigo durante todo el curso: la quest en blanco.
     
    Una quest se divide en 3 partes que podreis distinguir fácilmente:
     
    - Apertura: Son siempre las 2 primeras lineas de una quest.
     
    - Cuerpo: Es lo que podriamos llamar la quest en si, ya que es la parte de la quest que contiene todas las cosas que queremos que haga la quest.
     
    - Cierre: Son siempre ends (a los que dedicare un apartado especial en este capitulo) que hacen que nuestra quest acabe correctamente.
     
    Vamos a hablar ahora en profundidad de cada una de estas partes:
     
    1 - La apertura:
     
    La primera parte de una quest es la que llamaremos apertura a lo largo del curso (ya parezco un profesor ) y que como dije arriba son siempre las dos primeras lineas de una quest.
     
    Veamos un ejemplo de como se debe hacer una apertura:
     

    quest capidos begin state start begin Bien, ahora vamos a centrarnos en qué hace cada una de esas dos líneas:
     

    quest capidos begin La linea más básica de toda una quest, simplemente manda la orden de que comience la quest.
     
    *Desmitificando las quests v1: Se que mucha gente tiene la creencia pagana de que el nombre que va despues de quest en la primera linea de la apertura tiene que ser el mismo que el nombre del archivo .quest PERO ES MENTIRA!!
     
    El nombre que ponemos ahi puede ser el que nos apetezca, ya que simplemente es lo que el juego al cargar la quest para ver que está empezando una.
     
    Bien, ahora la segunda linea:
     

    state start begin Esta linea lo que hace es que comience el estado "start" , es decir: que podemos empezar a escribir nuestra quest.
     
    *Es muy importante que sepais que este estado va a continuar activo hasta el final de la quest, a expecion de casos en los que usemos otros estados aparte del inicial (en lo que profundizará raul en el capítulo de los estados).
    Esto es todo sobre la apertura, espero aver resuelto dudas y enseñado algo que no sepais, y si no lo habreis leido pa na
     
     
    2 - El cuerpo de una quest:
     
    Ahora que ya hemos mandado la orden de que la quest comience (primera linea de la apertura) y hemos activo el estado de start (para poder empezar a escribir quest) nos toca elaborar nuestra quest para hacer eso que queríamos hacer para dejar de ver la temible quest en blanco.
     

    quest capidos begin state start begin De momento tenemos esto, pero ahora queremos hacerlo más digo yo, no? Pues sí! Me remitiré de nuevo a la cita de mi colega raul:
     
    Como veis, cuando pensamos en lenguaje de quest nos planteamos hacer una acción y por lo tanto en el cuerpo de una quest puede suceder varias cosas:
     
    - Que una accion comience.
    - Que pongamos una condicion para que una accion se desarrolle.
    - Que una accion se desarrole.
    - Que comprobemos que una accion se esta desarrolando.
    - Que una accion termine.
     
    Es por eso que en el cuerpo de una quest vamos a usar una serie de operadores logísticos que nos permitiran desarrollar nuestra quest, y que son los siguientes:
     

    when while with and or if elseif else > < >= <= == ~= De ellos:
     
    * when y while sirven para comenzar acciones.
    * with and or if elseif y else sirven para poner condiciones.
    * > < >= <= == ~= sirven para hacer comprobaciones entre acciones.
     
    Primero veremos un ejemplo sencillo de quest que te pone un mensaje en la barra de chat cuando te logeas:
     

    quest capìdos begin state start begin when login begin chat("Bienvenido al servidor, pasalo bien") Como veis tenemos apertura, la orden de que comience una accion cuando nos logeemos y luego la accion que se desarrola cuando nos logeamos.
     
    Vamos a ver ahora mas fondo esto con un ejemplo de quest que envia un mensaje a todos cuando un nuevo pj comienza el juego:
     

    quest capidos begin --- Lineas de apertura state start begin when login with pc.get_level() == 1 begin ---- Linea con orden de comienzo, condicion y comprobacion notice_all("Hay un nuevo personaje en nuestro servidor") --- Linea con la accion Como veis empieza con la apertura.
     
    Luego tenemos una orden para comnenzar una accion: en este caso la accion comenzará cuando nos logeemos con un personaje.
     

    when login Y este comienzo además tiene una comprobación antes de que se desarrolle la accion:
     

    with pc.get_level() == 1 En este caso no solo llega con que nos logeemos con un personaje, ya que tiene que además ser nivel 1, porque tenemos una orden de login, pero con la orden with seguida de una funcion: pc.get_level() y como veis un == que sirve para comprobar que el valor del nivel del personaje es igual a 1.
     

    when login with pc.get_level() == 1 begin Y ahi ya está todo entero. Como veis una vez echa la orden de comenzar la accion cuando nos logeemos, con la condicion de que el personaje sea nivel 1 ponemos la orden begin, para que comience la accion.
     
    Por último simplemente ponemos la accion que se va a desarrollar:
     

    notice_all("Hay un nuevo personaje en nuestro servidor") Bien, creo que ahora ya vais entendiendo como va el cuerpo de una quest, quedaros con el dato de que siempre habrá una orden que haga que comience una mision, ya sea con el when, while, if.... y luego despues de especificar que tiene que pasar para que comience la accion usaremos funciones de quest para desarrolar esa acción.
     
    Bueno pues ahora ya tenemos nuestra accion desarrolandose, pero que hacemos con ella? Como las acciones no pueden ser eternas tenemos que acabarla, y para eso usaremos la palabra end, que indica que la accion termina.
     
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------
    *Apartado especial, nuestros amigos los ends:
     
    Como muchos sabeis uno de los errores más comunes a la hora de hacer quests es poner o bien ends de más o bien ends de menos, lo que hará que nuestras quests no funcionen. Por lo tanto antes de nada parémonos a pensar en que es lo que es un end.
     
    Procediente del inglés la palabra end es un verbo que significa terminar, lo que no nos puede dejar más claro cual es su función en una quest: terminar una acción.
     
    Por lo tanto cada vez que tengamos una accion tendremos que ponerle un end al final para acabarla. Y de que manera vamos a hacer eso? Os lo diremos en el proximo capitulo , na en serio, asi funcionan los ends:
     
    - Por cada begin que tengamos en nuestra quest nosotros le colocaremos un end.
    - Por cada if que haya en la quest pondremos un end.
     
    Veamos algunos ejemplos:
     

    when login begin chat("Hola") end when 105.kill begin say("Has matado un lobo") end when 20095.chat."Hola" begin say("Buenas") end Por cada begin corresponde a un end
     

    if pc.count_item("50084") == 1 then say("Veo que tienes la llave") end En este caso hay un if asi que ponemos un end
     
    *Desmitificando las quest v2: Mucha gente comete el error de pensar que si ves un elseif como lleva la palabra if pues debe tener un end también, pero NO!!! Y es porque un elseif es una continuacion de una condición y no una nueva condicion
     
    Ejemplo:
     

    local s = select ("opcion1" , "opcion2" , "opcion3) if s == 1 then say("Has clickado en la opcion 1") elseif s == 2 then say("Has clickado en la opcion 2") elseif s == 3 then say("Has clickado en la opcion 3") end Como veis solo hay un end, el correspondiente al primer if.
     
    ------------------------------------------------------------------------------------------------------------------------------------------------------------------
     
    Bien ahora que ya conocemos mejor a los ends (de los cuales os seguiremos hablando en posteriores capitulos) ya podemos acabar el cuerpo de nuestra quest, cerrando la accion que habeis comenzado.
     
     

    quest capidos begin --- Lineas de apertura state start begin when login with pc.get_level() == 1 begin ---- Linea con orden de comienzo, condicion y comprobacion notice_all("Hay un nuevo personaje en nuestro servidor") --- Linea con la accion end --- End correspondiente al begin de la linea 3  
    Pero los listos os habreis dado cuenta de que en nuestra quest quedan 2 begins (de la apertura) que no tienen su end y eso lo voi a explicar ahora en la ultima parte de la estructura de una quest.
     
    3 - Cierre de una quest:
     
    Cada vez que acabemos una quest vamos a tener que poner dos ends para cerrar la quest, y os estareis preguntando, y porque??? Pues la explicacion es esta:
     

    state start begin Os acordais de la apertura? Si lo haceis os acordareis de que para hacer una quest tenemos que hacer un estado de comienzo (state start), que logicamente acabara cuando acabe la quest. De ahi viene el primer end del cierre de una quest.
     
    *Detalle importante: algún espabilado habrá visto quests en los que se usan otros states aparte del start. En eses casos el cierre solo lleva un end (el que explico abajo) ya que acabaremos el start antes de lo normal para poner nuestro nuevo estado (para mas info sobre estado atentos al capítulo dedicado a ellos que hará raul).
     
    Y ahora el segundo end del cierre:
     

    quest capidos begin De nuevo dire si os acordais de la apertura (que espero que os acordeis ) sabreis que cada quest empieza con esa orden, y como os fijareis tiene un begin al final por lo que le corresponde un end, pero no se lo podemos poner en cualquier momento, ya que (me quoteo a mi mismo):
     
    Es decir, si acabamos la accion de que comience la quest, acabamos la quest (genial deduccion). Siguiendo este hilo de deduccion os habreis dado cuenta de que es por eso por lo que el end correspondiente al begin del quest nombre begin siempre va al final de la quest.
     
    Y ahora ya podemos ver nuestra quest completa y lista para cargar
     

    quest capidos begin --- Lineas state start begin ----- de apertura when login with pc.get_level() == 1 begin ---- Cuerpo de la quest notice_all("Hay un nuevo personaje en nuestro servidor") --- Cuerpo de la quest end --- End correspondiente al begin de la linea 3 --- Cuerpo de la quest (end correspondiente el when login begin) end --- Cierre del state end --- Cierre del quest begin Y eso es todo por el capítulo de hoy, espero que lo hayas disfrutado y pronto llegará el 3er episodio de manos de raul.
  9. Me Gusta
    Blesse reacted to Thanato in Bug de hp   
    Bueno os hago hoy otra guia, esta consiste en quitar el bug de hp sin necesidad de quest.
     
     
    Para arreglarlo es simple os vais a navicat. En navicat os vais a player, y en player haceis esto:
     

    Debes iniciar sesión para ver el contenido del enlace en esta publicación.  
    le dais en player a design table, luego de esto os saldra una pestaña con unos datos, buscais hp:

    Debes iniciar sesión para ver el contenido del enlace en esta publicación.  
    Y en hp justo al lado cambiais el smallint por int::

    Debes iniciar sesión para ver el contenido del enlace en esta publicación.  
    Asi desbugueareis el hp cuando pasa el limite de 32k de hp que empieza a bugearse cuando vais a otro mapa que os sale el hp negativa.
     
    Espero que os haya servido.
    Atentamente Thanato.
×
×
  • Crear nuevo...