Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local StateClass = {}
- StateClass.__index = StateClass
- local ReplicatedStorage = game:GetService("ReplicatedStorage")
- local RunService = game:GetService("RunService")
- local Player = game:GetService("Players").LocalPlayer
- local State = ReplicatedStorage:WaitForChild("State")
- local AlreadyCounting = false
- local LastChange = nil
- local COUNTDOWN_INTERVAL = .5
- local IDLE_REVERT_TIME = 5
- function StateClass.new(StateMachine)
- local self = setmetatable({}, StateClass)
- self.Name = StateMachine
- self.States = {}
- for _,State in ipairs(State[StateMachine]:GetChildren()) do
- self.States[State.Name] = require(State)
- end
- self.State = require(script.None)
- self.ReturnState = self.States.Idle
- return self
- end
- function StateClass:InitStates()
- for _,State in self.States do
- if State.Init then
- State.Init()
- end
- end
- end
- function StateClass:ChangeState(State)
- if self.State.Name == State then
- return
- end
- local ValidState = false
- local ErrorMessage = ""
- for StateName, Other in self.States do
- ErrorMessage = "Attempted to change to invalid state enum."
- if StateName == State then
- ValidState = true
- break
- end
- end
- local OldState = self.State
- local NewState = self.States[State]
- if NewState.RequiredStates then
- ValidState = false
- ErrorMessage = "Attempted to forbidden state"
- for _,RequiredState in ipairs(NewState.RequiredStates) do
- if RequiredState == OldState.Name then
- ValidState = true
- end
- end
- end
- if not ValidState then
- error(ErrorMessage..": "..NewState.Name)
- end
- if not NewState.IgnoreCallbacks then
- if OldState.Exit and not NewState.IgnoreExit then
- OldState.Exit(NewState)
- end
- if NewState.Enter then
- NewState.Enter(OldState)
- end
- end
- self.State = NewState
- print(self.Name.." State Change:",self.State.Name)
- if NewState.Name == "Idle" then
- return
- end
- LastChange = os.clock()
- if AlreadyCounting then return end
- AlreadyCounting = true
- if NewState.Movement then
- local Humanoid = Player.Character:WaitForChild("Humanoid")
- repeat task.wait() until Humanoid.MoveDirection.Magnitude == 0
- elseif not NewState.Movement and not NewState.Holdable then
- while true do
- task.wait(COUNTDOWN_INTERVAL)
- local DeltaTime = os.clock() - LastChange
- if DeltaTime >= IDLE_REVERT_TIME then
- break
- end
- end
- end
- if not NewState.Holdable then
- self:ChangeState(self.ReturnState)
- end
- AlreadyCounting = false
- end
- function StateClass:ChangeReturnState(State)
- if not self.States[State] then
- error("Attempted to change return state to invalid state enum.")
- end
- self.ReturnState = self.States[State]
- end
- function StateClass:FetchState(State)
- return self.State
- end
- return StateClass
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement