Jump to content
×
×
  • Create New...
  • 0

Petit bout de quête


guii59
 Share

Question

Bonsoir!

Je recherche un "bout de code" permettant de rendre un objet qui est utilisable en limitant son utilisation (Ex: Anneau de Téléportation avec limite de 50 utilisations, puis l'objet se détruit), si quelqu'un serais me dire ce serais sympa :)

Merci

Link to comment
Share on other sites

  • Answers 3
  • Created
  • Last Reply

Top Posters For This Question

Top Posters For This Question

3 answers to this question

Recommended Posts

  • 0

when login or levelup with pc.level  >= 10 then   // quand le joueur se co ou augmente de level après le lv 9

            pc.give_item2(ton_anno)  // donner l'item au joueur

            pc.setqf("coups_anno", 50)  // crée la variable coups_anno et lui attribuer la valeur 50

end

when ton_anno.use with pc.getqf("coups_anno") >= 2 begin   // quand tu utilise ton anno avec la valeur 2 ou + de ta variable ( en gros 2 utilisation restante ou + )

            pc.setqf("coups_anno", pc.getqf("coups_anno")-1)  // décrémenter la valeur de ta variable coups_anno 

end

when ton_anno.use with pc.getqf("coups_anno", 1)    //  quand tu utilise ton anno avec la valeur 1 de ta variable ( en gros il reste que 1 utilisation )

            pc.setqf("coups_anno", 50)    //  je remet la valeur a 50 ( au cas ou le joueur rachete l'item sur l'is par exemple )

            pc.remove_item(ton_anno, 1)   // je supprime l'item de son inventaire

end

En gros j'ai fait que tu reçoit l'anneau au lv 10 et au moment ou tu le reçoit il est régler sur 50 utilisation et a chaque fois que tu clique dessus il perd 1 utilisation j'ai rien mit de + vu que je ne sais pas ce que tu compte faire avec sa ^^

Tout sa pour te dire qu'il faut que tu crée une sorte de compteur en passant par la fonction getqf, setqf.

Link to comment
Share on other sites

  • 0

Bien essayé valent76, sauf que ça ne satisfait pas au cahier des charges. Avec ton code, à chaque connexion, tu donneras l'objet en question au joueur et tu réinitialiseras le compteur. Ce n'est de toute évidence pas le but recherché. De plus, tu as fais des erreurs de syntaxes.

 

Ayant trouvé ce problème intéressant, je vous propose un petit article sur des pistes de résolution.

 

Dans toute la suite de ce message, je me baserai sur le fait que nous n'avons pas accès aux sources du jeu et que nos seuls outils sont les quêtes et la base de données.

La première chose à faire, c'est de mettre en lumière les principaux obstacles qui s'opposent à nous.

  • Que se passe-t-il si le personnage possède plusieurs fois l'objet ?
  • Que se passe-t-il si le personnage jette l'objet ? Que se passe-t-il si le personnage vend l'objet ou l'échange ?

Ensuite, on va essayer d'y répondre de la meilleure manière qui soit.

Je ne traiterai ici que le premier obstacle majeur en supposant que le personnage peut posséder plusieurs fois l'objet dans son inventaire mais que ce dernier ne peut pas être échangé, jeté, vendu ou mis dans l'entrepôt de compte (chose possible via l'antiflag).

 

Supposons que le personnage possède n fois l'objet (n supérieur à 1) dans son inventaire. 

Posons objet_i , i allant de 1 à n, les n objets que le personnage possède dans son inventaire. Ils sont chacun identifiables par leur indice i (appartenant à l'intervalle d'entiers [|1, n|]).

 

Première difficulté : comment savoir quel est l'objet utilisé ?

 

En effet, on a l'habitude d'utiliser des syntaxes telles que ( when VNUM.use with ... begin ) qui permettent de capter l'événement d'utilisation d'un objet de vnum VNUM. Cependant, cela ne nous permet pas de savoir à quel objet on s'adresse. Comment individualiser notre objet ? En quoi est-il unique ?

Il y a plusieurs choix de réponse possibles. Le plus logique, le plus habituel et le plus efficace : son identifiant unique. Chaque objet du jeu est en effet lié à un identifiant unique qui permet d'accéder à ses caractéristiques particulières. On le retrouve notamment comme clé primaire de la table item (base player). Il se trouve qu'on a facilement accès à cet identifiant via la fonction item.get_id() qui s'applique justement à un événement d'utilisation d'un objet. 

 

Nous pouvons donc désormais identifier chacun des n objets présents dans l'inventaire grâce à son identifiant unique que nous noterons pour la suite objet_id_i, i allant de 1 à n

 

Intéressons nous maintenant plus spécifiquement à un objet d'indice k, k appartenant à l'intervalle d'entiers [|1, n|].

 

Deuxième difficulté : comment mettre en place la limite d'utilisation de cet objet ?

 

Là encore, il y a de nombreuses techniques possibles.

Fixons X le nombre de fois que l'objet peut être utilisé avant sa destruction.

 

1ere solution : event_flag personnalisé

 

Il nous faut un compteur, une variable numérique qui sera en quelque sorte liée à l'objet et que nous pourrons incrémenter ou décrémenter à souhait. Il se trouve que nous sommes capables de créer des variables numériques liées au personnage et de les gérer plutôt efficacement : les event flag. 

Comment passer du personnage à l'objet ? Etant donné que par hypothèse l'objet ne changera pas de personnage, il est possible de transformer une variable du personnage en variable pour l'objet. On pourra choisir de nommer les variables liées à un objet avec un espace de nom réservé qui sera attribué dynamiquement en fonction de l'identifiant de l'objet. Nous sommes ainsi capables d'agir sur une variable numérique virtuellement liée à l'objet d'indice k.

 

Exemple d'algorithme :

 

Quand le personnage utilise l'objet k

        Si la valeur de la variable questflag "objet_" + objet_id_k + "_count" est strictement inférieure à X alors

                On incrémente de 1 la valeur de la variable questflag "objet_" + objet_id_k + "_count"

        Sinon

                On supprime la variable questflag "objet_" + objet_id_k + "_count" (un identifiant unique peut être réutilisé par un autre objet plus tard une fois l'objet détruit)

                On supprime l'objet

        Fin si

        On téléporte le personnage

Fin

 

Avec cet algorithme, il n'y a rien à initialiser à l'obtention de l'objet. Tout se fait... tout seul. Il est redoutablement efficace et simple. Cependant, il ne pourra pas passer les obstacles suivants car l'objet ne serait alors plus lié au personnage.

 

Bonus : réponse possible aux autres obstacles

 

 

2eme solution : une technique plus énergivore à base de SQL

 

Il est possible d'accéder aux bases de données du jeu dans une quête. Comme je l'ai déjà énoncé, chaque objet dans le jeu est en faite représenté par une entrée dans la table item (base player) dans laquelle on trouvera les informations particulières à cet objet (tandis que les informations globales à tous les objets du même vnum se situeront dans item_proto). Où peut-on créer une variable, "un endroit", où mettre notre compteur qui serait lié à l'objet ?

Et bien la réponse paraît alors évidente : la table item, plus précisément dans l'entrée de l'objet étudié. 

Nous avons plusieurs possibilités pour créer cette information : créer un nouveau champ ou utiliser un champ déjà existant.

La première a l'avantage d'être plus propre et claire. Cependant, elle affectera tous les objets du jeu et doit donc être initialisée intelligemment pour ne pas créer d'incohérence. 

La seconde est plus du "bidouillage" et pourtant c'est peut être celle que je préférerai dans ce cas. La raison est la suivante : il est possible suite à des circonstances qui dépassent cette intervention (exemple d'une amélioration) qu'un objet perde son identifiant unique et devienne un "nouvel objet", avec un nouvel identifiant. Il sera alors recréé à l'identique (excepté le vnum qui sera incrémenté dans le cas de l'amélioration) grâce à une duplication des valeurs connues par le jeu de l'objet (bonus, pierres) présentes dans la table item. Si on utilise un champ déjà existant, il sera alors lui aussi recopié et donc sauvegardé dans le nouvel objet. Dans l'autre cas, la valeur du nouveau champ ne sera pas recopié.

 

Il nous faut donc choisir un champ déjà existant et non utilisé. Si le système s'adresse à un objet utilisable comme ici, je conseille d'utiliser une valeur de bonus (attrvalue) sans mettre d'attrtype. On aura alors aucun affichage graphique mais les données seront là. Dans le cas d'une arme ou d'une armure, on pensera à utiliser un des derniers socket.

 

Nous utiliserons pour la suite le champ attrvalue0. La valeur inscrite dans item_proto (s'appliquant à tous les objets du même vnum) sera 0 (initialisation). Ensuite, on procède de la même manière que dans le précédent algorithme.

 

Exemple d'algorithme :

 

 

Quand le personnage utilise l'objet k

        On sélectionne avec une requête SQL la valeur de son attrvalue0 et on la stocke dans la variable count

        Si la valeur de la variable count est strictement inférieure à X alors

                On incrémente de 1 la valeur de son attrvalue0 à l'aide d'une requête SQL

        Sinon

                On supprime l'objet (le jeu se chargera de supprimer la ligne correspondante dans la table player)

        Fin si

        On téléporte le personnage

Fin

 

Le grand avantage de cette technique c'est qu'à priori elle triomphe de tous les obstacles que nous avons énumérés. 

Cependant, je me dois de prévenir un éventuel utilisateur qu'il n'est pas conseillé d'utiliser des requêtes SQL dans les quêtes. Elles sont très énergivores, souvent peu efficaces (surtout dans une table aussi volumineuse que item) et pourront ralentir considérablement votre serveur.

 

Comment choisir ?

 

Cela dépend du besoin. Un anneau de téléportation à usage limité, je devine qu'il a sa place dans la boutique.

Est-il nécessaire de laisser aux joueurs le droit de l'échanger, de le jeter, de le mettre dans son entrepôt ou de le vendre ? 

Si oui, alors il est obligatoire d'utiliser la deuxième technique présentée. Heureusement, il n'y aura qu'une utilisation pour une téléportation, avec à chaque deux requêtes. C'est donc une charge tout à fait acceptable pour un serveur avec un minimum de moyens.

Sinon, privilégiez la méthode avec les event flag qui est beaucoup plus efficace.

 

Merci de votre lecture (et pardonnez moi si j'ai fais des erreurs...).

  • J'adore 1
Link to comment
Share on other sites

  • 0

Bien essayé valent76, sauf que ça ne satisfait pas au cahier des charges. Avec ton code, à chaque connexion, tu donneras l'objet en question au joueur

 

Il cherche l'idée comme indiquée bout de code je me doute que la quete ne marchera pas des l'obtention de l'item un petit set_state() et pour les erreurs c parce que j'ai fait a la va vite pour lui donner l'idée du comment faire.

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
 Share



  • Flux d'Activité

    1. 1

      Antares2.to | modern Old-/Middleschool | START 07.10.22 | International Server

    2. 0

      Projet Genesis

    3. 4

      Shiva.international serveur privé metin2 Oldschool Start 16.09.2022

    4. 0

      Metin2 Champions - Accès anticipé

    5. 0

      Barbok

    6. 4

      Shiva.international serveur privé metin2 Oldschool Start 16.09.2022

  • Recently Browsing

    • No registered users viewing this page.

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.