forked from Bastion/Bastion
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
226 lines
5.7 KiB
226 lines
5.7 KiB
---@type Tinkr, Bastion
|
|
local Tinkr, Bastion = ...
|
|
|
|
-- APL (Attack priority list) class
|
|
---@class Bastion.APL
|
|
---@field apl Bastion.APLActor[]
|
|
---@field variables table<string, any>
|
|
---@field name string
|
|
---@field last { successful: { name: string, time: number, index: number }, attempted: { name: string, time: number, index: number } }
|
|
local APL = {}
|
|
APL.__index = APL
|
|
|
|
-- Constructor
|
|
---@param name string
|
|
---@return Bastion.APL
|
|
function APL:New(name)
|
|
local self = setmetatable({}, APL)
|
|
|
|
self.apl = {}
|
|
self.variables = {}
|
|
self.name = name
|
|
self.last = {
|
|
successful = {
|
|
name = "",
|
|
time = -1,
|
|
index = -1,
|
|
},
|
|
attempted = {
|
|
name = "",
|
|
time = -1,
|
|
index = -1,
|
|
},
|
|
}
|
|
|
|
return self
|
|
end
|
|
|
|
-- Add a variable to the APL
|
|
---@param name string
|
|
---@param value any
|
|
function APL:SetVariable(name, value)
|
|
self.variables[name] = value
|
|
end
|
|
|
|
-- Get and evaluate a variable
|
|
---@param name string
|
|
---@return boolean
|
|
function APL:GetVariable(name)
|
|
return self.variables[name]
|
|
end
|
|
|
|
---@class Bastion.APL.Actor.Variable.Table : Bastion.APLActor.Table.Base
|
|
---@field variable string
|
|
---@field cb fun(...):any
|
|
---@field _apl Bastion.APL
|
|
|
|
-- Add variable
|
|
---@param name string
|
|
---@param cb fun(...):any
|
|
---@return Bastion.APLActor
|
|
function APL:AddVariable(name, cb)
|
|
local actor = Bastion.APLActor:New({
|
|
type = "variable",
|
|
variable = name,
|
|
cb = cb,
|
|
_apl = self,
|
|
})
|
|
table.insert(self.apl, actor)
|
|
return actor
|
|
end
|
|
|
|
---@class Bastion.APL.Actor.Action.Table : Bastion.APLActor.Table.Base
|
|
---@field action string
|
|
---@field cb fun(...):any
|
|
|
|
-- Add a manual action to the APL
|
|
---@param action string
|
|
---@param cb fun(...):any
|
|
---@return Bastion.APLActor
|
|
function APL:AddAction(action, cb)
|
|
local actor = Bastion.APLActor:New({
|
|
type = "action",
|
|
action = action,
|
|
cb = cb,
|
|
})
|
|
table.insert(self.apl, actor)
|
|
return actor
|
|
end
|
|
|
|
---@class Bastion.APL.Actor.Spell.Table : Bastion.APLActor.Table.Base
|
|
---@field spell Bastion.Spell
|
|
---@field condition? string|fun(self: Bastion.Spell): boolean
|
|
---@field castableFunc false | fun(self: Bastion.Spell): boolean
|
|
---@field target Bastion.Unit | false
|
|
---@field onCastFunc false | fun(self: Bastion.Spell):any
|
|
|
|
-- Add a spell to the APL
|
|
---@param spell Bastion.Spell
|
|
---@param condition? string|fun(self: Bastion.Spell):boolean
|
|
---@return Bastion.APLActor
|
|
function APL:AddSpell(spell, condition)
|
|
local castableFunc = spell.CastableIfFunc
|
|
local onCastFunc = spell.OnCastFunc
|
|
local target = spell:GetTarget()
|
|
|
|
local actor = Bastion.APLActor:New({
|
|
type = "spell",
|
|
spell = spell,
|
|
condition = condition,
|
|
castableFunc = castableFunc,
|
|
target = target,
|
|
onCastFunc = onCastFunc,
|
|
})
|
|
|
|
table.insert(self.apl, actor)
|
|
|
|
return actor
|
|
end
|
|
|
|
---@class Bastion.APL.Actor.Item.Table : Bastion.APLActor.Table.Base
|
|
---@field item Bastion.Item
|
|
---@field condition? string | fun(self: Bastion.Item): boolean
|
|
---@field usableFunc false | fun(...): boolean
|
|
---@field target Bastion.Unit | nil
|
|
|
|
-- Add an item to the APL
|
|
---@param item Bastion.Item
|
|
---@param condition? string | fun(self: Bastion.Item): boolean
|
|
---@return Bastion.APLActor
|
|
function APL:AddItem(item, condition)
|
|
local usableFunc = item.UsableIfFunc
|
|
local target = item:GetTarget()
|
|
|
|
local actor = Bastion.APLActor:New({
|
|
type = "item",
|
|
item = item,
|
|
condition = condition,
|
|
usableFunc = usableFunc,
|
|
target = target,
|
|
})
|
|
|
|
table.insert(self.apl, actor)
|
|
|
|
return actor
|
|
end
|
|
|
|
---@class Bastion.APL.Actor.APL.Table : Bastion.APLActor.Table.Base
|
|
---@field apl Bastion.APL
|
|
---@field condition? fun(...):boolean
|
|
|
|
-- Add an APL to the APL (for sub APLs)
|
|
---@param apl Bastion.APL
|
|
---@param condition fun(...):boolean
|
|
---@return Bastion.APLActor
|
|
function APL:AddAPL(apl, condition)
|
|
if not condition then
|
|
error("Bastion: APL:AddAPL: No condition for APL " .. apl.name)
|
|
end
|
|
local actor = Bastion.APLActor:New({
|
|
type = "apl",
|
|
apl = apl,
|
|
condition = condition,
|
|
})
|
|
table.insert(self.apl, actor)
|
|
return actor
|
|
end
|
|
|
|
---@param name string
|
|
---@param enabled? boolean
|
|
function APL:ToggleAPL(name, enabled)
|
|
for _, actor in ipairs(self.apl) do
|
|
if actor.actor.type == "apl" and actor.name == name then
|
|
actor.enabled = type(enabled) == "boolean" and enabled or not actor.enabled
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
function APL:UpdateLastAttempted(name, index)
|
|
self.last.attempted.name = name
|
|
self.last.attempted.time = GetTime()
|
|
self.last.attempted.index = index
|
|
end
|
|
|
|
function APL:UpdateLastSuccessful(name, index)
|
|
self.last.successful.name = name
|
|
self.last.successful.time = GetTime()
|
|
self.last.successful.index = index
|
|
end
|
|
|
|
-- Execute the APL
|
|
function APL:Execute()
|
|
for i, actor in ipairs(self.apl) do
|
|
self:UpdateLastAttempted(actor.name, i)
|
|
if actor.enabled and (not actor:HasTraits() or actor:Evaluate()) and actor:Execute() then
|
|
self:UpdateLastSuccessful(actor.name, i)
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
|
|
---@class Bastion.APL.Actor.Sequencer.Table : Bastion.APLActor.Table.Base
|
|
---@field sequencer Bastion.Sequencer
|
|
---@field condition? fun(...):boolean
|
|
|
|
-- Add a Sequencer to the APL
|
|
---@param sequencer Bastion.Sequencer
|
|
---@param condition fun(...):boolean
|
|
---@return Bastion.APLActor
|
|
function APL:AddSequence(sequencer, condition)
|
|
local actor = Bastion.APLActor:New({
|
|
type = "sequencer",
|
|
sequencer = sequencer,
|
|
condition = condition,
|
|
})
|
|
table.insert(self.apl, actor)
|
|
return actor
|
|
end
|
|
|
|
-- tostring
|
|
---@return string
|
|
function APL:__tostring()
|
|
return "Bastion.__APL(" .. self.name .. ")"
|
|
end
|
|
|
|
return APL
|
|
|