326 lines
8.5 KiB
Lua
326 lines
8.5 KiB
Lua
if not WeakAuras.IsLibsOK() then return end
|
|
local AddonName = ...
|
|
local Private = select(2, ...)
|
|
|
|
local SharedMedia = LibStub("LibSharedMedia-3.0");
|
|
local L = WeakAuras.L;
|
|
|
|
-- Default settings
|
|
local default = {
|
|
model_path = "Creature/Arthaslichking/arthaslichking.m2",
|
|
modelIsUnit = false,
|
|
model_x = 0,
|
|
model_y = 0,
|
|
model_z = 0,
|
|
width = 200,
|
|
height = 200,
|
|
sequence = 1,
|
|
advance = false,
|
|
rotation = 0,
|
|
scale = 1,
|
|
selfPoint = "CENTER",
|
|
anchorPoint = "CENTER",
|
|
anchorFrameType = "SCREEN",
|
|
xOffset = 0,
|
|
yOffset = 0,
|
|
frameStrata = 1,
|
|
border = false,
|
|
borderColor = {1.0, 1.0, 1.0, 0.5},
|
|
backdropColor = {1.0, 1.0, 1.0, 0.5},
|
|
borderEdge = "None",
|
|
borderOffset = 5,
|
|
borderInset = 11,
|
|
borderSize = 16,
|
|
borderBackdrop = "Blizzard Tooltip"
|
|
};
|
|
|
|
Private.regionPrototype.AddAlphaToDefault(default)
|
|
|
|
local screenWidth, screenHeight = math.ceil(GetScreenWidth() / 20) * 20, math.ceil(GetScreenHeight() / 20) * 20;
|
|
|
|
local properties = {
|
|
width = {
|
|
display = L["Width"],
|
|
setter = "SetRegionWidth",
|
|
type = "number",
|
|
min = 1,
|
|
softMax = screenWidth,
|
|
bigStep = 1,
|
|
default = 32
|
|
},
|
|
height = {
|
|
display = L["Height"],
|
|
setter = "SetRegionHeight",
|
|
type = "number",
|
|
min = 1,
|
|
softMax = screenHeight,
|
|
bigStep = 1,
|
|
default = 32
|
|
},
|
|
}
|
|
|
|
Private.regionPrototype.AddProperties(properties, default);
|
|
|
|
local function GetProperties(data)
|
|
return properties;
|
|
end
|
|
|
|
local regionFunctions = {
|
|
Update = function() end,
|
|
SetAlpha = function(self, alpha)
|
|
self.alpha = alpha
|
|
if self.model then
|
|
self.model:SetAlpha(alpha)
|
|
end
|
|
end
|
|
}
|
|
|
|
-- Called when first creating a new region/display
|
|
local function create(parent)
|
|
-- Main region
|
|
local region = CreateFrame("Frame", nil, UIParent);
|
|
region.regionType = "model"
|
|
region:SetMovable(true);
|
|
region:SetResizable(true);
|
|
region:SetMinResize(1, 1);
|
|
|
|
-- Border region
|
|
local border = CreateFrame("Frame", nil, region);
|
|
region.border = border;
|
|
|
|
Private.regionPrototype.create(region);
|
|
|
|
for k, v in pairs (regionFunctions) do
|
|
region[k] = v
|
|
end
|
|
|
|
-- Return complete region
|
|
return region;
|
|
end
|
|
|
|
local function CreateModel()
|
|
return CreateFrame("PlayerModel", nil, UIParent)
|
|
end
|
|
|
|
-- Keep the two model apis separate
|
|
local poolModelApi = CreateObjectPool(CreateModel)
|
|
local poolUnitApi = CreateObjectPool(CreateModel)
|
|
|
|
local function ConfigureModel(region, model, data)
|
|
model.modelIsUnit = data.modelIsUnit
|
|
|
|
model:ClearAllPoints()
|
|
model:SetAllPoints(region)
|
|
model:SetParent(region)
|
|
--model:SetKeepModelOnHide(true)
|
|
model:Show()
|
|
|
|
-- Adjust model
|
|
WeakAuras.SetModel(model, data.model_path, data.modelIsUnit, data.modelDisplayInfo)
|
|
model:SetPosition(data.model_z, data.model_x, data.model_y);
|
|
model:SetFacing(rad(region.rotation));
|
|
|
|
model:SetScript("OnShow", function()
|
|
WeakAuras.SetModel(model, data.model_path, data.modelIsUnit, data.modelDisplayInfo)
|
|
model:SetPosition(data.model_z, data.model_x, data.model_y);
|
|
model:SetFacing(rad(region.rotation));
|
|
end)
|
|
|
|
if data.modelIsUnit then
|
|
model:RegisterEvent("UNIT_MODEL_CHANGED");
|
|
if (data.model_path == "target") then
|
|
model:RegisterEvent("PLAYER_TARGET_CHANGED");
|
|
elseif (data.model_path == "focus") then
|
|
model:RegisterEvent("PLAYER_FOCUS_CHANGED");
|
|
end
|
|
model:SetScript("OnEvent", function(self, event, unitId)
|
|
Private.StartProfileSystem("model");
|
|
if (event ~= "UNIT_MODEL_CHANGED" or UnitIsUnit(unitId, data.model_path)) then
|
|
WeakAuras.SetModel(model, data.model_path, data.modelIsUnit, data.modelDisplayInfo)
|
|
end
|
|
Private.StopProfileSystem("model");
|
|
end
|
|
);
|
|
else
|
|
model:UnregisterEvent("UNIT_MODEL_CHANGED");
|
|
model:UnregisterEvent("PLAYER_TARGET_CHANGED");
|
|
model:UnregisterEvent("PLAYER_FOCUS_CHANGED");
|
|
model:SetScript("OnEvent", nil);
|
|
end
|
|
|
|
-- Enable model animation
|
|
if(data.advance) then
|
|
local elapsed = 0;
|
|
model:SetScript("OnUpdate", function(self, elaps)
|
|
Private.StartProfileSystem("model");
|
|
elapsed = elapsed + (elaps * 1000);
|
|
model:SetSequenceTime(data.sequence, elapsed);
|
|
Private.StopProfileSystem("model");
|
|
end)
|
|
else
|
|
model:SetScript("OnUpdate", nil)
|
|
end
|
|
end
|
|
|
|
local function AcquireModel(region, data)
|
|
local pool = data.modelIsUnit and poolUnitApi or poolModelApi
|
|
local model = pool:Acquire()
|
|
ConfigureModel(region, model, data)
|
|
return model
|
|
end
|
|
|
|
local function ReleaseModel(model)
|
|
model:SetAlpha(1)
|
|
--model:SetKeepModelOnHide(false)
|
|
model:Hide()
|
|
model:UnregisterEvent("UNIT_MODEL_CHANGED");
|
|
model:UnregisterEvent("PLAYER_TARGET_CHANGED");
|
|
model:UnregisterEvent("PLAYER_FOCUS_CHANGED");
|
|
model:SetScript("OnEvent", nil);
|
|
local pool = model.modelIsUnit and poolUnitApi or poolModelApi
|
|
pool:Release(model)
|
|
end
|
|
|
|
-- Modify a given region/display
|
|
local function modify(parent, region, data)
|
|
Private.regionPrototype.modify(parent, region, data);
|
|
-- Localize
|
|
local border = region.border;
|
|
|
|
if region.model then
|
|
ReleaseModel(region.model)
|
|
region.model = nil
|
|
end
|
|
|
|
-- Reset position and size
|
|
region:SetWidth(data.width);
|
|
region:SetHeight(data.height);
|
|
region.width = data.width;
|
|
region.height = data.height;
|
|
region.scalex = 1;
|
|
region.scaley = 1;
|
|
|
|
-- Update border
|
|
if data.border then
|
|
border:SetBackdrop({
|
|
edgeFile = SharedMedia:Fetch("border", data.borderEdge),
|
|
edgeSize = data.borderSize,
|
|
bgFile = SharedMedia:Fetch("background", data.borderBackdrop),
|
|
insets = {
|
|
left = data.borderInset,
|
|
right = data.borderInset,
|
|
top = data.borderInset,
|
|
bottom = data.borderInset,
|
|
},
|
|
});
|
|
border:SetBackdropBorderColor(data.borderColor[1], data.borderColor[2], data.borderColor[3], data.borderColor[4]);
|
|
border:SetBackdropColor(data.backdropColor[1], data.backdropColor[2], data.backdropColor[3], data.backdropColor[4]);
|
|
|
|
border:SetPoint("bottomleft", region, "bottomleft", -data.borderOffset, -data.borderOffset);
|
|
border:SetPoint("topright", region, "topright", data.borderOffset, data.borderOffset);
|
|
|
|
border:Show();
|
|
else
|
|
border:Hide();
|
|
end
|
|
-- Rescale model display
|
|
function region:Scale(scalex, scaley)
|
|
if(scalex < 0) then
|
|
region.mirror_h = true;
|
|
scalex = scalex * -1;
|
|
else
|
|
region.mirror_h = nil;
|
|
end
|
|
region:SetWidth(region.width * scalex);
|
|
if(scaley < 0) then
|
|
scaley = scaley * -1;
|
|
region.mirror_v = true;
|
|
else
|
|
region.mirror_v = nil;
|
|
end
|
|
region:SetHeight(region.height * scaley);
|
|
end
|
|
|
|
function region:SetRegionWidth(width)
|
|
region.width = width;
|
|
region:Scale(region.scalex, region.scaley);
|
|
end
|
|
|
|
function region:SetRegionHeight(height)
|
|
region.height = height;
|
|
region:Scale(region.scalex, region.scaley);
|
|
end
|
|
|
|
-- Rotate model
|
|
function region:SetAnimRotation(degrees)
|
|
region.animRotation = degrees
|
|
region:UpdateEffectiveRotation()
|
|
end
|
|
|
|
function region:SetRotation(degrees)
|
|
region.rotation = degrees
|
|
region:UpdateEffectiveRotation()
|
|
end
|
|
|
|
function region:UpdateEffectiveRotation()
|
|
region.effectiveRotation = region.animRotation or region.rotation
|
|
if region.model then
|
|
region.model:SetFacing(rad(region.effectiveRotation))
|
|
end
|
|
end
|
|
|
|
region:SetRotation(data.rotation)
|
|
|
|
-- Get model rotation
|
|
function region:GetBaseRotation()
|
|
return region.rotation
|
|
end
|
|
|
|
function region:PreShow()
|
|
if not region.model then
|
|
region.model = AcquireModel(self, data)
|
|
else
|
|
ConfigureModel(region, region.model, data)
|
|
end
|
|
if type(data.alpha) == "number" then
|
|
region:SetAlpha(data.alpha)
|
|
end
|
|
end
|
|
|
|
function region:PreHide()
|
|
if region.model then
|
|
ReleaseModel(region.model)
|
|
region.model = nil
|
|
end
|
|
end
|
|
|
|
Private.regionPrototype.modifyFinish(parent, region, data);
|
|
end
|
|
|
|
-- Work around for movies and world map hiding all models
|
|
do
|
|
function Private.PreShowModels(self, event)
|
|
Private.StartProfileSystem("model");
|
|
for id, data in pairs(Private.regions) do
|
|
Private.StartProfileAura(id);
|
|
if data.region and data.region.toShow then
|
|
if (data.regionType == "model") then
|
|
data.region:PreShow();
|
|
end
|
|
end
|
|
Private.StopProfileAura(id);
|
|
end
|
|
for model in pairs(Private.barmodels) do
|
|
model:PreShow()
|
|
end
|
|
Private.StopProfileSystem("model");
|
|
end
|
|
end
|
|
|
|
local function validate(data)
|
|
Private.EnforceSubregionExists(data, "subbackground")
|
|
end
|
|
|
|
-- Register new region type with WeakAuras
|
|
Private.RegisterRegionType("model", create, modify, default, GetProperties, validate);
|