aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Metin2

Metin2 Quest Timer : utilisation et exemples

Le Metin2 quest timer est l'une des parties les plus puissantes — et les plus souvent mal utilisees — du systeme de quetes : il permet de declencher un evenement non pas instantanement, mais apres un delai defini. Que vous vouliez une quete a compte a rebours, un avertissement qui se repete a intervalles, un delai de reapparition de boss, ou un cooldown du type "vous pouvez reclamer cette recompense une fois toutes les 24 heures", les minuteurs sont au coeur de tout cela. Dans cet article, nous allons parcourir pas a pas les deux mecanismes principaux du moteur de quetes Metin2 — le q.start_timer lie au joueur et le server_timer global — avec des exemples reels et fonctionnels.

Qu'est-ce qu'un quest timer et comment fonctionne-t-il ?

Le moteur de quetes est evenementiel : les blocs when ... begin ... end reagissent a des evenements precis (dialogue, kill, connexion). Un minuteur ajoute un "delai" a cette logique. Quand vous demarrez un minuteur, le moteur l'enregistre, et a son expiration il leve un evenement special — que vous attrapez a nouveau avec un bloc when. Il en existe deux types :

  • Minuteur lie au joueur (q.start_timer) : le minuteur appartient a un personnage precis. Quand il se declenche, le bloc s'execute dans le contexte de ce joueur, vous pouvez donc appeler directement les fonctions pc.*.
  • Minuteur serveur global (server_timer) : le minuteur appartient au serveur, pas a un joueur. Il est ideal pour des taches non liees a quelqu'un, comme les reapparitions de boss ou les evenements de carte.

Un minuteur lie au joueur avec q.start_timer

C'est le scenario le plus courant : un joueur parle a un PNJ, et X secondes plus tard quelque chose se produit. Vous le demarrez avec q.start_timer("nom", secondes) et attrapez le resultat dans un bloc when nom.timer.

quest boite_cadeau begin
    state start begin
        when 20095.chat."Ouvrir la boite" begin
            say_title("Marchand :")
            say("La boite s'ouvrira dans 10 secondes, attends...")
            q.start_timer("ouvrir_boite", 10)
        end

        when ouvrir_boite.timer begin
            say("La boite s'est ouverte ! Voici ta recompense.")
            pc.give_item2(27003, 1)   -- vnum d'item d'exemple
            pc.give_exp2(5000)
        end
    end
end

Le point cle : le bloc ouvrir_boite.timer s'execute deja dans le contexte du bon joueur, car nous avons demarre le minuteur pour ce joueur. Si vous rappelez q.start_timer avec un nom deja existant, l'ancien est remplace par le nouveau, ce qui evite commodement un double declenchement accidentel.

Evenements differes globaux avec server_timer

Supposons que vous vouliez qu'un boss reapparaisse une heure apres sa mort. Cela n'a rien a voir avec un joueur precis, vous utilisez donc server_timer. La signature est server_timer("nom", secondes, arg). Vous pouvez passer un VID ou un nombre en troisieme parametre et le relire avec get_server_timer_arg() au declenchement.

quest reapparition_boss begin
    state start begin
        when 6091.kill begin
            -- Le boss est mort, reapparition dans 1 heure
            local map_index = pc.get_map_index()
            server_timer("retour_boss", 60 * 60, map_index)
            notice_all("Le boss est tombe ! Il reviendra dans 1 heure.")
        end

        when retour_boss.server_timer begin
            local map_index = get_server_timer_arg()
            regen_in_map(map_index, "data/boss_regen.txt")
            notice_all("Le boss est reapparu !")
        end
    end
end

A l'interieur d'un bloc server_timer, il n'y a pas de contexte joueur par defaut. Si vous devez agir sur un joueur precis, transportez son PID via l'argument et utilisez le motif q.begin_other_pc_block(pid) ... q.end_other_pc_block().

Le motif de cooldown

Les minuteurs sont faits pour des choses qui se declencheront "bientot", mais un cooldown persistant du type "reclamer cette recompense une fois toutes les 24 heures" doit survivre meme a un redemarrage du serveur. La bonne methode n'est pas un minuteur, mais l'ecriture d'un horodatage dans un flag du joueur. get_global_time() renvoie l'heure actuelle du serveur en secondes ; vous la stockez avec pc.setqf et comparez plus tard.

quest recompense_quotidienne begin
    state start begin
        when 20095.chat."Recompense quotidienne" begin
            local now = get_global_time()
            local last = pc.getqf("derniere_recompense")
            local cooldown = 24 * 60 * 60   -- 24 heures

            if now - last < cooldown then
                local reste = cooldown - (now - last)
                say("Attends encore " .. math.floor(reste / 3600) .. " heures pour la prochaine recompense.")
                return
            end

            pc.setqf("derniere_recompense", now)
            pc.give_item2(50300, 1)
            say("Ta recompense quotidienne est prete !")
        end
    end
end

La difference est cruciale : q.start_timer est perdu au redemarrage du serveur, mais l'horodatage ecrit dans un flag reste dans la base de donnees. Pour des cooldowns persistants, preferez toujours ce motif.

Minuteurs repetitifs et annulation

Pour une tache qui se repete a intervalles (par exemple un avertissement toutes les 30 secondes), vous re-armez le minuteur dans son propre bloc. Quand vous voulez l'arreter, vous brisez la boucle avec un flag de quete — car si vous ne le redemarrez tout simplement pas, la boucle s'arrete d'elle-meme.

quest compteur begin
    state start begin
        when login begin
            pc.setqf("tour", 0)
            q.start_timer("tic", 30)
        end

        when tic.timer begin
            local tour = pc.getqf("tour") + 1
            pc.setqf("tour", tour)
            chat("Tour : " .. tour)

            if tour < 5 then
                q.start_timer("tic", 30)    -- re-armer = continuer
            else
                chat("Compteur termine.")    -- ne pas re-armer = arreter
            end
        end
    end
end

Si vous devez annuler tot un minuteur lie au joueur, q.clear_timer() efface les minuteurs en cours. Pour un minuteur global, utilisez q.clear_server_timer("nom", arg).

Erreurs courantes et astuces

  • Le nom du minuteur ne correspond pas au bloc when : si vous avez demarre q.start_timer("ouvrir_boite", 10), le bloc doit etre when ouvrir_boite.timer. Les noms doivent etre strictement identiques.
  • Utiliser un minuteur pour un cooldown persistant : le minuteur est efface au redemarrage du serveur. Pour des durees longues et persistantes, utilisez le motif get_global_time() + flag.
  • Appeler pc.* dans server_timer : il n'y a pas de joueur dans le contexte global ; transportez le PID via l'argument et entrez dans un bloc q.begin_other_pc_block.
  • Intervalles tres courts : evitez le travail en dessous de la seconde ; le moteur de quetes fonctionne a la resolution de la seconde, et des minuteurs trop frequents nuisent aux performances.
  • Verifiez syserr : si un minuteur ne se declenche pas comme prevu, regardez d'abord syserr.txt — les erreurs Lua y apparaissent generalement.

Questions frequentes

Quelle est la difference entre q.start_timer et server_timer ?

q.start_timer appartient a un joueur precis et le bloc s'execute dans son contexte ; il tombe si le personnage se deconnecte. server_timer appartient au serveur, n'est lie a personne et sert aux evenements globaux comme les reapparitions de boss.

Qu'arrive-t-il aux minuteurs si le serveur redemarre ?

Les minuteurs en memoire sont perdus. C'est pourquoi vous devez gerer les attentes de plusieurs heures ou jours non pas avec un minuteur, mais en ecrivant get_global_time() dans un flag du joueur ; le flag persiste en base de donnees.

Puis-je lancer plusieurs minuteurs en meme temps ?

Oui, donnez simplement un nom different a chacun. Demarrer un nouveau minuteur avec le meme nom annule l'ancien et arme le nouveau, ce qui est parfois utilise volontairement comme mecanisme de "reinitialisation".

Bloque sur le systeme de quetes ? Si vous avez besoin d'aide pour le developpement de quetes Metin2 — quetes basees sur des minuteurs, logique de donjon ou systemes d'evenements personnalises — contactez-moi et resolvons votre projet ensemble.

Bu kategorideki tüm yazılar →

Devamı için