mirror of
https://github.com/Blaststar/Questie-Octo-Vanilla.git
synced 2026-10-20 20:30:49 +00:00
226 lines
7.7 KiB
Lua
226 lines
7.7 KiB
Lua
QuestieOcto.Visuals = QuestieOcto.Visuals or {}
|
|
local V = QuestieOcto.Visuals
|
|
|
|
local ICON_ROOT="Interface\\AddOns\\Questie-Octo\\UI\\Icons\\"
|
|
local TEX_GLOW=ICON_ROOT.."glow"
|
|
|
|
local function Settings()
|
|
return QuestieOcto.MinimapSettings
|
|
end
|
|
|
|
local function NextRandom(seed)
|
|
seed=math.mod(seed*214013+2531011,4294967296)
|
|
local value=math.mod(math.floor(seed/65536),32768)/32767
|
|
return seed,value
|
|
end
|
|
|
|
-- HSV->RGB (h in [0,360), s/v in [0,1]). Lua 5.0: math.mod is fmod and works on
|
|
-- floats, math.abs/math.floor are available.
|
|
local function HSVToRGB(h,s,v)
|
|
local c=v*s
|
|
local hp=h/60
|
|
local x=c*(1-math.abs(math.mod(hp,2)-1))
|
|
local r,g,b=0,0,0
|
|
if hp<1 then r,g,b=c,x,0
|
|
elseif hp<2 then r,g,b=x,c,0
|
|
elseif hp<3 then r,g,b=0,c,x
|
|
elseif hp<4 then r,g,b=0,x,c
|
|
elseif hp<5 then r,g,b=x,0,c
|
|
else r,g,b=c,0,x end
|
|
local m=v-c
|
|
return r+m,g+m,b+m
|
|
end
|
|
|
|
-- Full-wheel vivid colors. The previous scheme mapped each RGB channel into
|
|
-- [0.45,0.95], which clustered every roll near a light desaturated gray: little
|
|
-- variety and near-identical neighbours. Drawing a hue across the entire color
|
|
-- wheel with high saturation and brightness gives a far larger, more separable
|
|
-- gamut so overlapping quests/objectives are easy to tell apart, and re-rolling
|
|
-- (Full Node click) jumps to a clearly different color.
|
|
local function SeedColor(seed)
|
|
seed=tonumber(seed) or 0
|
|
local h,s,v
|
|
seed,h=NextRandom(seed)
|
|
seed,s=NextRandom(seed)
|
|
seed,v=NextRandom(seed)
|
|
local hue=h*360
|
|
local sat=0.82+s*0.18 -- 0.82 .. 1.00: strongly saturated
|
|
local val=0.85+v*0.15 -- 0.85 .. 1.00: bright/readable
|
|
return HSVToRGB(hue,sat,val)
|
|
end
|
|
|
|
V.colorRolls=V.colorRolls or {}
|
|
|
|
function V:GetQuestColor(questID)
|
|
questID=tonumber(questID) or 0
|
|
-- Each Full Node click re-rolls the quest's color (see CycleQuestColor).
|
|
local roll=self.colorRolls[questID] or 0
|
|
return SeedColor(questID+roll*1000003)
|
|
end
|
|
|
|
-- Full Nodes: clicking a spawn dot re-rolls its quest's color so overlapping
|
|
-- quests can be told apart, mirroring pfQuest's node click behavior.
|
|
function V:CycleQuestColor(questID)
|
|
questID=tonumber(questID)
|
|
if not questID then return end
|
|
self.colorRolls[questID]=(self.colorRolls[questID] or 0)+1
|
|
if QuestieOcto.Map and QuestieOcto.Map.RefreshVisualSettings then
|
|
QuestieOcto.Map:RefreshVisualSettings()
|
|
elseif QuestieOcto.Minimap and QuestieOcto.Minimap.RefreshVisualSettings then
|
|
QuestieOcto.Minimap:RefreshVisualSettings()
|
|
end
|
|
end
|
|
|
|
function V:GetObjectiveColor(questID,objectiveIndex)
|
|
return SeedColor((tonumber(questID) or 0)+32768*(tonumber(objectiveIndex) or 0))
|
|
end
|
|
|
|
function V:IsObjectiveRole(role)
|
|
return role=="objectiveCreature" or role=="objectiveObject" or role=="objectiveItemSource"
|
|
end
|
|
|
|
function V:EnsureGlow(pin)
|
|
if not pin or pin.glowTexture then return end
|
|
|
|
-- Questie 3.3.5 compatibility bridge:
|
|
-- glow = same icon frame, ARTWORK sublevel -1
|
|
-- icon = same icon frame, OVERLAY
|
|
local tex=pin:CreateTexture(nil,"ARTWORK")
|
|
if tex.SetDrawLayer then tex:SetDrawLayer("ARTWORK",-1) end
|
|
tex:SetTexture(TEX_GLOW)
|
|
tex:SetWidth(18)
|
|
tex:SetHeight(18)
|
|
tex:SetPoint("CENTER",pin,"CENTER",0,0)
|
|
tex:Hide()
|
|
pin.glowTexture=tex
|
|
end
|
|
|
|
function V:ResizeGlow(pin)
|
|
if not pin or not pin.glowTexture then return end
|
|
local width=pin:GetWidth() or 16
|
|
local height=pin:GetHeight() or 16
|
|
pin.glowTexture:SetWidth(width*1.13)
|
|
pin.glowTexture:SetHeight(height*1.13)
|
|
pin.glowTexture:ClearAllPoints()
|
|
pin.glowTexture:SetPoint("CENTER",pin,"CENTER",0,0)
|
|
end
|
|
|
|
function V:ClearPin(pin,alpha)
|
|
if not pin then return end
|
|
alpha=tonumber(alpha) or 1
|
|
pin.iconR,pin.iconG,pin.iconB=1,1,1
|
|
pin.glowR,pin.glowG,pin.glowB=1,1,1
|
|
pin.glowShown=false
|
|
pin.glowForced=nil
|
|
if pin.texture then pin.texture:SetVertexColor(1,1,1,alpha) end
|
|
if pin.glowTexture then pin.glowTexture:Hide() end
|
|
end
|
|
|
|
function V:ApplyPin(pin,node,isMinimap,alpha)
|
|
if not pin or not node then return end
|
|
alpha=tonumber(alpha) or 1
|
|
|
|
self:EnsureGlow(pin)
|
|
|
|
local objective=self:IsObjectiveRole(node.role)
|
|
local colorEnabled
|
|
local glowEnabled
|
|
|
|
if isMinimap then
|
|
colorEnabled=Settings():Get("questMinimapObjectiveColors") and true or false
|
|
glowEnabled=Settings():Get("alwaysGlowMinimap") and true or false
|
|
else
|
|
colorEnabled=Settings():Get("questObjectiveColors") and true or false
|
|
glowEnabled=Settings():Get("alwaysGlowMap") and true or false
|
|
end
|
|
|
|
local r,g,b=1,1,1
|
|
-- Quest pickup/turn-in presentation priority is PvP > Repeatable > Event >
|
|
-- Turtle low-level gray > Normal. Gray uses dedicated artwork like the other
|
|
-- quest-start variants; objective tinting never recolors pickup/turn-in icons.
|
|
if (node.pvp or node.repeatable) and (node.role=="available" or node.role=="itemStart" or node.role=="turnin") then
|
|
r,g,b=1,1,1
|
|
elseif objective and colorEnabled then
|
|
r,g,b=self:GetQuestColor(node.questID)
|
|
end
|
|
pin.iconR,pin.iconG,pin.iconB=r,g,b
|
|
if pin.texture then pin.texture:SetVertexColor(r,g,b,alpha) end
|
|
|
|
if objective and glowEnabled and pin.glowTexture then
|
|
local gr,gg,gb=self:GetObjectiveColor(node.questID,node.objectiveIndex)
|
|
pin.glowR,pin.glowG,pin.glowB=gr,gg,gb
|
|
pin.glowTexture:SetVertexColor(gr,gg,gb,alpha)
|
|
self:ResizeGlow(pin)
|
|
pin.glowTexture:Show()
|
|
pin.glowShown=true
|
|
elseif pin.glowTexture then
|
|
pin.glowTexture:Hide()
|
|
pin.glowShown=false
|
|
end
|
|
end
|
|
|
|
-- Fixed light blue-white used for the hover-highlight glow. The highlight only
|
|
-- appears while every other objective is faded, so it never needs to be color
|
|
-- coded per quest; a neutral tint reads clearly against the vivid node colors
|
|
-- rather than blending into them.
|
|
local HIGHLIGHT_GLOW_R,HIGHLIGHT_GLOW_G,HIGHLIGHT_GLOW_B=0.50,0.70,1.0
|
|
|
|
-- Tracker-hover highlight: brighten a pin and force its glow on so the hovered
|
|
-- quest's objectives stand out, then restore the normal glow state on release.
|
|
function V:SetHighlight(pin,on)
|
|
if not pin or not pin.texture then return end
|
|
if on then
|
|
pin.texture:SetVertexColor(pin.iconR or 1,pin.iconG or 1,pin.iconB or 1,1)
|
|
if pin.glowTexture then
|
|
pin.glowTexture:SetVertexColor(HIGHLIGHT_GLOW_R,HIGHLIGHT_GLOW_G,HIGHLIGHT_GLOW_B,1)
|
|
self:ResizeGlow(pin)
|
|
pin.glowTexture:Show()
|
|
pin.glowForced=true
|
|
end
|
|
else
|
|
pin.texture:SetVertexColor(pin.iconR or 1,pin.iconG or 1,pin.iconB or 1,1)
|
|
if pin.glowForced and pin.glowTexture then
|
|
pin.glowForced=nil
|
|
if pin.glowShown then
|
|
pin.glowTexture:SetVertexColor(pin.glowR or 1,pin.glowG or 1,pin.glowB or 1,1)
|
|
pin.glowTexture:Show()
|
|
else
|
|
pin.glowTexture:Hide()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
function V:ApplyFullNode(pin,node,isMinimap,alpha)
|
|
if not pin or not node or not pin.texture then return end
|
|
-- pfQuest's ordinary spawn nodes are deliberately compact and subdued.
|
|
-- Full Nodes use pfQuest's native 14px baseline and 15% transparency;
|
|
-- the user's only size control is the global map/minimap scale.
|
|
alpha=(tonumber(alpha) or 1)*0.85
|
|
local r,g,b=self:GetQuestColor(node.questID)
|
|
r,g,b=r*0.72,g*0.72,b*0.72
|
|
pin.iconR,pin.iconG,pin.iconB=r,g,b
|
|
pin.texture:SetTexture("Interface\\AddOns\\Questie-Octo\\UI\\Icons\\pfquest_node")
|
|
pin.texture:SetVertexColor(r,g,b,alpha)
|
|
if pin.glowTexture then pin.glowTexture:Hide() end
|
|
pin.glowShown=false
|
|
pin.fullNode=true
|
|
pin.fullNodeNode=node
|
|
end
|
|
|
|
function V:SetAlpha(pin,alpha)
|
|
if not pin then return end
|
|
alpha=tonumber(alpha) or 1
|
|
if pin.fullNode then alpha=alpha*0.85 end
|
|
if alpha<0 then alpha=0 end
|
|
if alpha>1 then alpha=1 end
|
|
|
|
if pin.texture then
|
|
pin.texture:SetVertexColor(pin.iconR or 1,pin.iconG or 1,pin.iconB or 1,alpha)
|
|
end
|
|
if pin.glowTexture and pin.glowTexture:IsShown() then
|
|
pin.glowTexture:SetVertexColor(pin.glowR or 1,pin.glowG or 1,pin.glowB or 1,alpha)
|
|
end
|
|
end
|