forked from Bastion/Bastion
parent
a572688294
commit
031c68009c
@ -0,0 +1,141 @@ |
||||
---@type Tinkr, Bastion |
||||
local Tinkr, Bastion = ... |
||||
|
||||
---@class Bastion.APLActor.Table.Base |
||||
---@field type "spell" | "item" | "apl" | "sequencer" | "variable" | "action" |
||||
|
||||
---@alias Bastion.APLActor.Table Bastion.APL.Actor.Spell.Table | Bastion.APL.Actor.Item.Table | Bastion.APL.Actor.APL.Table | Bastion.APL.Actor.Sequencer.Table | Bastion.APL.Actor.Variable.Table | Bastion.APL.Actor.Action.Table |
||||
|
||||
-- Create an APL actor for the APL class |
||||
---@class Bastion.APLActor |
||||
---@field actor Bastion.APLActor.Table |
||||
---@field enabled boolean |
||||
---@field traits Bastion.APLTrait[] |
||||
---@field name string |
||||
local APLActor = {} |
||||
APLActor.__index = APLActor |
||||
|
||||
-- Constructor |
||||
---@param actor Bastion.APLActor.Table |
||||
function APLActor:New(actor) |
||||
local self = setmetatable({}, APLActor) |
||||
if actor.type == "spell" then |
||||
local name = actor.spell:GetName() or "Unknown" |
||||
local id = actor.spell:GetID() or 0 |
||||
self.name = string.format("[%s] `%s`<%s>", "spell", name, id) |
||||
elseif actor.type == "item" then |
||||
local name = actor.item:GetName() or "Unknown" |
||||
local id = actor.item:GetID() or 0 |
||||
self.name = string.format("[%s] `%s`<%s>", "item", name, id) |
||||
elseif actor.type == "apl" then |
||||
self.name = string.format("[%s] `%s`", "apl", actor.apl.name) |
||||
elseif actor.type == "sequencer" then |
||||
self.name = string.format("[%s]", "sequencer") |
||||
elseif actor.type == "variable" then |
||||
self.name = string.format("[%s] `%s`", "variable", actor.variable) |
||||
elseif actor.type == "action" then |
||||
self.name = string.format("[%s] `%s`", "action", actor.action) |
||||
else |
||||
self.name = string.format("[%s] Unknown", actor.type) |
||||
end |
||||
self.actor = actor |
||||
self.enabled = true |
||||
self.traits = {} |
||||
|
||||
return self |
||||
end |
||||
|
||||
-- Add a trait to the APL actor |
||||
---@param ... Bastion.APLTrait |
||||
---@return Bastion.APLActor |
||||
function APLActor:AddTraits(...) |
||||
for _, trait in ipairs({ ... }) do |
||||
table.insert(self.traits, trait) |
||||
end |
||||
|
||||
return self |
||||
end |
||||
|
||||
-- Get the actor |
||||
---@return Bastion.APLActor.Table |
||||
function APLActor:GetActor() |
||||
return self.actor |
||||
end |
||||
|
||||
-- Evaulate the APL actor |
||||
---@return boolean |
||||
function APLActor:Evaluate() |
||||
for _, trait in ipairs(self.traits) do |
||||
if not trait:Evaluate(self:GetActor()) then |
||||
return false |
||||
end |
||||
end |
||||
|
||||
return true |
||||
end |
||||
|
||||
-- Execute |
||||
function APLActor:Execute() |
||||
local actorTable = self:GetActor() |
||||
-- If the actor is a sequencer we don't want to continue executing the APL if the sequencer is not finished |
||||
if actorTable.type == "sequencer" then |
||||
---@cast actorTable Bastion.APL.Actor.Sequencer.Table |
||||
if actorTable.condition and actorTable.condition() and not actorTable.sequencer:Finished() then |
||||
actorTable.sequencer:Execute() |
||||
return true |
||||
end |
||||
|
||||
if not actorTable.condition and not actorTable.sequencer:Finished() then |
||||
actorTable.sequencer:Execute() |
||||
return true |
||||
end |
||||
|
||||
-- Check if the sequencer can be reset and reset it if it can |
||||
if actorTable.sequencer:ShouldReset() then |
||||
actorTable.sequencer:Reset() |
||||
end |
||||
end |
||||
if actorTable.type == "apl" then |
||||
---@cast actorTable Bastion.APL.Actor.APL.Table |
||||
if actorTable.condition and actorTable.condition() then |
||||
-- print("Bastion: APL:Execute: Executing sub APL " .. actorTable.apl.name) |
||||
if actorTable.apl:Execute() then |
||||
return true |
||||
end |
||||
end |
||||
end |
||||
if actorTable.type == "spell" then |
||||
---@cast actorTable Bastion.APL.Actor.Spell.Table |
||||
return actorTable.spell:CastableIf(actorTable.castableFunc):OnCast(actorTable.onCastFunc):Cast(actorTable.target, |
||||
actorTable.condition) |
||||
end |
||||
if actorTable.type == "item" then |
||||
---@cast actorTable Bastion.APL.Actor.Item.Table |
||||
return actorTable.item:UsableIf(actorTable.usableFunc):Use(actorTable.target, actorTable.condition) |
||||
end |
||||
if self:GetActor().type == "action" then |
||||
---@cast actorTable Bastion.APL.Actor.Action.Table |
||||
-- print("Bastion: APL:Execute: Executing action " .. actorTable.action) |
||||
self:GetActor().cb() |
||||
end |
||||
if actorTable.type == "variable" then |
||||
---@cast actorTable Bastion.APL.Actor.Variable.Table |
||||
-- print("Bastion: APL:Execute: Setting variable " .. actorTable.variable) |
||||
actorTable._apl.variables[actorTable.variable] = actorTable.cb(actorTable._apl) |
||||
end |
||||
return false |
||||
end |
||||
|
||||
-- has traits |
||||
---@return boolean |
||||
function APLActor:HasTraits() |
||||
return #self.traits > 0 |
||||
end |
||||
|
||||
-- tostring |
||||
---@return string |
||||
function APLActor:__tostring() |
||||
return string.format("Bastion.__APLActor(%s)", self.name) |
||||
end |
||||
|
||||
return APLActor |
@ -0,0 +1,42 @@ |
||||
---@type Tinkr, Bastion |
||||
local Tinkr, Bastion = ... |
||||
|
||||
-- Create an APL trait for the APL class |
||||
---@class Bastion.APLTrait |
||||
---@field cb fun(actor?: Bastion.APLActor.Table):boolean |
||||
---@field lastcall number |
||||
local APLTrait = {} |
||||
APLTrait.__index = APLTrait |
||||
|
||||
-- Constructor |
||||
---@param cb fun(actor?: Bastion.APLActor.Table):boolean |
||||
---@return Bastion.APLTrait |
||||
function APLTrait:New(cb) |
||||
local self = setmetatable({}, APLTrait) |
||||
|
||||
self.cb = cb |
||||
self.lastcall = 0 |
||||
|
||||
return self |
||||
end |
||||
|
||||
-- Evaulate the APL trait |
||||
---@param actor? Bastion.APLActor.Table |
||||
---@return boolean |
||||
function APLTrait:Evaluate(actor) |
||||
if GetTime() - self.lastcall > 0.1 then |
||||
self.lastresult = self.cb(actor) |
||||
self.lastcall = GetTime() |
||||
return self.lastresult |
||||
end |
||||
|
||||
return self.lastresult |
||||
end |
||||
|
||||
-- tostring |
||||
---@return string |
||||
function APLTrait:__tostring() |
||||
return "Bastion.__APLTrait" |
||||
end |
||||
|
||||
return APLTrait |
@ -0,0 +1,69 @@ |
||||
---@type Tinkr, Bastion |
||||
local Tinkr, Bastion = ... |
||||
|
||||
-- Create a notification class for the notifications list (takes icon and text) |
||||
---@class Bastion.Notification |
||||
---@field icon Texture |
||||
---@field text FontString |
||||
---@field frame Frame |
||||
---@field addedAt number |
||||
---@field duration number |
||||
---@field list Bastion.NotificationList |
||||
local Notification = { |
||||
} |
||||
Notification.__index = Notification |
||||
|
||||
-- Constructor |
||||
---@param list Bastion.NotificationList |
||||
---@param icon string |
||||
---@param text string |
||||
---@param duration number |
||||
---@return Bastion.Notification |
||||
function Notification:New(list, icon, text, duration) |
||||
local self = setmetatable({}, Notification) |
||||
|
||||
if not duration then duration = 2 end |
||||
|
||||
-- Create a frame for the notification |
||||
self.frame = CreateFrame("Frame", nil, list.frame) |
||||
self.frame:SetSize(5, 5) |
||||
self.frame:SetPoint("CENTER", list.frame, "CENTER", 0, 0) |
||||
self.frame:SetFrameStrata("HIGH") |
||||
|
||||
-- Create a texture for the icon |
||||
self.icon = self.frame:CreateTexture(nil, "ARTWORK") |
||||
self.icon:SetSize(32, 32) |
||||
self.icon:SetPoint("LEFT", self.frame, "LEFT", 0, 0) |
||||
self.icon:SetTexture(icon) |
||||
|
||||
-- Create a fontstring for the text |
||||
self.text = self.frame:CreateFontString(nil, "BACKGROUND", "NumberFontNormal") |
||||
self.text:SetPoint("LEFT", self.frame, "LEFT", 32 + 16, 0) |
||||
self.text:SetText(text) |
||||
self.text:SetFont("Fonts\\OpenSans-Bold.ttf", 18, "") |
||||
|
||||
-- set the frame size to the size of the text + icon |
||||
self.frame:SetSize(self.text:GetStringWidth() + 32 + 16, 32) |
||||
|
||||
self.addedAt = GetTime() |
||||
self.duration = duration |
||||
self.list = list |
||||
|
||||
return self |
||||
end |
||||
|
||||
-- Remove notification |
||||
---@return nil |
||||
function Notification:Remove() |
||||
-- Fade out the notification frame and remove it after the fade |
||||
UIFrameFadeOut(self.frame, 0.2, 1, 0) |
||||
C_Timer.After(0.5, function() |
||||
self.frame:Hide() |
||||
self.frame:ClearAllPoints() |
||||
self.frame:SetParent(nil) |
||||
self.frame = nil |
||||
self.list:Update() |
||||
end) |
||||
end |
||||
|
||||
return Notification |
@ -0,0 +1,92 @@ |
||||
---@type Tinkr, Bastion |
||||
local Tinkr, Bastion = ... |
||||
|
||||
-- Create a NotificationList class |
||||
|
||||
---@class Bastion.NotificationList |
||||
---@field frame Frame |
||||
local NotificationList = { |
||||
notifications = {} |
||||
} |
||||
NotificationList.__index = NotificationList |
||||
|
||||
-- Constructor |
||||
---@return Bastion.NotificationList |
||||
function NotificationList:New() |
||||
local self = setmetatable({}, NotificationList) |
||||
|
||||
-- Create a frame for the notifications |
||||
self.frame = CreateFrame("Frame", "BastionNotificationList", UIParent) |
||||
self.frame:SetSize(600, 60) |
||||
self.frame:SetPoint("TOP", UIParent, "TOP", 0, -100) |
||||
self.frame:SetFrameStrata("HIGH") |
||||
|
||||
-- Remove notifications after 5 seconds |
||||
C_Timer.NewTicker(0.1, function() |
||||
for i, notification in ipairs(self.notifications) do |
||||
if GetTime() - notification.addedAt > notification.duration then |
||||
notification:Remove() |
||||
table.remove(self.notifications, i) |
||||
end |
||||
end |
||||
end) |
||||
|
||||
return self |
||||
end |
||||
|
||||
-- Add a notification to the list |
||||
---@param icon string |
||||
---@param text string |
||||
---@param duration number |
||||
---@return nil |
||||
function NotificationList:AddNotification(icon, text, duration) |
||||
-- Create a new notification |
||||
local notification = Bastion.Notification:New(self, icon, text, duration) |
||||
|
||||
-- Add the notification to the list |
||||
table.insert(self.notifications, notification) |
||||
UIFrameFadeIn(notification.frame, 0.2, 0, 1) |
||||
|
||||
-- Update the notifications |
||||
self:Update() |
||||
end |
||||
|
||||
-- Update the notifications |
||||
---@return nil |
||||
function NotificationList:Update() |
||||
-- Loop through the notifications |
||||
for i, notification in ipairs(self.notifications) do |
||||
-- Set the position of the notification |
||||
notification.frame:SetPoint("CENTER", self.frame, "CENTER", 0, -42 * (i - 1)) |
||||
end |
||||
end |
||||
|
||||
-- Remove a notification from the list |
||||
---@param notification Bastion.Notification |
||||
---@return nil |
||||
function NotificationList:RemoveNotification(notification) |
||||
-- Loop through the notifications |
||||
for i, v in ipairs(self.notifications) do |
||||
-- Check if the notification is the one we want to remove |
||||
if v == notification then |
||||
-- Remove the notification from the list |
||||
table.remove(self.notifications, i) |
||||
notification:Remove() |
||||
break |
||||
end |
||||
end |
||||
end |
||||
|
||||
-- Remove all notifications from the list |
||||
---@return nil |
||||
function NotificationList:RemoveAllNotifications() |
||||
-- Loop through the notifications |
||||
for i, v in ipairs(self.notifications) do |
||||
-- Remove the notification from the list |
||||
table.remove(self.notifications, i) |
||||
self.notifications[i]:Remove() |
||||
end |
||||
end |
||||
|
||||
-- Remove all notifications |
||||
return NotificationList |
@ -1,147 +0,0 @@ |
||||
-- Create a NotificationsList class |
||||
|
||||
---@class NotificationsList |
||||
local NotificationsList = { |
||||
notifications = {} |
||||
} |
||||
NotificationsList.__index = NotificationsList |
||||
|
||||
-- Constructor |
||||
---@return NotificationsList |
||||
function NotificationsList:New() |
||||
local self = setmetatable({}, NotificationsList) |
||||
|
||||
-- Create a frame for the notifications |
||||
self.frame = CreateFrame("Frame", "BastionNotificationsList", UIParent) |
||||
self.frame:SetSize(600, 60) |
||||
self.frame:SetPoint("TOP", UIParent, "TOP", 0, -100) |
||||
self.frame:SetFrameStrata("HIGH") |
||||
|
||||
-- Remove notifications after 5 seconds |
||||
C_Timer.NewTicker(0.1, function() |
||||
for i, notification in ipairs(self.notifications) do |
||||
if GetTime() - notification.addedAt > notification.duration then |
||||
notification:Remove() |
||||
table.remove(self.notifications, i) |
||||
end |
||||
end |
||||
end) |
||||
|
||||
return self |
||||
end |
||||
|
||||
-- Create a notification class for the notifications list (takes icon and text) |
||||
---@class Notification |
||||
local Notification = { |
||||
} |
||||
Notification.__index = Notification |
||||
|
||||
-- Constructor |
||||
---@param list NotificationsList |
||||
---@param icon string |
||||
---@param text string |
||||
---@param duration number |
||||
---@return Notification |
||||
function Notification:New(list, icon, text, duration) |
||||
local self = setmetatable({}, Notification) |
||||
|
||||
if not duration then duration = 2 end |
||||
|
||||
-- Create a frame for the notification |
||||
self.frame = CreateFrame("Frame", nil, list.frame) |
||||
self.frame:SetSize(5, 5) |
||||
self.frame:SetPoint("CENTER", list.frame, "CENTER", 0, 0) |
||||
self.frame:SetFrameStrata("HIGH") |
||||
|
||||
-- Create a texture for the icon |
||||
self.icon = self.frame:CreateTexture(nil, "ARTWORK") |
||||
self.icon:SetSize(32, 32) |
||||
self.icon:SetPoint("LEFT", self.frame, "LEFT", 0, 0) |
||||
self.icon:SetTexture(icon) |
||||
|
||||
-- Create a fontstring for the text |
||||
self.text = self.frame:CreateFontString(nil, "BACKGROUND", "NumberFontNormal") |
||||
self.text:SetPoint("LEFT", self.frame, "LEFT", 32 + 16, 0) |
||||
self.text:SetText(text) |
||||
self.text:SetFont("Fonts\\OpenSans-Bold.ttf", 18) |
||||
|
||||
-- set the frame size to the size of the text + icon |
||||
self.frame:SetSize(self.text:GetStringWidth() + 32 + 16, 32) |
||||
|
||||
self.addedAt = GetTime() |
||||
self.duration = duration |
||||
self.list = list |
||||
|
||||
return self |
||||
end |
||||
|
||||
-- Remove notification |
||||
---@return nil |
||||
function Notification:Remove() |
||||
-- Fade out the notification frame and remove it after the fade |
||||
UIFrameFadeOut(self.frame, 0.2, 1, 0) |
||||
C_Timer.After(0.5, function() |
||||
self.frame:Hide() |
||||
self.frame:ClearAllPoints() |
||||
self.frame:SetParent(nil) |
||||
self.frame = nil |
||||
self.list:Update() |
||||
end) |
||||
end |
||||
|
||||
-- Add a notification to the list |
||||
---@param icon string |
||||
---@param text string |
||||
---@param duration number |
||||
---@return nil |
||||
function NotificationsList:AddNotification(icon, text, duration) |
||||
-- Create a new notification |
||||
local notification = Notification:New(self, icon, text, duration) |
||||
|
||||
-- Add the notification to the list |
||||
table.insert(self.notifications, notification) |
||||
UIFrameFadeIn(notification.frame, 0.2, 0, 1) |
||||
|
||||
-- Update the notifications |
||||
self:Update() |
||||
end |
||||
|
||||
-- Update the notifications |
||||
---@return nil |
||||
function NotificationsList:Update() |
||||
-- Loop through the notifications |
||||
for i, notification in ipairs(self.notifications) do |
||||
-- Set the position of the notification |
||||
notification.frame:SetPoint("CENTER", self.frame, "CENTER", 0, -42 * (i - 1)) |
||||
end |
||||
end |
||||
|
||||
-- Remove a notification from the list |
||||
---@param notification Notification |
||||
---@return nil |
||||
function NotificationsList:RemoveNotification(notification) |
||||
-- Loop through the notifications |
||||
for i, v in ipairs(self.notifications) do |
||||
-- Check if the notification is the one we want to remove |
||||
if v == notification then |
||||
-- Remove the notification from the list |
||||
table.remove(self.notifications, i) |
||||
notification:Remove() |
||||
break |
||||
end |
||||
end |
||||
end |
||||
|
||||
-- Remove all notifications from the list |
||||
---@return nil |
||||
function NotificationsList:RemoveAllNotifications() |
||||
-- Loop through the notifications |
||||
for i, v in ipairs(self.notifications) do |
||||
-- Remove the notification from the list |
||||
table.remove(self.notifications, i) |
||||
self.notifications[i]:Remove() |
||||
end |
||||
end |
||||
|
||||
-- Remove all notifications |
||||
return NotificationsList, Notification |
Loading…
Reference in new issue