Tutoriel sur les addons J'ai toujours voulu faire un tuto sur les addons, donc je vais essayer de dire tout ce que je connais, je sais bien que très peu de joueurs liront tout ça, et encore moins feront des addons après avoir lut ces posts, mais c'est pas grave.
Il y a toujours des joueurs qui cherchent comment faire des addons, au moins ils en auront la possibilité s'ils trouvent ce post, et ne seront pas bloqués comme j'ai été il y a longtemps.
Ce tuto va être très long, genre c'est la première fois que je découpe autant un post ^^ :

Il est susceptible d'évoluer clairement, car je ne connais pas tout dans les addons, il y aura peut être des erreurs qui seront corrigés par d'autres joueurs, et mon premier jet ne va pas totalement vous accompagnez dans la création d'addon, il y aura pas mal de chose que vous devrez voir par vous même, mais je repasserai sur les posts pour les compléter, et surtout pour les fautes d'orthographes ^^. Sommaire- C'est quoi un addon ?
- Pourquoi faire un addon ?
- Comment faire un addon ?
- L'ordre de parcourt du fil d'exécution
- Faire du visuel
- Les objets qui existent pour faire vos addons
- Les scripts handlers attachés aux objets
- Les hooks
- Les événements
- Les SaveVariables
- Le LUA dans wow
Pourquoi faire un addon ? Ça, c'est à vous de le savoir, mais je vais vous donner quelques exemple.
- Avoir une belle interface.
- Avoir une interface plus compact, donc plus optimisé, et donc plus belle pour certains.
- En rogue, afficher les points de combos de manière plus visible.
- En rogue, voir les ticks d'énergies.
- Voir beaucoup mieux visuellement les procs de certains sorts, en war la fulgurance.
- Voir la menace.
- Voir les dégats.
etc...
Vous trouverez votre raison assez facilement. Une fois que vous avez votre raison, vous devez savoir si elle n'est pas faisable facilement en macro, en générale la réponse est non. J'explique ici la différence les macros et les scripts, sachant qu'un addon est composé de scripts, c'est comme si je comparais les macros et les addons (dans le post linké).
Comment faire un addon ? - Où se renseigner ?
Tout ce que je vais écrire, vient de ces sites :
- wow wiki
- wowprogramming
- wow gamepedia
Le site 3 wow gamepedia, est pratiquement pareil que le site 1 wow wiki, donc je n'ai utilisé que les deux premiers sites pour tout apprendre. Et ces sites sont toujours maintenus à la dernière version du jeu, mais on est à vanilla, donc il y aura plein d'outils qu'on ne pourra pas utiliser, et ce n'est pas toujours préciser.
- Commencer à coder
Je précise que j'explique les addons sous windows, sur mac les addons fait sous windows ne fonctionne pas toujours, je ne sais pas trop pourquoi, dans certains addons il y a parfois un dossier MACOSX, ou un truc dans le genre, c'est peut être lié.
Pour commencer, vous devez avoir le jeu fermé, vous allez dans votre dossier d'installation du jeu, et ensuite dans le dossier Interface/Addons/, là vous créez un nouveau dossier appelé MonAddon, tous les noms d'addons doivent être unique, sinon il y aura un conflit, vous allez dans ce nouveau dossier et vous créez trois fichiers :
MonAddon.toc MonAddon.xml MonAddon.lua toc, xml et lua sont les extensions des fichiers, vous devez pouvoir modifier les extensions sur windows, par défaut ont ne peux pas.
Ça vous donne ça :

Le fichier MonAddon.toc doit avoir le même nom que le dossier de l'addon, les autres fichiers peuvent être appelé autrement on va voir pourquoi.
- Le fichier .toc
- Le fichier .xml
- Le fichier .lua
Actuellement cet addon n'affiche rien.
L'ordre de parcourt du fil d'exécution Pour savoir comment coder un addon, il faut savoir comment wow appels les addons qu'on lui passe.
Le fil d'exécution :
C'est un peu abstrait comme notion, mais vitale pour comprendre la programmation.
Par exemple vous allez dans le dossier d'installation de wow, et vous ouvrez avec le bloc note le fichier WoW.exe (ne le faites pas vous même, je vous met une image)
WoW.exe ouvert en bloc note :

C'est une suite de caractères qui ne veut rien dire pour nous, sauf à certain endroits vous voyez quelques phrases compréhensibles en anglais.
Le fil d'exécution c'est ce qui parcourt le fichier et le li, caractère par caractère. Pour imager encore un peu plus, le fil d'exécution a une "tête de lecture" qui li le premier caractère puis le second etc..
On peut imager le parcourt de la tête de lecture du fil d'exécution en sélectionnant le premier caractère :

Puis le second :

Etc..
Chaque caractère signifie quelque chose pour l'ordinateur, lui fait utiliser une fonctionnalité, et par exemple, certains caractères disent à la tête de lecture de sauter à un endroit du fichier, donc faire une opération stockée plus loin ou pour répéter une opération en sautant en arrière. D'autres caractères peuvent dire de créer un autre fil d'exécution qui aura lui aussi une tête de lecture à un autre endroit du fichier.
Bref, dans ce fichier il y a des séries de caractères parcourut par une tête de lecture, qui gère le rendu graphique du jeu et donc les addons, Le parcourt du fil d'exécution dans wow et les addons :
- Vous ouvrez le jeu, vous arrivez sur la fenêtre de connexion.
- Vous écriez vous nom de compte et votre mot de passe.
- Vous vous connectez.
- Le jeu lit les fichier .toc des addons.
- Vous arrivez sur la liste de vos peronnages.
- Vous choisissez votre personnage.
- Vous commencer le chargement pour entrer dans le jeu :
- Pour chaque addon, un par un, le jeu lit tout vos fichier .lua et .xml dans l'ordre d'écrit dans les fichiers .toc.
- Plus le nombre d'addon est élevé plus cette phase est longue.
- Vous êtes dans le jeu (pour le serveur), mais le jeu n'a pas encore calculer la première image du jeu (sur votre pc).
- Le jeu calcule la première image du jeu :
Là je ne sais pas ce que fait le jeu réellement mais, j'interprète beaucoup.
- Le jeu calcul graphiquement l'environnement 3D (le relief, les personnages, l'équipement, les bâtiments etc..) il en fait une image.
- Le jeu calcul graphiquement l'interface :
- Étant donné qu'on est dans le calcul de la première image du jeu, le jeu appel pour chaque addon, un par un, les scripts OnLoad de chaque frame déclarée dans les fichiers .xml.
- Le jeu appel pour chaque addon, un par un, les scripts OnUpdate des frames dans les fichiers .xml.
- Une fois que tout les addons ont eu leurs scripts OnUpdate entièrement exécutés, l'interface est entièrement calculée pour l'image actuelle.
- Le jeu colle l'image de l'interface sur l'image de l'environnement 3D.
- Le jeu affiche la première image.
- Le jeu calcul la seconde image :
- Le jeu recommence l'étape 9, mais il n'appel plus les scripts OnLoad des frames où il l'a déjà appelé, par contre il appel les scripts OnLoad des frames qui ont étaient crées pendant l'appel des scripts OnLoad et OnUpdate du calcul de l'image précédente (on en reparle ^^).
- Le jeu appel les scripts OnUpdate de toutes les frames qui sont déjà chargées, et des nouvelles frames qui ont eu le scripts OnLoad entièrement exécutés durant le calcul de cette nouvelle image.
- etc...
La même chose, mais dans la pratique :
On reprend notre addon, mais avec quelques modification.
Voila votre nouveau fichier .xml :

- Code: Tout sélectionner
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd"> <Script file="MonAddon.lua"/> <Frame name="MonAddon_MainFrame"> <Scripts> <OnLoad> ChatFrame1:AddMessage("OnLoad dans le fichier xml.") MonAddon_MainFrame_OnLoad() </OnLoad> <OnUpdate> ChatFrame2:AddMessage("OnUpdate dans le fichier xml.") MonAddon_MainFrame_OnUpdate(arg1) </OnUpdate> <OnEvent> ChatFrame1:AddMessage("OnEvent dans le fichier xml.") MonAddon_MainFrame_OnEvent(event, arg1, arg2, arg3, arg4) </OnEvent> </Scripts> </Frame> </Ui>
Et votre nouveau fichier .lua :

- Code: Tout sélectionner
ChatFrame1:AddMessage("Passage 1 du file d'exécution dans le fichier lua.")
function MonAddon_MainFrame_OnLoad() ChatFrame1:AddMessage("OnLoad dans le fichier lua.") end
ChatFrame1:AddMessage("Passage 2 du file d'exécution dans le fichier lua.")
function MonAddon_MainFrame_OnUpdate(arg1) ChatFrame2:AddMessage("OnUpdate dans le fichier lua.") end
ChatFrame1:AddMessage("Passage 3 du file d'exécution dans le fichier lua.")
function MonAddon_MainFrame_OnEvent(event, arg1, arg2, arg3, arg4) ChatFrame1:AddMessage("OnEvent dans le fichier lua.") end
ChatFrame1:AddMessage("Passage 4 du file d'exécution dans le fichier lua.")
Vous pouvez voir des ligne en plus composées de : ChatFrame1:AddMessage("Avec du text ici.") Cette ligne va afficher du text dans la première fenêtre de votre t'chat box, et donc : ChatFrame2:AddMessage("Avec du text ici.") va l'afficher dans la seconde, à savoir votre journal de combat.
Voila ce que ça donne en se connectant ou en faisant un ReloadUI :

Quand on est programmeur il faut être curieux, en écrivant ce tuto, j'essaye encore des chose que je n'est pas essayé depuis que je code des addons :
Je change le fichier .toc en :

J'ai inversé l'ordre des deux fichiers, car que sait que l'ordre est important et je voulais voir la différence visuelle que cela causerait.
Et voila ce que ça donne :
 Conclusion :
Je vais pas faire une conclusion spécialement étendue car je n'en voit pas l'intérêt, on voit que le fichiers .lua est lut deux fois, dans un ordre différent en fonction de l'ordre dans le fichier .toc, on peut donc comparer avec la théorie que j'ai écrit plus haut et affiner ses propres conclusions, chacun pense ce qu'il veut du fonctionnement interne de wow, avec sa propre rétro-ingénierie. Et clairement je ne sais pas pourquoi le fichier .lua est lu une seconde fois.
Mais je vais quand même faire un dernier essaie avant de repasser sur le déroulement normal du tuto "faire des addons" car là on est plus dans "comprendre wow". Donc la même, avec des visuel plus précis :
Conclusion :
Rapide encore une fois ; comme tout les affichages sont cette fois dans la même fenêtre, et avec un affichage contrôler, cela ne flood plus l'écran, et on comprend mieux l'ordonnance des appels fait par le jeu, et ça aide à mieux coder ses addons. Allez un p'tit dernier ^^, avec le calcul des FPS :
Comme ça on prouve que le calcul des addons est bien fait entre chaque image du jeu.
Nouveau fichier .lua :

- Code: Tout sélectionner
local Current = 0 local Update = 0 local Refresh = 1 local framePerSecond = 0
local FirstUpdate = false
ChatFrame1:AddMessage("Passage 1 du file d'exécution dans le fichier lua.")
function MonAddon_MainFrame_OnLoad() ChatFrame1:AddMessage("OnLoad dans le fichier lua.") end
ChatFrame1:AddMessage("Passage 2 du file d'exécution dans le fichier lua.")
function MonAddon_MainFrame_OnUpdate(arg1) if FirstUpdate == false then ChatFrame1:AddMessage("OnUpdate premier passage.") FirstUpdate = true end framePerSecond = framePerSecond + 1 Current = Current + arg1 if (Current > (Update + Refresh)) then ChatFrame1:AddMessage("OnUpdate : " .. tostring(math.floor(Current)) .. ", framePerSecond : " .. tostring(framePerSecond)) Update = Current framePerSecond = 0 end end
ChatFrame1:AddMessage("Passage 3 du file d'exécution dans le fichier lua.")
function MonAddon_MainFrame_OnEvent(event, arg1, arg2, arg3, arg4) ChatFrame1:AddMessage("OnEvent dans le fichier lua.") end
ChatFrame1:AddMessage("Passage 4 du file d'exécution dans le fichier lua.")
Ce qui nous donne :
 Conclusion :
Là c'est très intéressant, car on voit entre l'OnUpdate premier passage, et le second passage dans OnUpdate il n'y a que 3 images d'écart.
J'ai fais d'autres tests de mon côté en m'étant les mêmes textes mais dans d'autres addons, dont un au début de la liste des addons, quand on est sur la liste de nos personnages, et du textes dans un addon à la fin de la liste, et on voit bien l'ordre d'appel des addons qui respect l'ordre de la liste d'addon, c'est par ordre alphabétique.
Faire du visuel Enfin ^^.
Plus haut on a vu qu'une frame c'est le conteneur de base dans l'interface de wow, elle à une position et une dimension, on va voir ça en code tout de suite. Donc retirez tout ce qui affiche du text on reviens avec un addon vide, je garde juste le code qui "mesure" le temps.
Fichier .lua :

- Code: Tout sélectionner
local Current = 0 local Update = 0 local Refresh = 1
local frame local texture local fontString
function MonAddon_MainFrame_OnLoad() frame = CreateFrame("Frame", "FrameName", UIParent) frame:SetPoint("TopLeft", UIParent, "TopLeft", 0, -200) frame:SetWidth(400) frame:SetHeight(400) texture = frame:CreateTexture() texture:SetParent(frame) texture:SetPoint("TopLeft", frame, "TopLeft", 0, 0) texture:SetWidth(frame:GetWidth()) texture:SetHeight(frame:GetHeight()) texture:SetTexture(1, 1, 1, 1) fontString = frame:CreateFontString() fontString:SetParent(frame) fontString:SetFont("Fonts\\FRIZQT__.TTF", 20) fontString:SetText("Hello World !") fontString:SetPoint("Center", frame, "Center", 0, 0) fontString:SetTextColor(0, 0, 0, 1) end
function MonAddon_MainFrame_OnUpdate(arg1) Current = Current + arg1 if (Current > (Update + Refresh)) then Update = Current end end
function MonAddon_MainFrame_OnEvent(event, arg1, arg2, arg3, arg4) end
Voila le résultat :

Explication :
Donc la frame contient la texture, et la fontString. Une texture doit juste afficher une couleur ou une image, une image du jeu genre l'icone d'un sort, ou une image à vous stocké dans le dossier de l'addon, et une fontString affiche du text.
Quand je dit "la frame contient la texture et la fontString", c'est un peu un abus de langage car, c'est juste de l'architecture, car si vous donnez à la texture une position en x plus grande que la largeur de la frame, ça vas quand même fonctionne, à vous de savoir ce que vous voulez. La documentation :
Si vous ne savez pas comment marche une fonction, démerdez vous avec la documentation, vous allez dans google et vous tapez "wow api SetPoint" pour la fonction SetPoint donc ici vous prenez le premier lien et vous lisez pendant 5 minutes ou moins ou plus et vous faites des tests pendant le temps qu'il vous faut pour comprendre le bordel.
Je vous ai linké trois sites plus, qui vous aideront à coder des addons. Voila des page qui appartiennent à ces site, qui vous aideront :
C'est dans ces deux liens que vous passerez énormément de temps à chercher comment faire quelques chose. SetTexture :
Pour afficher une image du jeu, remplacer la ligne 20 par :
- Code: Tout sélectionner
texture:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
Résultat :

Et j'ai changé la couleur du texte à la ligne 27 :
- Code: Tout sélectionner
fontString:SetTextColor(0, 1, 0, 1)
======================================================================
Pour afficher une image à vous, remplacer la ligne 20 par ces deux lignes :
- Code: Tout sélectionner
texture:SetTexture("Interface\\Addons\\MonAddon\\TargetIcons", true) texture:SetTexCoord(0, 0, 0, 1, 1, 0, 1, 1)
Votre image doit être placer dans le dossier de votre addon, vous pouvez même piquer les images qui sont dans le dossiers des autres addons.
Renseignez vous pour comprendre la fonction SetTexCoord(), elle sert à choisir la zone de l'image qui sera affichée, par exemple pour afficher juste le crâne, et pas toute l'image.
Résultat:

À chaque fois que vous rajouter une image dans le dossier de votre addon, vous devez relancer le jeu, car le jeu ne le sait pas, car il ne revérifie pas si le contenu du dossier Interface à changer une fois le jeu lancer, et un ReloadUI n'y changera rien.
Vous voyez aussi que l'image s'est adapté aux dimensions de la texture, ça l'a "tordu" horizontalement, à vous de gérer l'esthétisme. Le format de l'image et ses caractéristiques :
Wow peut charger des .png et des .blp, perso j'utilise des .blp, car durant mes premiers essais j'ai plus souvent réussi à faire fonctionner mes images en jeu avec des .blp qu'avec des .png, mais les deux fonctionnent si on sait comment faire.
Pour transformer une image en .blp il faut un logiciel, j'utilise BLP2PNG.exe, lisez le fichier Readme.txt, il est pas long, et sinon vous risquez de perdre un peu de temps ^^.
Et le détail QUI TUE TOUT, les image doivent être de largeur et de hauteur en puissance de 2 xD, elles peuvent être de forme rectangulaire mais de largeur et hauteur en puissance de 2, sinon wow ne les chargera pas, ça à beau être écrit dans la documentation de la fonction SetTexture() ça saute vraiment pas aux yeux. Conclusion pour faire du visuel :
Pour faire du visuel, vous pouvez le faire en lua comme je vous montre, mais vous pouvez aussi le faire en xml dans le fichier .xml, à vous de voir ce que vous préférez.
Pour faire un addon il faut un très grand nombre de frame, de texture, de fontString et d'autre objet que je vais détailler plus loin. C'est à vous de savoir comment vous devez faire votre addon, où vous allez mettre telle frame et telle texture.
Par exemple dans un addon d'interface de raid, la barre de vie des joueurs est faite avec une frame et une texture dedans, et si la vie du joueur baisse il faut réduire la largeur de la frame et de la texture pour le voir visuellement, pareil pour la barre de mana, et si le joueur qui utilise cet addon veut changer la couleur de la barre de vie des rogues car il trouve le jaune trop flashy il faut tout un bordel d'architecture et une interface d'option interne à l'addon, et là on commence à bien se faire chier avec des frame dans tout les sens, et s'il veut rajouter un dégrader sur les barres de vie des joueurs il faut mixé l'affichage avec la fonction Texture:SetGradientAlpha().
Les objets qui existent pour faire vos addons
Les scripts handlers attachés aux objets Les script handler sont des scripts qui sont exécutés lors d'une action de l'utilisateur avec sa sourie et son clavier sur votre addon (frame, texture et autre objet). Allez en bas de la page de la documentation de la frame et vous verrez la catégorie script handler. On peut voir un script handler qui s'appel OnMouseUp, c'est plutôt intéressant ^^. Il y a une catégorie script handler pour chaque objet, sauf les texture je crois, mais comme on met les textures dans des frames, ce n'est pas un soucis.
Donc voila comment afficher un text quand on clique sur une frame :

- Code: Tout sélectionner
local Current = 0 local Update = 0 local Refresh = 1
local frame local texture local fontString
local function OnMouseDown(self, button) ChatFrame1:AddMessage("un text méthode 1") end
function MonAddon_MainFrame_OnLoad() frame = CreateFrame("Frame", "FrameName", UIParent) frame:SetPoint("TopLeft", UIParent, "TopLeft", 0, -200) frame:SetWidth(400) frame:SetHeight(400) texture = frame:CreateTexture() texture:SetParent(frame) texture:SetPoint("TopLeft", frame, "TopLeft", 0, 0) texture:SetWidth(frame:GetWidth()) texture:SetHeight(frame:GetHeight()) texture:SetTexture(1, 1, 1, 1) fontString = frame:CreateFontString() fontString:SetParent(frame) fontString:SetFont("Fonts\\FRIZQT__.TTF", 20) fontString:SetText("Hello World !") fontString:SetPoint("Center", frame, "Center", 0, 0) fontString:SetTextColor(0, 0, 0, 1) -- METHODE 1 frame:SetScript("OnMouseDown", OnMouseDown) -- METHODE 2 frame:SetScript("OnMouseDown", function() ChatFrame1:AddMessage("un text méthode 2") end) frame:EnableMouse(true) end
function MonAddon_MainFrame_OnUpdate(arg1) Current = Current + arg1 if (Current > (Update + Refresh)) then Update = Current end end
function MonAddon_MainFrame_OnEvent(event, arg1, arg2, arg3, arg4) end
Résultat :

Ça fonctionne de la même manière pour tout les scripts handlers, vous utilisez la fonction SetScript sur l'objet en question et basta.
N'oubliez pas le frame:EnableMouse(true) (ligne 40) si votre frame ne sera pas utilisable par la sourie, malgrés le fait de lui affecté un script handler lié à la sourie.
Je vous ai montré deux méthodes ligne 33 et 36, les deux fonctionnent, je vous les montre pour deux raisons, la première pour vous montrer les possibilités d'utilisation du lua, et la seconde pour vous montrez que le SetScript de la méthode 2 à écrase le SetScript de la méthode 1.
Sauf que ça pose un problème quand vous faites un SetScript sur un objet qui n'est pas à vous, car en utilisant la fonction SetScript pour le script handler OnMouseUp vous allez peut être écraser un précédent script handler OnMouseUp qui était déjà là, et donc c'est la transition parfaite pour parler des hooks qui permet d'éviter ça.
Le LUA dans wow Le lua est un langage de programmation, voila le site officiel du langage, mais ne vous attardez pas trop dessus, car on a pas besoin de plus de 1% de la somme d'information gigantesque de ce site.
Édit : Pour apprendre juste ce qu'il faut sur le lua allez sur ce site.
Les limites du lua dans wow, et comment les dépasser :
Dans wow le lua à était limité par blizzard. De base avec le lua ont peut lire et écrire dans les fichiers, se balader dans les dossiers de votre ordinateur, ouvrir des programmes, communiquer avec des serveurs extérieur etc.., mais blizzard a retiré toutes ces fonctions quand on utilise le lua dans wow pour faire des addons, et heureusement sinon on pourrait coder des virus grâce aux addons.
Donc c'est mieux comme ça, mais ça retire un peu de liberté au développeur d'addon, par exemple pour l'addon GTS (GuildToolS), qui stock tout les items de la banque de guilde grâce aux SaveVariables expliqué au dessus. Cet addon créé une page .html qu'on peut mettre sur un serveur ftp pour voir très joliment ce que contient notre bdg, mais comment ils ont fait ? vu que blizzard à rendu impossible la communication entre les addons et "l'extérieur de wow", l'addon GTS ne créé pas la page .html directement.
Les mecs qui ont fait GTS, on aussi coder avec le langage C, un programme (un .exe) qu'ils ont mis à disposition dans l'addon, et son but est de lire les fichier contenant les SaveVariables pour retrouver tout les items écrit et sauvegardé par l'addon. Donc on peux communiquer avec l'extérieur mais c'est chiant.
Pareil pour les mecs qui ont fait le site RealmPlayer RealmStat, il ont un programme extérieur à wow qui envois les SaveVariables de SW_Stats sur leur serveur, et ensuite ils font un graphique avec les courbes de dps.
super topic t'es un monstre
arrogant et insupportable en bg
Thx, thx, yep mais je trouverai sans doute des choses à rajouter plus tard ^^.
Ya de l'activité chez toi pour prendre le temps de nous pondre ça !! Avec mauvais jeux de mot bien entendu !
Pas des masses, c'est les vacances ^^. Mais ça ne m'a pris en tout que 10 heures d'écriture réparties sur 1.5 jours, vu que je connais le sujet c'était rapide.
Ouh la ! Petite mine d'or ça ! Merci tu m'éclaircis sur des points qui me posaient problème :) Nice topic ty ^^
Merci pour ce super guide ! Il m'a vraiment aidé à débuter !
Ça serait chouette d'avoir une petite liste des boucles logiques et des arguments qui sont disponibles en lua sur WoW. Est ce qu'on peut faire une boucle while ? For ? et comment. Ce genre de chose :) Comme tu l'as expliqué dans ta dernière partie, la masse d'information sur le lua est très importante et ce n'est pas forcement facile de s'y retrouver, et encore plus de faire le tri avec ce qui est faisable sur WoW !
|
|
Kradh
<Danse avec les Loots>
|
|
|
Kradh
<Danse avec les Loots>
|
|