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
 | |
| 
 |