comparison SayIt.lua @ 0:24f337b9dfa0

Initial commit, testing .pkgmeta
author contrebasse
date Sun, 08 May 2011 17:11:26 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:24f337b9dfa0
1 --[[ TODO :
2 - Changer la couleur pour toutes les fenêtres de quête (possible ?)
3 - Chercher le texte pour les couleurs à partir de la somme des longueurs de texte précédents (incrémental), compliqué !
4 - Modifier les variables statiques directement dans la fonction Paragraphes() (Bof...)
5 - Traduction
6 - Clic droit pour phrase perso
7 - Shif clic droit pour emote
8 - griser le choix des couleurs si pas de coloration
9 - reset des options (virer les couleurs foireuses...)
10 --]]
11
12 --********************************************************
13 --
14 -- Déclarations de variables
15 --
16 --********************************************************
17 --
18 -- Variables statiques
19 --
20 local target_name = "" -- "" vide ou nom du npc
21 local text_table = {} -- table du texte à dire
22 local text_full = ''
23 local i_phrase = 1 -- indice de la prochaine phrase à dire
24 --local char_dits = 0 -- nombre de caractères prononcés, pour améliorer la recherche lors de la coloration
25 local max_phrase = 0 -- indice du nombre de phrases à dire
26 local gossip_button, quest_button, current_button
27 local TextFrame
28
29 --
30 -- Fonctions locales pour accélérer l'exécution
31 --
32 local _G = _G
33 local GetUnitName = GetUnitName
34 local GetQuestText = GetQuestText
35 local GetProgressText = GetProgressText
36 local GetGossipText = GetGossipText
37 local GetRewardText = GetRewardText
38 local DEFAULT_CHAT_FRAME = DEFAULT_CHAT_FRAME
39 local UIErrorsFrame,UIErrorsFrame_OnEvent = UIErrorsFrame,UIErrorsFrame_OnEvent
40 local SendChatMessage = SendChatMessage
41 local GameTooltip = GameTooltip
42 local CreateFrame = CreateFrame
43 local IsShiftKeyDown,IsControlKeyDown = IsShiftKeyDown,IsControlKeyDown
44 local GossipFrame,QuestFrame = GossipFrame,QuestFrame
45 local GossipGreetingText = GossipGreetingText
46 local QuestProgressText = QuestProgressText
47 local GameTooltip_SetDefaultAnchor = GameTooltip_SetDefaultAnchor;
48
49 local tonumber = tonumber;
50 local string = string;
51 local string_format = string.format;
52
53 local LibStub = LibStub;
54
55 --********************************************************
56 --
57 -- Fonctions de debug et warning
58 --
59 --********************************************************
60 --
61 -- fonction qui affiche des messages de debug
62 --
63 local function DEBUG(msg)
64 --if true then return end
65 if not msg then msg="nil" end
66 DEFAULT_CHAT_FRAME:AddMessage("(DEBUG) " .. msg);
67 end
68
69 local function Warn(msg)
70 if not msg then return end
71 --DEFAULT_CHAT_FRAME:AddMessage("(SayIt) "..msg);
72 local event = "UI_INFO_MESSAGE"
73 UIErrorsFrame_OnEvent(UIErrorsFrame, event, msg)
74 end
75
76
77 --********************************************************
78 --
79 -- Analyse de texte
80 --
81 --********************************************************
82 --
83 -- Function qui sépare les paragraphes/phrases d'un texte en éléments de tableau
84 --
85 local function Paragraphes(txt)
86 -- Si pas de texte, pas la peine de continuer
87 if not txt or txt=="" then
88 return {}, 0
89 end
90
91 local text = {}
92 local p = 1
93 for paragraph in txt:gmatch("[^\r\n]+") do
94 -- On enlève au texte le double '|', le nom du Npc le " dit : " et un caractère en plus (fin de string ?)
95
96 -- Est-ce une émote ?
97 local e = (paragraph:sub(1,1)=="<" and paragraph:sub(-1)==">")
98 local t,Nchar_supp
99 if e then
100 Nchar_supp = 2
101 t = paragraph:sub(2,-2) -- on vire les < >
102 else
103 Nchar_supp = 9+target_name:len()
104 t = paragraph
105 end
106
107 -- Coupe par phrase
108 -- [.!?]+ : au moins un signe de ponctuation, permet de gérer ... !? ?! par exemple
109 -- [^%s][^%s]%s* : le dernier mot de la phrase dois avoir au moins 2 caractères, pour éviter de couper "M. Dupont" (pas parfait mais mieux que rien)
110 -- on transforme chaque phrase en paragraphe, et on repasse le test précédent
111 for tt in t:gsub('([^%s][^%s]%s*[%.%!%?]+)(%s+)(%u)','%1\n%3'):gmatch('[^\r\n]+') do --for tt in t:gmatch('(.-[.!?]+)%s*') do
112 text[p] = { -- Le texte est coupé au cas où...
113 ["texte"] = tt:sub(1,254-Nchar_supp), -- ça devrait être 255, mais ça ne passe pas...
114 ["emote"] = e }
115 p = p+1
116 end
117 end
118
119 return text, p-1
120 end
121
122 --
123 -- Coloration du texte de la fenêtre
124 --
125 local cDit = "|cff".."606060" -- gris clair
126 local cJusteDit = "|cff".."7f0000" -- gris foncé
127 local cADire = "|cff".."00007f" -- jaunasse
128 local cNonDit = "|cff".."202020" -- noir
129
130 local function SpecialChar(txt)
131 return txt and txt:gsub('([%(%)%.%+%-%*%?%[%^%$%]])','%%%1') or ''
132 end
133 local function ColorieTexte(txt)
134 --print('______')
135 local tJusteDit,tADire
136 if i_phrase > 1 then
137 tJusteDit = text_table[i_phrase-1].texte
138 end
139 if i_phrase <= max_phrase then
140 tADire = text_table[i_phrase].texte
141 end
142
143 --print(txt)
144 --print('^(.*)('..SpecialChar(tJusteDit)..')(.-)('..SpecialChar(tADire)..')(.*)$')
145 local _,_,tDit,tJusteDit2,space,tADire2,tNonDit = txt:find('^(.-)('..SpecialChar(tJusteDit)..')(.-)('..SpecialChar(tADire)..')(.*)$') --,char_dits)
146
147 --print('tDit:'..(tDit or ''))
148 --print('tJusteDit2:'..(tJusteDit2 or ''))
149 --print('tADire2:'..(tADire2 or ''))
150 --print('tNonDit:'..(tNonDit or ''))
151
152 return (tDit and SayItOptions.cDit..tDit..'|r' or '' )..
153 (tJusteDit and SayItOptions.cJusteDit..tJusteDit..'|r' or '' )..
154 (space or '')..(tADire and SayItOptions.cADire..tADire..'|r' or '' )..
155 (tNonDit and SayItOptions.cNonDit..tNonDit..'|r' or '' )
156 end
157
158 --
159 -- Faire parler un Npc
160 --
161 local function NpcDit(txt)
162 if not txt then return end
163 if not txt.emote then
164 SendChatMessage("\124\124 "..GetUnitName("Npc").." dit : "..
165 txt.texte,"EMOTE")
166 else
167 SendChatMessage("\124\124 "..txt.texte,"EMOTE")
168 return
169 end
170 end
171
172
173 --********************************************************
174 --
175 -- Boutons et tooltips
176 --
177 --********************************************************
178 --
179 -- Remplissage du tooltip
180 --
181 local function TooltipUpdate(b)
182 if max_phrase>0 then
183 -- Coloration du texte dans la fenêtre
184 if TextFrame and SayItOptions.colorisation == 2 then
185 TextFrame:SetText(ColorieTexte(text_full))
186 end
187
188 -- tooltip
189 if not SayItOptions.tooltip then return end
190
191 if SayItOptions.ancre_tooltip then
192 GameTooltip:SetOwner(b,"ANCHOR_BOTTOMRIGHT")-- Position du tooltip
193 else
194 GameTooltip_SetDefaultAnchor(GameTooltip, b)
195 end
196
197 -- texte du tolltip
198 GameTooltip:SetText(target_name,1,1,1) -- Nom du Pnj
199 if SayItOptions.texte_tooltip then
200 local txt = ""
201 if i_phrase <= max_phrase then
202 if not text_table[i_phrase].emote then
203 GameTooltip:AppendText(" va dire :")
204 else
205 GameTooltip:AppendText(" :")
206 end
207 txt = text_table[i_phrase].texte
208 GameTooltip:AddLine('"'..txt..'"',1,0.82,0,true)
209 else
210 GameTooltip:AppendText(" a terminé.")
211 end
212 end
213
214 -- Raccourcis
215 if SayItOptions.raccourcis_tooltip then
216 GameTooltip:AddLine(" ")
217 if i_phrase <= max_phrase then
218 GameTooltip:AddDoubleLine("Dire la phrase","Clic gauche",1,1,1,1,1,1)
219 end
220 if i_phrase>1 then
221 GameTooltip:AddDoubleLine("Phrase précédente","Ctrl+Clic/Roulette haut",1,1,1,1,1,1)
222 end
223 if i_phrase <= max_phrase then
224 GameTooltip:AddDoubleLine("Sauter la phrase","Shift+Clic/Roulette bas",1,1,1,1,1,1)
225 end
226 end
227 GameTooltip:Show()
228 else
229 GameTooltip:SetText("")
230 GameTooltip:Hide()
231 end
232 end
233
234 --
235 -- Créations des boutons, avec les fonctions des clics/mouseover
236 --
237 local function CreerBouton(parent)
238 local button = CreateFrame("Button", parent:GetName().."SayButton", parent, "UIPanelButtonTemplate")
239 button:SetText("Dire")
240 button:SetHeight(22)
241 button:SetWidth(button:GetTextWidth() + 40)
242 button:SetPoint("BOTTOM",parent,"BOTTOM",-9,72)
243
244 -- Set the frame level of the gossip_button to be 1 deeper than its parent
245 local buttonparent = button:GetParent()
246 local framelevel = buttonparent:GetFrameLevel()
247 local framestrata = buttonparent:GetFrameStrata()
248 button:SetFrameLevel(framelevel + 1)
249 button:SetFrameStrata(framestrata)
250 button:Enable()
251
252 -- Action du bouton
253 button:RegisterForClicks("LeftButtonUp")
254 button:EnableMouseWheel(true)
255 button:SetScript("OnClick",function(self, button, down)
256 -- état des modificateurs
257 local shiftDown = IsShiftKeyDown();
258 local ctrlDown = IsControlKeyDown();
259
260 -- On évite le cas foireux
261 if shiftDown and ctrlDown then return end
262
263 -- lecture phrase actuelle
264 if not shiftDown and not ctrlDown and i_phrase<=max_phrase then
265 NpcDit(text_table[i_phrase])
266 end
267
268 -- Passage phrase suivante
269 if ctrlDown then
270 if i_phrase==1 then
271 Warn("Le début du texte est atteint.")
272 else
273 i_phrase = i_phrase-1
274 --char_dits = char_dits - text_table[i_phrase].texte:len()
275 if TextFrame and SayItOptions.colorisation == 3 then
276 TextFrame:SetText(ColorieTexte(text_full))
277 end
278 end
279 else
280 if i_phrase>max_phrase then
281 Warn("La fin du texte est atteinte.")
282 else
283 --char_dits = char_dits + text_table[i_phrase].texte:len()
284 i_phrase = i_phrase+1
285 if TextFrame and SayItOptions.colorisation == 3 then
286 TextFrame:SetText(ColorieTexte(text_full))
287 end
288 end
289 end
290
291 -- Mise à jour du texte du tooltip
292 TooltipUpdate(self)
293 end)
294 button:SetScript("OnMouseWheel", function(self, delta)
295 -- Passage phrase suivante
296 if delta==1 then
297 if i_phrase==1 then
298 Warn("Le début du texte est atteint.")
299 else
300 i_phrase = i_phrase-1
301 --char_dits = char_dits - text_table[i_phrase].texte:len()
302 if TextFrame and SayItOptions.colorisation == 3 then
303 TextFrame:SetText(ColorieTexte(text_full))
304 end
305 end
306 else
307 if i_phrase>max_phrase then
308 Warn("La fin du texte est atteinte.")
309 else
310 --char_dits = char_dits + text_table[i_phrase].texte:len()
311 i_phrase = i_phrase+1
312 if TextFrame and SayItOptions.colorisation == 3 then
313 TextFrame:SetText(ColorieTexte(text_full))
314 end
315 end
316 end
317
318 -- Mise à jour du texte du tooltip
319 TooltipUpdate(self)
320 end)
321
322
323 -- Tooltip
324 button:SetScript("OnEnter", TooltipUpdate)
325 button:SetScript("OnLeave", function()
326 GameTooltip:Hide()
327 if TextFrame and SayItOptions.colorisation == 2 then
328 TextFrame:SetText(text_full)
329 end
330 end)
331
332 return button
333 end
334
335
336 --********************************************************
337 --
338 -- Gestion des events
339 --
340 --********************************************************
341 --
342 -- fonction lancée au chargement de l'add-on
343 --
344 function _G.SayIt_OnLoad(self,...)
345 -- Création des deux boutons
346 gossip_button = CreerBouton(GossipFrame)
347 quest_button = CreerBouton(QuestFrame)
348
349 -- Pour ne pas avoir de warning avec findglobals
350 -- GLOBALS: this
351 -- Events à suivre
352 SayItFrame:RegisterEvent("GOSSIP_SHOW"); -- Affiche fenêtre Gossip
353 SayItFrame:RegisterEvent("GOSSIP_CLOSED"); -- Ferme fenêtre gossip (peut-être appelé juste avant l'ouverture d'une quête)
354 SayItFrame:RegisterEvent("QUEST_DETAIL"); -- Nouvelle quête
355 SayItFrame:RegisterEvent("QUEST_PROGRESS"); -- Quête en cours, non terminée
356 SayItFrame:RegisterEvent("QUEST_COMPLETE"); -- Quête en cours et terminée
357 SayItFrame:RegisterEvent("QUEST_FINISHED"); -- Fermeture fenêtre quête
358 --"QUEST_GREETING" ?
359 end
360
361 --
362 -- fonction appelée quand il y a un event
363 --
364 function _G.SayIt_OnEvent(self, event, ...)
365 --DEBUG("Event:"..event)
366 --Warn(event)
367
368 if ( event=="GOSSIP_CLOSED" or event=="QUEST_FINISHED") then
369 -- Reset
370 target_name = ""
371 text_full = nil
372 current_button = nil
373 TextFrame = nil
374
375 elseif event=="GOSSIP_SHOW" then
376 target_name = GetUnitName("Npc")
377 text_full = GetGossipText()
378 current_button = gossip_button
379 TextFrame = GossipGreetingText
380
381 elseif event=="QUEST_DETAIL" then
382 target_name = GetUnitName("Npc")
383 text_full = GetQuestText();
384 current_button = quest_button
385 TextFrame = nil
386
387 elseif event=="QUEST_PROGRESS" then
388 target_name = GetUnitName("Npc")
389 text_full = GetProgressText();
390 current_button = quest_button
391 TextFrame = QuestProgressText
392
393 elseif event=="QUEST_COMPLETE" then
394 target_name = GetUnitName("Npc")
395 text_full = GetRewardText();
396 current_button = quest_button
397 TextFrame = nil
398
399 --elseif event=="QUEST_GREETING" then
400 -- GetGreetingText()
401 --GreetingText
402 else return
403 end
404
405 -- On ne sait jamais (ça arrive quand la fenêtre ne s'ouvre pas parce que celle des options est ouverte, par exemple)
406 if not target_name or not text_full or not current_button then
407 return
408 end
409
410 -- Reset de l'indice
411 i_phrase = 1
412 --char_dits = 0
413
414 -- Découpage du texte en paragraphes/phrase
415 text_table, max_phrase = Paragraphes(text_full)
416
417 -- Affichage en couleur
418 if TextFrame and SayItOptions.colorisation == 3 then
419 TextFrame:SetText(ColorieTexte(text_full))
420 end
421 end
422
423
424 --********************************************************
425 --
426 -- Ace 3.0
427 --
428 --********************************************************
429 -- http://www.wowace.com/addons/ace3/pages/getting-started/
430
431 -- Enregistrement comme add-on
432 local SayIt = LibStub("AceAddon-3.0"):NewAddon("SayIt")
433 --
434 -- Ace Config
435 --
436 local function Hex2Val(h)
437 if not h then return 0,0,0 end
438 return tonumber(h:sub(5,6),16)/255, tonumber(h:sub(7,8),16)/255, tonumber(h:sub(9,10),16)/255
439 end
440 local function Val2Hex(r,g,b)
441 return string_format("|cff%02x%02x%02x",(r or 0)*255,(g or 0)*255,(b or 0)*255)
442 end
443 local options = {
444 type = "group",
445 args = {
446 tooltip_header = {
447 name = "Tooltip",
448 type = "header",
449 order = 80
450 },
451 activer_tooltip = {
452 name = "Afficher le tooltip",
453 desc = "Affiche un tooltip pour le bouton \"Dire\"",
454 type = "toggle",
455 get = function() return SayItOptions.tooltip end,
456 set = function(info,state) SayItOptions.tooltip = state end,
457 width = "full",
458 order = 81
459 },
460 montrer_texte = {
461 name = "Afficher le texte dans le tooltip",
462 desc = "Affiche le texte qui va être dit pas le pnj dans le tooltip du bouton \"Dire\"",
463 type = "toggle",
464 get = function() return SayItOptions.texte_tooltip end,
465 set = function(info,state) SayItOptions.texte_tooltip = state end,
466 width = "full",
467 order = 82
468 },
469 montrer_raccourcis = {
470 name = "Afficher les raccourcis dans le tooltip",
471 desc = "Affiche les raccourcis dans le tooltip du bouton \"Dire\"",
472 type = "toggle",
473 get = function() return SayItOptions.raccourcis_tooltip end,
474 set = function(info,state) SayItOptions.raccourcis_tooltip = state end,
475 width = "full",
476 order = 83
477 },
478 ancre_tooltip = {
479 name = "Ancrer le tooltip au bouton",
480 desc = "Ancre le tooltip au bouton \"Dire\". Sinon, il sera dans sa position par défaut.",
481 type = "toggle",
482 get = function() return SayItOptions.ancre_tooltip end,
483 set = function(info,state) SayItOptions.ancre_tooltip = state end,
484 width = "full",
485 order = 84
486 },
487 couleur_header = {
488 name = "Couleurs des textes",
489 type = "header",
490 order = 99
491 },
492 o100 = {
493 name = "|cffffd100Remarque :|r La colorisation ne marche pas pour les fenêtres d'acceptation et de rendu de quête.\n",
494 type = "description",
495 order = 100
496 },
497 colorier = {
498 name = "Colorisation",
499 desc = "Colore le texte dans la fenêtre du pnj.",
500 --descStyle = 'inline',
501 type = "select",
502 values = {
503 "Aucune",
504 "Sous la souris",
505 "Toujours"
506 },
507 style = 'radio',
508 get = function() return SayItOptions.colorisation end,
509 set = function(info,val) SayItOptions.colorisation = val end,
510 order = 101
511 },
512 o102 = {
513 name = "\n|cffffd100Couleurs utilisées lors de la colorisation des textes|r",
514 type = "description",
515 order = 102
516 },
517 couleur_cDit = {
518 name = "Texte déjà dit",
519 desc = "Couleur dans laquelle apparaitra le texte que le pnj a déjà dit.",
520 type = "color",
521 get = function() return Hex2Val(SayItOptions.cDit) end,
522 set = function(info,r,g,b) SayItOptions.cDit = Val2Hex(r,g,b) end,
523 width = "full",
524 order = 103
525 },
526 couleur_cJusteDit = {
527 name = "Texte tout juste dit",
528 desc = "Couleur dans laquelle apparaitra le texte que le pnj vient de dire.",
529 type = "color",
530 get = function() return Hex2Val(SayItOptions.cJusteDit) end,
531 set = function(info,r,g,b) SayItOptions.cJusteDit = Val2Hex(r,g,b) end,
532 width = "full",
533 order = 104
534 },
535 couleur_cADire = {
536 name = "Texte qui va être dit",
537 desc = "Couleur dans laquelle apparaitra le texte que le pnj dira la prochaine fois.",
538 type = "color",
539 get = function() return Hex2Val(SayItOptions.cADire) end,
540 set = function(info,r,g,b) SayItOptions.cADire = Val2Hex(r,g,b) end,
541 width = "full",
542 order = 105
543 },
544 couleur_cNonDit = {
545 name = "Texte pas encore dit",
546 desc = "Couleur dans laquelle apparaitra le texte que le pnj n'a pas encore dit.",
547 type = "color",
548 get = function() return Hex2Val(SayItOptions.cNonDit) end,
549 set = function(info,r,g,b) SayItOptions.cNonDit = Val2Hex(r,g,b) end,
550 width = "full",
551 order = 106
552 }
553 }
554 }
555
556 function SayIt:OnInitialize()
557 -- Code that you want to run when the addon is first loaded goes here.
558
559 -- Application de la config par Ace
560 LibStub("AceConfig-3.0"):RegisterOptionsTable("SayIt".."BlizzOptions", options, {"sayit"})
561 LibStub("AceConfigDialog-3.0"):AddToBlizOptions("SayIt".."BlizzOptions","Say It")
562 LibStub("AceConfig-3.0"):RegisterOptionsTable("SayIt", function() return self:GetOptions() end) -- tiré de adibags
563
564 -- Récupération de la config...
565 if not SayItOptions then
566 SayItOptions = {}
567 end
568 if SayItOptions.tooltip==nil then
569 SayItOptions.tooltip = true
570 end
571 if SayItOptions.texte_tooltip==nil then
572 SayItOptions.texte_tooltip = true
573 end
574 if SayItOptions.raccourcis_tooltip==nil then
575 SayItOptions.raccourcis_tooltip = true
576 end
577 if SayItOptions.ancre_tooltip==nil then
578 SayItOptions.ancre_tooltip = true
579 end
580 if not SayItOptions.colorisation then
581 SayItOptions.colorisation = 2
582 end
583 if not SayItOptions.cDit then
584 SayItOptions.cDit = "|cff".."606060"
585 end
586 if not SayItOptions.cJusteDit then
587 SayItOptions.cJusteDit = "|cff".."7f0000"
588 end
589 if not SayItOptions.cADire then
590 SayItOptions.cADire = "|cff".."00007f"
591 end
592 if not SayItOptions.cNonDit then
593 SayItOptions.cNonDit = "|cff".."202020"
594 end
595 end
596
597 --function SayIt:OnEnable()
598 -- Called when the addon is enabled
599 --end
600
601 --function SayIt:OnDisable()
602 -- Called when the addon is disabled
603 --end
604