Inscrit le: 14 Oct 2009 Messages: 719 Sujets: 40 Spécialité en worldedit: Les bugs Médailles: 1 (En savoir plus...)
Posté le: 29/05/12 17:47 Sujet du message: Buff
Salut,
Je suis en train de faire un "système" de buff et j'aurais besoin de vos conseils.
D'abord à propos des buffs non stackables. Wareditor m'a conseillé de remplacer l'ancien buff qu'à l'unité si le nouveau est de niveau supérieur. Le problème étant que si on se retrouve dans cette situation, c'est bof :
Un fantassin a le buff 'X' de niveau 2 et qui dure encore 10 secondes sur lui. On lui ré applique le buff 'X' mais niveau 3 et qui dure 3 secondes. Cela voudrait dire que l'on supprime l'ancien buff et qu'on met le nouveau de niveau 3 pendant 3 secondes. Mais pendant les 7 secondes qui suivent, il n'y aura aucun buff sur l'unité alors que le buff de niveau 2 devait rester pendant 10 secondes.
J'ai donc essayé de comprendre la logique de Warcraft avec le sort choc des ténèbres. Pour eux, si le niveau buff a une durée supérieur, alors on incrémente la durée. De même que si le buff a un niveau supérieur, on incrémente le niveau. Dans la situation de tout à l'heure on se retrouverait avec le buff 'X' de niveau 3 pendant 10 secondes. Un peu cheaté, mais ça me convient pas mal comme solution.
J'ai essayé avec un second buff : surprise, plus du tout la même logique. Blizzou aime bien faire des feintes .
Comment gérer ces buffs non stackables sachant que je ne veux pas enregistrer tous les buffs du même type non stackable pour savoir lequel est du plus haut niveau à un moment. J'avais fait cela pour mon "système" de régénération, mais c'est très lourd comme méthode.
Deuxième problème (qui est plus une question d'optimisation et de déspaghettisation) :
J'aimerais que l'on puisse retrouver tous les buffs d'une unité avec la complexité la moins élevée (O(n)). Pour cela j'ai utilisé une liste chaînée, avec le premier membre de cette liste attribué à une variable au déploiement de la custom value de l'unité.
Donc là, il n'y a pas trop de problème : on peut retrouver un buff d'un certain type d'une unité avec une complexité de O(1) (à l'aide d'une hashtable), et en même temps retrouver tous ses buffs avec une boucle, et avec un complexité de O(n).
Le problème étant que les buffs peuvent aussi être stackables. Pour retrouver un buff d'un certain type d'une unité, la hashtable ne suffit plus. J'ai donc décidé de créer une autre liste chaînée avec les buffs stackables du même type d'une même unité entre eux, avec le premier membre de cette chaîne sauvegardé dans la hashtable.
Ça nous fait donc deux chaînes, et un système pas mal alourdi pour pas grand chose.
Est-ce un peu trop spaghetti? Devrais-je plutôt simplement ajouter les buffs stackables à la première liste, et énumérer toute cette liste pour les retrouver? Le problème étant qu'on perd en optimisation, la complexité devenant O(n) avec n le nombre de buffs total sur l'unité, à la place de O(n) avec n le nombre de buff du même type de l'unité. _________________
Inscrit le: 14 Oct 2009 Messages: 719 Sujets: 40 Spécialité en worldedit: Les bugs Médailles: 1 (En savoir plus...)
Posté le: 29/05/12 18:24 Sujet du message:
Un système qui permet de :
I. On définit un type de buff
On peut ensuite lui attribuer pleins de caractéristiques telles que : buff type positif, négatif, neutre, s'il est stackable, s'il est permanent (important pour les auras), effet spécial, attachement, une fonction périodique, une fonction lancée à l'application du buff, à sa destruction, etc.
II. Une fois défini, on a ces fonctions à disposition :
- Buff.add takes unit caster, unit target, integer level, real duration, BuffType whichBuff returns thistype
(Une durée de 0 est considérée comme infinie. Utile pour des auras)
- Buff.destroy takes nothing returns nothing
- Buff.has takes unit whichUnit, integer whichBuff returns boolean
(Méthode plus rapide que getLevel > 0)
- Buff.getLevel takes unit whichUnit, integer whichBuff returns integer
(Pour les buffs stackables, renvoie le niveau le plus haut)
- Buff.remove takes unit whichUnit, integer whichBuff, boolean removePermanant returns integer
(return le niveau du buff)
- Buff.removeByEffectType takes unit whichUnit, integer effectType, boolean removePermanant returns integer
(return le nombre de buff retirés de cette manière.
Les buffs stackables seront comptabilisés plusieurs fois)
- Buff.removeAll takes unit whichUnit, boolean removePermanant returns integer
(return le nombre de buff retirés de cette manière. Les buffs stackables seront comptabilisés plusieurs fois)
- et d'autres
Bref, si tu as déjà touché à l'éditeur de starcraft II, la même interface que les buffs de scII proposent. _________________
Inscrit le: 23 Aoû 2007 Messages: 7143 Sujets: 147 Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance Médailles: 2 (En savoir plus...)
Posté le: 29/05/12 18:52 Sujet du message:
En fait ce que je voulais surtout savoir c'est si les effets des buffs sont appliqués uniquement par trigger ou si ne serait ce qu'une partie d'entre eux sont ajoutés via une dummy unit avec un spell.
Sinon j'ai pas touché à l'éditeur de sc2, je crois que je vais attendre que les 2 add ons soient sortis, soit d'ici 5 ans ou plus :p _________________
Inscrit le: 23 Aoû 2007 Messages: 7143 Sujets: 147 Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance Médailles: 2 (En savoir plus...)
Posté le: 29/05/12 19:33 Sujet du message:
Sapeur-Goblin a écrit:
Euh, non, la totalité des buffs sont ajoutés pas trigger, enfin ça change vraiment grand chose?
"pas" == "par" ?
Ca change énormément oui, si les buffs sont ajoutés par trigger (n'ont pas d'effet en soi), alors il est "facile" de gérer les buffs stackables avec levels multiples ou non, car on peut les enlever et ajouter comme bon nous semble, étant donné que c'est juste visuel.
Par contre s'ils ont des effets en eux même, alors on ne peut pas faire ce que l'on veut, puisque les supprimer, enlèvera aussi leurs effets.
Cela dit je présume que certains effets de buffs ne sont pas reproductibles par trigger ...
Citation:
Tu voudrais pas lâcher ce si bel éditeur de déclencheur pour un éditeur de données ?
Bah à vrai dire ça fait déjà un bail que j'ai aussi lâché celui là, je vivotes juste avec mes acquis et ma mémoire, c'est juste une habitude ancrée depuis plusieurs années qui me fait continuer à poster à son sujet.
PS : Sinon y'a des systèmes de buffs déjà existants, you know. _________________
Dernière édition par Troll-Brain le 29/05/12 19:37; édité 1 fois
Inscrit le: 14 Oct 2009 Messages: 719 Sujets: 40 Spécialité en worldedit: Les bugs Médailles: 1 (En savoir plus...)
Posté le: 29/05/12 19:42 Sujet du message:
Troll-Brain a écrit:
PS : Sinon y'a des systèmes de buffs déjà existants, you know.
Ouais, j'en ai vu un sur HiveWorkShop mais il m'a l'air très bizarre et je préfère avoir le mien.
Troll-Brain a écrit:
Ce qui veut dire ? Dans l'éditeur d'objet ?
Sapeur-Goblin a écrit:
I. On définit un type de buff
On peut ensuite lui attribuer pleins de caractéristiques telles que : buff type positif, négatif, neutre, s'il est stackable, s'il est permanent (important pour les auras), effet spécial, attachement, une fonction périodique, une fonction lancée à l'application du buff, à sa destruction, etc.
Le tout par déclencheur. _________________
Dernière édition par Sapeur-Goblin le 29/05/12 19:43; édité 1 fois
Inscrit le: 21 Fév 2010 Messages: 1785 Sujets: 22 Spécialité en worldedit: La modestie Médailles: 1 (En savoir plus...)
Posté le: 29/05/12 19:43 Sujet du message:
Mets un champs de type entier dans ta chaîne listée pour le level, non? À moins que le stack puisse se produire pour le même buff mais avec des niveaux différents (ce que jte conseille pas de faire :p). _________________
Inscrit le: 14 Oct 2009 Messages: 719 Sujets: 40 Spécialité en worldedit: Les bugs Médailles: 1 (En savoir plus...)
Posté le: 30/05/12 12:31 Sujet du message:
Je ne crois pas que ça change quelque chose que l'on puisse connaître le nombre de stacks.
S'il n'y avait que des buffs non stackables, ça se passerait de cette manière :
- On a une hashtable
- On a une variable thistype array, qu'on va appeler enumInst
- On a un membre de la structure thistype appelé next
- Lorsqu'on ajoute le buff, on l'enregistre dans la hashtable et dans l'index de enumInst correspondant à la custom value de la cible. Sauf que si cet index est déjà utilisé, on l'assigne au membre next de cette liste.
Bref, une liste chaînée.
Le problème est de savoir comment faire pour les buffs cumulables. Le plus simple serait bien sûr de faire comme pour les buffs non cumulables, de tout rajouter dans la liste chaînée à l'index de l'unité. Cependant pour retrouver tous les buffs du même type d'une unité, ça ne marche plus du tout de la même manière. Pour les buffs non cumulables, il suffit de faire comme ça : LoadInteger(table, GetUnitUserData(u), whichBuff). Mais pour les buffs cumulables, une boucle dans la liste chaînée s'impose. Or cette liste contient tous les buffs de l'unité. Donc on ne retrouve pas directement les buffs d'un certain type cumulables et on fait des calculs en plus. Vaut-il mieux rajouter les buffs stackables en vrac dans la première liste et les retrouver avec une boucle un peu plus longue? Faut-il faire une deuxième liste chaînée? Avez-vous d'autres manières d’indexer les buffs?
Il est aussi nécessaire de classer les buffs en différentes catégories : positifs, négatifs, neutres. Pour retrouver tous les buffs d'une même catégorie d'une unité, j'ai donc décidé de séparer la variable enumInst en trois : positivInst, negativInst, neutralInst pour un minimum de boucles. On retrouve tous les buffs très rapidement avec cette méthode.
Mais encore une fois ça alourdi pas mal le système. Il aurait été simplement possible de tout mettre en vrac dans la liste et de faire une boucle sur la totalité des buffs de l'unité. De même qu'il n'est pas possible d'ajouter ses propres types de buffs : il faudrait toucher au système lui-même.
Donc ces trucs que je fais pour mieux classer les buffs et ainsi les retrouver plus rapidement sont-ils inutiles? Je me complique la vie pour rien ? Ou au contraire vous me conseillez de le faire?
Sinon je crois qu'il faudrait déplacer le sujet vers les déclencheurs . _________________
Toutes les heures sont au format GMT + 1 Heure Aller à la page 1, 2Suivante
Page 1 sur 2
Vous ne pouvez pas poster de nouveaux sujets dans ce forum Vous ne pouvez pas répondre aux sujets dans ce forum Vous ne pouvez pas éditer vos messages dans ce forum Vous ne pouvez pas supprimer vos messages dans ce forum Vous ne pouvez pas voter dans les sondages de ce forum