Skip to content

Instantly share code, notes, and snippets.

@BastienClement
Created April 1, 2016 13:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BastienClement/b6ee69cac5b521f43ae00f1453fc97b9 to your computer and use it in GitHub Desktop.
Save BastienClement/b6ee69cac5b521f43ae00f1453fc97b9 to your computer and use it in GitHub Desktop.
Archimonde Chaos
function(e, time, event, _, source, sourceName, _, _, dest, destName, _, _, spell, spellName)
if spell == 185014 and source and dest then
local Hud = FS.Hud
local key = source .. "_chaos_target"
if event == "SPELL_AURA_APPLIED" then
Hud:RemovePoint(key)
local source_pt = Hud:GetPoint(source)
if not source_pt then return end
local pt = Hud:CreateShadowPoint(dest, key)
function pt:Position()
local sx, sy = source_pt:Position()
local tx, ty = self.ref:Position()
if not sx or not tx then
return 0, 0
end
local dx, dy = tx - sx, ty - sy
local len = (dx * dx + dy * dy) ^ 0.5
local mul = 100 / (len + 0.00001)
return sx + dx * mul, sy + dy * mul
end
local line = Hud:DrawLine(source, pt, 128)
if UnitIsUnit("player", destName) or UnitIsUnit("player", sourceName) then
line:SetColor(0, 0.5, 0.8, 0.8)
else
function line:OnUpdate()
if self:UnitDistance("player") < 2 then
line:SetColor(0.8, 0, 0, 0.8)
else
line:SetColor(0, 0.8, 0, 0.5)
end
end
end
elseif event == "SPELL_AURA_REMOVED" then
Hud:RemovePoint(key)
end
end
end
local FS = LibStub("AceAddon-3.0"):GetAddon("FS")
if not FS then return end
local Hud = FS:GetModule("Hud")
-- Généralement il n'est pas nécessaire de passer par l'API d'AceAddon pour
-- récupérer l'objet FS et les modules.
--
-- FS est disponible comme variable globale, et FS.Hud est équivalent à
-- LibStub("AceAddon-3.0"):GetAddon("FS"):GetModule("Hud"), en plus court.
-- Il n'est pas nécessaire d'appeler cette fonction sauf si le but est d'activer
-- le HUD même s'il est désactivé dans les options.
Hud:Enable()
-------------------------------------------------------------------------------
-- Utils
-------------------------------------------------------------------------------
-- Tu n'utilise jamais la deuxième valeur de retour, tu pourrais substituer
-- les pack(...) par { ... } et éviter un appel de fonction
function pack(...)
return { ... }, select("#", ...)
end
-------------------------------------------------------------------------------
-- Database
-------------------------------------------------------------------------------
default = {
overrun = 100,
width = 256,
selfColor = { 0, 0.78, 1.0, 0.5 },
inColor = { 0.9, 0, 0.1, 0.5 },
outColor = { 0, 0.8, 0.1, 0.5 }
}
for k, v in pairs(default) do
if db[k] == nil then
db[k] = v
end
end
config = {
overrun = {
order = 1,
type = "range",
name = "Overrun",
min = 10,
max = 150,
step = 10,
get = function() return db.overrun end,
set = function(_, v) db.overrun = v end
},
width = {
order = 2,
type = "range",
name = "Width",
min = 64,
max = 512,
step = 64,
get = function() return db.width end,
set = function(_, v) db.width = v end
},
selfColor = {
order = 3,
type = 'color',
name = "Self Color",
hasAlpha = true,
get = function() return unpack(db.selfColor) end,
set = function(_, ...)
db.selfColor = ...
end
},
inColor = {
order = 4,
type = 'color',
name = "Inside Color",
hasAlpha = true,
get = function() return unpack(db.inColor) end,
set = function(_, ...)
db.inColor = ...
end
},
outColor = {
order = 5,
type = 'color',
name = "Outside Color",
hasAlpha = true,
get = function() return unpack(db.outColor) end,
set = function(_, ...)
db.outColor = ...
end
}
}
-------------------------------------------------------------------------------
-- Events
-------------------------------------------------------------------------------
--[[
Attention ici, d'un côté ton package est reloadable de l'autre tu crée une
frame dans l'initialisation du package. Les frames ne sont pas supprimée
contrairement aux variables classiques. Du coup à chaque reload du package,
tu crée une nouvelle frame. Aussi, puisque du ne debind pas les events de
l'ancienne frame, tu te retrouve après 3 reloads avec 3 frames executant
3 versions de ton addon. Probablement source de problèmes.
La solution à ça est de ne pas déclarer la frame local, de cette façon tu
pourra check lors du reload si f == nil et ne pas la créer si ce n'est pas
le cas.
]]
local f = CreateFrame("Frame", nil);
f:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED");
f:RegisterEvent("ENCOUNTER_START");
f:RegisterEvent("ENCOUNTER_END");
f:SetScript("OnEvent", function(self, event, ...)
self[event](self, ...)
end)
local ENCOUNTER_ID = nil
local RAYS = {}
function f:ENCOUNTER_START(encounterID, encounterName, difficultyID, raidSize)
ENCOUNTER_ID = encounterID
end
function f:ENCOUNTER_END(encounterID, encounterName, difficultyID, raidSize, endStatus)
ENCOUNTER_ID = nil
end
--[[
COMBAT_LOG_EVENT_UNFILTERED est un event relativement lourd qui trigger
considérablement plus que tous les autres. Du coup, vu que tu track les
débuts / fins d'encouter. Tu pourrais retirer le check dans CLEU et à la
place bind et débind CLEU dans tes listeners pour ENCOUNTER_START/_END.
]]
function f:COMBAT_LOG_EVENT_UNFILTERED(_, event, _, sourceGUID, sourceName, sourceFlags, sourceRaidFlags, destGUID, destName, destFlags, _, _, spellName, ...)
--[[
De façon générale track le spell par ID plutôt que nom est une solution
plus robuste si tu veux gérer des joueurs de différentes langues. Mais
ça marche aussi si t'es 100% qu'il n'y aura que des joueurs avec le jeu
en anglais.
]]
if spellName == "Focused Chaos" and ENCOUNTER_ID == 1799 then
-- RAYS ne peut pas être nil ici. Cette ligne ne fait jamais rien right?
RAYS = RAYS or {}
if event == "SPELL_CAST_START" then
--[[
NE JAMAIS APPELER CETTE FONCTION
Elle n'est pas documentée dans l'API du HUD volontairement.
Je ne pense pas que ça puisse avoir un effet néfaste, mais c'est
complétement inutile. Le HUD se charge lui-même de maintenir une
liste à jour des joueurs du raid.
]]
Hud:RefreshRaidPoints()
--[[
Idem, tu force ici le HUD à être visible. Le HUD est automatiquement
affiché lorsqu'au moins un objet est dessiné sur l'écran.
Puisque tu le force visible ici, tu es forcé de le masquer à la main
plus tard. Dès que tu auras plus d'un truc sur ton HUD ça va devenir
difficile de savoir quand l'afficher ou non si tu gère ça à la main.
Par ex: Archimonde avec
* Les Wrought Chaos
* Les timers des Doomfire
* Les Shackled Torments
* ...
Bref, ne gère pas la visibilité du HUD à la main.
]]
Hud:Show(true)
elseif event == "SPELL_AURA_APPLIED" then
local playerName, _ = UnitName("player")
local pt = Hud:CreateShadowPoint(destName)
-- Ici, l'utilisation de la table de config de Ace3 est étrange.
-- Les fonctions get/set sont là pour Ace, toi tu peux directement
-- accéder à db.width, db.overrun etc.
local width = config.width.get()
local overrun = config.overrun.get()
-- Un détail de plus ici, tu crées une nouvelle table à chaque fois
-- alors que config.selfColor/inColor/outColor sont déjà des tables
-- qui correspondent à ce que tu veux. Utilise directement db.selfColor
local selfColor = pack(config.selfColor.get())
local inColor = pack(config.inColor.get())
local outColor = pack(config.outColor.get())
function pt:Position()
--[[
Je suis pas fan d'ajouter des fonctions comme ça sur l'objet
HUD, déjà si c'est fait dans le fichier Hud.lua, tu auras des
problèmes lors de mises à jour. Et dans tous les cas, tu cours
le risque d'avoir une collision avec une foncton du même nom
que je pourrais rajouter par la suite.
]]
local vx, vy = Hud:Vector(sourceName, destName, overrun)
local x, y = self.ref:Position()
return x + vx, y + vy
end
local line = Hud:DrawLine(sourceName, pt, width)
function line:OnUpdate()
if sourceName == playerName or destName == playerName then
--[[
Il est possible de faire ce check en dehors du line:OnUpdate
et ne jamais définir une fonction qui sera évaluée toutes les
frames pour une condition qui ne change jamais.
]]
self:SetColor(unpack(selfColor))
elseif self:UnitDistance("player", true) < width * (1.0 / 64) then
--[[
Attention ici, UnitDistance(_, true) est en mode "strict"
et va retourner -1 si la projection du point du joueur sur
la ligne se trouve en dehors des deux bornes. Vu que tu test
<, si le joueur est derrière une ligne, il sera considéré
dedans.
Aussi la largeur de l'objet Line n'a pas de relation avec des
yards dans le jeu. Hors UnitDistance retourne une distance en
yards. Comparer les deux n'est peut être pas une bonne idée
surtout que l'abilité a une "vrai largeur" qui est celle qui
est importante.
]]
self:SetColor(unpack(inColor))
else
self:SetColor(unpack(outColor))
end
end
RAYS[destGUID] = { ["line"] = line } -- Peut être écrit { line = line }
elseif event == "SPELL_AURA_REMOVED" then
local ray = RAYS[destGUID]
if ray then
-- Pourquoi pas ray.line:Remove() ?
for _, v in pairs(ray) do
v:Remove()
end
RAYS[destGUID] = nil
if not next(RAYS) then
-- À nouveau, ça sera automatique lorsque la dernière ligne sera retirée
Hud:Hide()
end
end
end
end
end
--[[
Une note encore sur ta table RAY. Le Hud supporte un système de nommage des points et
des objets ainsi que des dépendences des objets sur les points qui les définissent.
Par exemple, tu peux donner un nom à CreateShadowPoint, par exemple:
local name = sourceGUID .. "_chaos_target"
Par la suite, tu peux créer des objets sur la base de ce point, par exemple la ligne.
Finalement, lorsque le debuff est retiré tu peux faire:
Hud:RemovePoint(sourceGUID .. "_chaos_target")
Le point défini va être supprimé sans avoir à garder une référence dessus. Et aussi,
puisque ta ligne dépend de ce point dans sa construction, elle sera supprimée avec.
Ce qui me fait remarquer que tes points ne sont jamais supprimés dans ta version.
Lorsque tu sauve ton objet ligne, il faudrait aussi sauver l'objet point. Ce qui
finalement revient au même que ce que j'expliquais, juste en gérant l'objet ligne
explicitement, ce qui est inutile.
Pour référence, je te donne mon implémentation du même module dans un fichier
à part. C'est un trigger custom WeakAuras sur COMBAT_LOG_EVENT_UNFILTERED.
Pacman n'existait pas encore.
Dans l'ensemble c'est pas mal !
Good job !
]]
function reload()
load("main.lua", true)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment