--!strict
--Services
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
--Modules
local Helper = require(ReplicatedStorage.Packages.Helper)
local Fusion = require(ReplicatedStorage.Packages.Fusion)
local FusionTypes = require(ReplicatedStorage.Packages._Index["[email protected]"].fusion.Types)
--Vars
local Player = game.Players.LocalPlayer :: Player
local PlayerGui = Player.PlayerGui
local Database = Player:WaitForChild("Database")
local Peek = Fusion.peek
--Constants
local LEFT_ACCEL = Vector3.new(20, 2, 30) --Smoke effect velocity when going LEFT
local RIGHT_ACCEL = Vector3.new(-20, 2, 30) --Smoke effect velocity when going RIGHT
local VELOCITY_MAG = 1000 --Side movement velocity
local DrainageTick = 0.1 --Control bar drain
--Types
export type Class = {
Character: Model?,
HRP: BasePart?,
LinearVelocity: LinearVelocity?,
Smoke: ParticleEmitter?,
Init: boolean,
Input: RBXScriptConnection,
LastTimeRedirected: number?,
Scope: FusionTypes.Scope,
ScopeValues: {
Control: FusionTypes.Value?
},
}
local module = {}
function module.new(character)
local self = {}
self.Character = character
self.HRP = nil
self.LinearVelocity = nil
self.Smoke = nil
self.Init = false
self.Input = nil
self.LastTimeRedirected = nil
self.ScopeValues = {
Control = nil
}
self.Scope = nil
return self
end
function module:Init(class: Class): ()
if class.Init then warn("Inited before: fail") return end
class.HRP = class.Character:WaitForChild("HumanoidRootPart")
if not class.HRP then warn('Init failed, not rootpart') return end
class.Init = true
--Velocity
class.LinearVelocity = Instance.fromExisting(script.LinearVelocity)
if not class.LinearVelocity then warn("Failed creating velocity") return end
class.LinearVelocity.Parent = class.HRP
local VelocityAttachment = Instance.new("Attachment", class.HRP)
VelocityAttachment.Name = "Director"
class.LinearVelocity.Attachment0 = VelocityAttachment
--Smoke effect
local SmokeAttachment = ReplicatedStorage.Templates.Assets.Effects.ControlSmoke:Clone()
SmokeAttachment.Parent = class.HRP
class.Smoke = SmokeAttachment:FindFirstChild("ParticleEmitter") :: ParticleEmitter
if not class.Smoke then warn("Failed creating smoke effect") return end
class.Smoke.Enabled = false
module:InitInterface( class )
module:HandleInput( class )
end
function module:InitInterface(class: Class)
local Scope = Fusion:scoped()
class.Scope = Scope
local ControlValue = Database.Upgrades.Control :: NumberValue
local Limit = 20 * ( ControlValue.Value * 0.1 + 1)
local Control = Scope:Value( Limit ) :: FusionTypes.Value
class.ScopeValues.Control = Control
local RoundMoney = PlayerGui:WaitForChild("Money"):WaitForChild("RoundMoney")
local ControlGui = PlayerGui:WaitForChild("ControlBar")
RoundMoney.Visible = true
ControlGui.Enabled = true
local ControlFill = ControlGui.Bar.Fill :: Frame
local SizeCompute = Scope:Computed(function(use)
return UDim2.fromScale( use(Control) :: number / Limit , 1)
end)
Scope:Hydrate(ControlFill) {
Size = SizeCompute
}
end
function module:HandleInput(class: Class): ()
local Control = class.ScopeValues.Control :: FusionTypes.Value
local function ShrinkControlUI()
Control:set( Peek(Control) :: number - DrainageTick )
end
class.Input = game:GetService("RunService").PostSimulation:Connect(function(deltaTimeSim: number)
local current_direction = nil
if UserInputService:IsKeyDown(Enum.KeyCode.A) then
current_direction = "Left"
end
if UserInputService:IsKeyDown(Enum.KeyCode.D) then
current_direction = "Right"
end
if current_direction then
ShrinkControlUI()
end
if Peek(Control) :: number > 0 then
module:SetDirection(class, current_direction)
else
module:SetDirection(class, nil)
end
end)
end
function module:SetDirection(class: Class, direction: string?): ()
if not class.Character then return end
if not class.LinearVelocity then return end
if not class.Smoke then return end
if direction == nil then
class.Smoke.Enabled = false
class.LinearVelocity.Enabled = false
else
class.Smoke.Enabled = true
class.LinearVelocity.Enabled = true
if module.LastTimeRedirected then
local Past = os.time() - module.LastTimeRedirected
if Past > 5 then
Helper:Play("Air")
end
else
Helper:Play("Air")
end
module.LastTimeRedirected = os.time()
end
if direction == "Left" then
class.Smoke.Acceleration = LEFT_ACCEL
class.LinearVelocity.VectorVelocity = Vector3.new(-VELOCITY_MAG,0,0)
elseif direction == "Right" then
class.Smoke.Acceleration = RIGHT_ACCEL
class.LinearVelocity.VectorVelocity = Vector3.new(VELOCITY_MAG,0,0)
end
end
function module:Destroy(class: Class): ()
if class.LinearVelocity then
class.LinearVelocity:Destroy()
class.LinearVelocity = nil
end
if class.HRP then
local attachment = class.HRP:FindFirstChild("Director")
if attachment then
attachment:Destroy()
end
end
if class.Scope then
class.Scope.doCleanup()
end
if class.Input then
class.Input:Disconnect()
end
local RoundMoney = PlayerGui:WaitForChild("Money"):WaitForChild("RoundMoney")
RoundMoney.Visible = false
class.Character = nil
class.HRP = nil
class.Init = false
end
return module