forked from jeffi/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.
136 lines
4.5 KiB
136 lines
4.5 KiB
---@type Tinkr
|
|
local Tinkr,
|
|
---@class Bastion
|
|
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 (not actorTable.condition or 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 not actorTable.condition or actorTable.condition() then
|
|
-- print("Bastion: APL:Execute: Executing sub APL " .. actorTable.apl.name)
|
|
return actorTable.apl:Execute()
|
|
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
|
|
|
|
Bastion.APLActor = APLActor
|
|
|