Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --------------------------
- -- Finite State Machine --
- --------------------------
- local Class = {}
- function Class.new(Parent)
- local FSM = {
- Parent = Parent,
- Stack = {},
- States = {},
- }
- return setmetatable(FSM, Class)
- end
- function Class:AddState(Index, Value)
- self.States[Index] = {Name = Index, Func = Value}
- end
- function Class:RemoveState(Index)
- table.remove(self.States, Index)
- end
- function Class:GetCurrentState()
- local StateName = self.Stack[#self.Stack]
- local State = self.States[StateName]
- return State
- end
- function Class:PopState()
- --warn("Popping state")
- local output = self.Stack[#self.Stack]
- -- self.Stack[#self.Stack] = nil
- table.remove(self.Stack, #self.Stack)
- return output
- end
- function Class:PushState(StateName)
- local CurrentState = self:GetCurrentState()
- if CurrentState == nil or CurrentState.Name ~= StateName then
- --warn("Pushing state")
- self.Stack[#self.Stack+1] = StateName
- else
- --warn("Cannot push State while in same State:", State)
- end
- end
- function Class:Update()
- local CurrentState = self:GetCurrentState()
- if CurrentState ~= nil then
- CurrentState.Func(self.Parent)
- else
- error("Error: CurrentState is nil.")
- end
- end
- Class.__index = Class
- return Class
- -------------------------------------------------------------------------------------------------------------------------------
- -------------------------------------------------------------------------------------------------------------------------------
- -------------------------------------------------------------------------------------------------------------------------------
- local Players = game:GetService("Players")
- return {
- Idle = function(self)
- self:StopMoving()
- local Goal = self:GetTarget()
- if Goal then
- self.LastTargetUpdate = tick()
- self.Target = Goal
- self.StateMachine:PushState("Seek")
- end
- end,
- Seek = function(self)
- --if tick() - self.LastTargetUpdate < self.TargetUpdateRate then
- if tick() - self.LastTargetUpdate < 10 then
- local DistanceFromTarget = self:MoveTo(self.Target[2])
- if DistanceFromTarget < self.AttackRange then
- -- Target is within range
- self.LastAttack = tick() - (self.AttackRate * 0.75)
- self.StateMachine:PushState("Attack")
- else
- -- Target is not in range
- -- self:LookAt(self.Target[2])
- if not self:HasPath() then
- warn("Getting path")
- self.StateMachine:PushState("FindPath")
- else
- warn("Following path")
- self:FollowPath()
- end
- end
- else
- -- Time to change targets
- print("Time to change targets")
- self.StateMachine:PopState()
- end
- end,
- Attack = function(self)
- if self:GetDistanceFromTarget(self.Target[2]) > self.AttackRange then
- self.StateMachine:PopState()
- else
- self:Attack(self.Target[2])
- self:LookAt(self.Target[2])
- self:StopMoving()
- end
- end,
- FindPath = function(self)
- self:StopMoving()
- if self:FindPath(self.Target[2]) then
- self.StateMachine:PopState()
- --self.StateMachine:PushState("Seek")
- end
- end,
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement