How am I able to clean up this code? It’s like 400 lines long and it’s so messy and unreadable at this point. I have no idea what to change about it. I considered using external modules, but that wouldn’t really work.
Code:
-- TODO:
-- A module that creates hints with just a bit of customization and simple code.
---------- Variables ----------
local HS = { }
local DisallowedWhiteSpace = {"\n", "\r", "\t", "\v", "\f"}
--
local GuiService = game:GetService("GuiService")
local StarterGui = game:GetService("StarterGui")
local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local TextService = game:GetService("TextService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
--
local DefaultThemeFolder = script:WaitForChild("DefaultTheme")
local ThemesFolder = script:WaitForChild("Themes")
local Assets = script:WaitForChild("Assets")
local Plugins = script:WaitForChild("Plugins")
local Signal = require(Plugins:FindFirstChild("Signal"))
local DefaultTheme = require(DefaultThemeFolder:WaitForChild("DefaultTheme"))
local HintsGui = Assets:FindFirstChild("Hints"):Clone()
local Player = Players.LocalPlayer
local PlayerGui = Player:WaitForChild("PlayerGui")
---------- Events & Properties ----------
local function argumentError(argument : string, functionName : string)
argument = argument or "nil"
functionName = functionName or "nil"
error(string.format("The %s argument must be passed in the %s function.", argument, functionName))
end
local function invalidError(object : string, type : string)
object = object or "nil"
type = type or "nil"
error(string.format("%s is not a valid %s.", object, type))
end
local function customError(msg : string, ...)
error(string.format(msg, ...))
end
local function customError2(msg : string)
error(msg)
end
local function onMenuOpenedConfig(isHintVisible : boolean)
HintsGui.Enabled = isHintVisible
end
local function setHintProperties(self : any)
if not self then
argumentError("self", "setHintProperties")
end
self._.BackgroundColor3 = self.HintTheme.hintColor
self._.UICorner.CornerRadius = self.HintTheme.hintCornerRadius
self._.BorderUIStroke.Color = self.HintTheme.hintStrokeColor
self._.BorderUIStroke.LineJoinMode = self.HintTheme.hintStrokeLineJoinMode
self._.BorderUIStroke.Thickness = self.HintTheme.hintStrokeSize
self._.TextColor3 = self.HintTheme.labelColor
self._.TextUIStroke.Color = self.HintTheme.labelStrokeColor
self._.TextUIStroke.LineJoinMode = self.HintTheme.labelStrokeLineJoinMode
self._.TextUIStroke.Thickness = self.HintTheme.hintStrokeSize
self._.Font = self.HintTheme.labelFont
self._.ExtraPadding.PaddingLeft = self.HintTheme.labelPaddingLeft
self._.ExtraPadding.PaddingRight = self.HintTheme.labelPaddingRight
self.HintTransparency = self.HintTheme.hintTransparency
self.LabelTransparency = self.HintTheme.labelTransparency
end
local function cancelHint(self : any)
local type = self.AnimationType
local label = self._
if type == "Fade" then
TweenService:Create(label, TweenInfo.new(self.TweenLength2, self.EasingStyle2, self.EasingDirection2), {Transparency = 1}):Play()
TweenService:Create(label:WaitForChild("BorderUIStroke"), TweenInfo.new(self.TweenLength2, self.EasingStyle2, self.EasingDirection2), {Transparency = 1}):Play()
TweenService:Create(label:WaitForChild("TextUIStroke"), TweenInfo.new(self.TweenLength2, self.EasingStyle2, self.EasingDirection2), {Transparency = 1}):Play()
task.wait(self.TweenLength2)
label:Destroy()
elseif type == "None" then
label.Transparency = 1
label:WaitForChild("BorderUIStroke").Transparency = 1
label:WaitForChild("BorderUIStroke").Transparency = 1
label:Destroy()
end
end
local function animateHint(self : any)
local type = self.AnimationType
local infiniteTime = self.InfiniteTime
local label = self._
label.Visible = true
local hintCancelled = self.Cancelled
if not self then
argumentError("self", "animateHint")
end
if self.VisibleTime <= 1 then
error("Max visible time cannot be 1 or under.")
end
if type == "Fade" then
if self.InfiniteTime == true then
HS.HintAdding:Fire(label)
self.BroadcastRecieved:Fire()
TweenService:Create(label, TweenInfo.new(self.TweenLength1, self.EasingStyle1, self.EasingDirection1), {TextTransparency = self.LabelTransparency}):Play()
TweenService:Create(label, TweenInfo.new(self.TweenLength1, self.EasingStyle1, self.EasingDirection1), {BackgroundTransparency = self.HintTransparency}):Play()
TweenService:Create(label:WaitForChild("BorderUIStroke"), TweenInfo.new(self.TweenLength1, self.EasingStyle1, self.EasingDirection1), {Transparency = self.HintTransparency}):Play()
TweenService:Create(label:WaitForChild("TextUIStroke"), TweenInfo.new(self.TweenLength1, self.EasingStyle1, self.EasingDirection1), {Transparency = self.LabelTransparency}):Play()
else
HS.HintAdding:Fire(label)
self.BroadcastRecieved:Fire()
TweenService:Create(label, TweenInfo.new(self.TweenLength1, self.EasingStyle1, self.EasingDirection1), {TextTransparency = self.LabelTransparency}):Play()
TweenService:Create(label, TweenInfo.new(self.TweenLength1, self.EasingStyle1, self.EasingDirection1), {BackgroundTransparency = self.HintTransparency}):Play()
TweenService:Create(label:WaitForChild("BorderUIStroke"), TweenInfo.new(self.TweenLength1, self.EasingStyle1, self.EasingDirection1), {Transparency = self.HintTransparency}):Play()
TweenService:Create(label:WaitForChild("TextUIStroke"), TweenInfo.new(self.TweenLength1, self.EasingStyle1, self.EasingDirection1), {Transparency = self.LabelTransparency}):Play()
task.wait(self.VisibleTime + self.TweenLength1)
if not hintCancelled then
HS.HintRemoving:Fire(label)
TweenService:Create(label, TweenInfo.new(self.TweenLength2, self.EasingStyle2, self.EasingDirection2), {Transparency = 1}):Play()
TweenService:Create(label:WaitForChild("BorderUIStroke"), TweenInfo.new(self.TweenLength2, self.EasingStyle2, self.EasingDirection2), {Transparency = 1}):Play()
TweenService:Create(label:WaitForChild("TextUIStroke"), TweenInfo.new(self.TweenLength2, self.EasingStyle2, self.EasingDirection2), {Transparency = 1}):Play()
task.wait(self.TweenLength2)
label:Destroy()
elseif hintCancelled then
return
end
end
elseif type == "None" then
if self.InfiniteTime == true then
HS.HintAdding:Fire(label)
self.BroadcastRecieved:Fire()
label.TextTransparency = self.LabelTransparency
label.BackgroundTransparency = self.HintTransparency
label:WaitForChild("BorderUIStroke").Transparency = self.HintTransparency
label:WaitForChild("BorderUIStroke").Transparency = self.LabelTransparency
else
HS.HintAdding:Fire(label)
self.BroadcastRecieved:Fire()
label.TextTransparency = self.LabelTransparency
label.BackgroundTransparency = self.HintTransparency
label:WaitForChild("BorderUIStroke").Transparency = self.HintTransparency
label:WaitForChild("BorderUIStroke").Transparency = self.LabelTransparency
task.wait(self.VisibleTime)
if not hintCancelled then
HS.HintRemoving:Fire(label)
label.Transparency = 1
label:WaitForChild("BorderUIStroke").Transparency = 1
label:WaitForChild("BorderUIStroke").Transparency = 1
label:Destroy()
elseif hintCancelled then
return
end
end
end
end
HintsGui.Parent = PlayerGui
HintsGui.Archivable = false
--
HS.HintAdding = Signal.new()
HS.HintRemoving = Signal.new()
--
GuiService.MenuOpened:Connect(function()
onMenuOpenedConfig(false)
end)
GuiService.MenuClosed:Connect(function()
onMenuOpenedConfig(true)
end)
---------- Constructors ----------
function HS.new(xAlignment : "Left" | "Center" | "Right")
local newClass = setmetatable({ }, {__index = HS})
newClass._ = script.Assets:WaitForChild("HintMsg"):Clone()
local HintsFrame = HintsGui.HintsFrame
if xAlignment == "Right" then
StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.PlayerList, false)
newClass._.Parent = HintsFrame.RightFrame
newClass.HintXAlignment = 3
elseif xAlignment == "Center" then
newClass._.Parent = HintsFrame.CenterFrame
newClass.HintXAlignment = 2
elseif xAlignment == "Left" then
newClass._.Parent = HintsFrame.LeftFrame
newClass.HintXAlignment = 1
end
newClass.HintXAlignment = 2
newClass.HintTheme = DefaultTheme
newClass.VisibleTime = 12
newClass.HintTransparency = newClass.HintTheme.hintTransparency
newClass.LabelTransparency = newClass.HintTheme.labelTransparency
newClass.EasingDirection1 = Enum.EasingDirection.In
newClass.EasingDirection2 = Enum.EasingDirection.Out
newClass.EasingStyle1 = Enum.EasingStyle.Quad
newClass.EasingStyle2 = Enum.EasingStyle.Quad
newClass.TweenLength1 = 1
newClass.TweenLength2 = 1
newClass.Cancelled = false
newClass.BroadcastCancelled = Signal.new()
newClass.BroadcastRecieved = Signal.new()
newClass.Broadcasted = Signal.new()
newClass.InfiniteTime = false
newClass.AnimationType = "Fade"
newClass.EligibleToBeCancelled = false
return newClass
end
---------- Setting Methods ----------
function HS:setLabel(text : string)
text = text or ""
for k,v in ipairs(DisallowedWhiteSpace) do
if string.find(text, v) then
customError2("Whitespaces are not allowed.")
end
end
local label = self._
label.Text = text
end
function HS:setVisibleTime(isInfinite : boolean, time : number)
time = time or 12
isInfinite = isInfinite or false
local label = self._
self.InfiniteTime = isInfinite
self.VisibleTime = time
end
function HS:setRichText(enabled : boolean)
enabled = enabled or false
local label = self._
label.RichText = enabled
end
function HS:setTweenLength(length1 : number, length2 : number)
length1 = length1 or 1
length2 = length2 or 1
self.TweenLength1 = length1
self.TweenLength2 = length2
end
function HS:setTweenDirection(direction1 : Enum.EasingDirection, direction2 : Enum.EasingDirection)
direction1 = direction1 or Enum.EasingDirection.In
direction2 = direction2 or Enum.EasingDirection.Out
self.EasingDirection1 = direction1
self.EasingDirection2 = direction2
end
function HS:setTweenStyle(style1 : Enum.EasingStyle, style2 : Enum.EasingStyle)
style1 = style1 or Enum.EasingStyle.Quad
style2 = style2 or Enum.EasingStyle.Quad
self.EasingStyle1 = style1
self.EasingStyle2 = style2
end
function HS:setTheme(theme : string)
if ThemesFolder:FindFirstChild(theme) and ThemesFolder:FindFirstChild(theme):IsA("ModuleScript") then
self.HintTheme = require(ThemesFolder:FindFirstChild(theme))
else
invalidError(theme, "theme")
end
end
function HS:setTweenType(type : "Fade" | "None")
self.AnimationType = type
end
---------- Getting Methods ----------
function HS:getLabel(): string
return self._.Text
end
function HS:getLabelFont(returnAsString : boolean): Enum.Font | string
if returnAsString then
return self._.Font.Name
else
return self._.Font
end
end
function HS:getCurrentHints(): {TextLabel}
local hintsTable = {}
for k,v in pairs(HintsGui.HintsFrame:GetDescendants()) do
if v:IsA("TextLabel") and v.Name == "HintMsg" then
table.insert(hintsTable, v)
end
end
return hintsTable
end
function HS:getVisibleTime(): number
return self.VisibleTime
end
function HS:getTweenLength(type : "1" | "2"): number
if type == "1" then
return self.TweenLength1
else
return self.TweenLength2
end
end
function HS:getTweenDirection(type : "1" | "2"): Enum.EasingDirection
if type == "1" then
return self.EasingDirection1
else
return self.EasingDirection2
end
end
function HS:getTweenStyle(type : "1" | "2"): Enum.EasingStyle
if type == "1" then
return self.EasingStyle1
else
return self.EasingStyle2
end
end
function HS:getTweenType(type : "1" | "2"): "Fade" | "None"
return self.AnimationType
end
function HS:getDestroyOnFinished(): boolean
return self.DestroyOnFinished
end
function HS:getRichTextEnabled(): boolean
return self._.RichText
end
function HS:getHintXAlignment(): number
return self.HintXAlignment
end
function HS:getTheme(): ModuleScript
return self.HintTheme
end
function HS:getEligibleToBeCancelled(): boolean
return self.EligibleToBeCancelled
end
function HS:getHintSize(): Vector2
return self._.AbsoluteSize
end
function HS:getLabelPadding(): number
return self._.ExtraPadding.PaddingLeft, self._.ExtraPadding.PaddingRight
end
---------- Broadcast Methods ----------
function HS:broadcastHintToClient(yieldThread : boolean)
yieldThread = yieldThread or false
local label = self._
local EligibleToBeCancelled = self.EligibleToBeCancelled
EligibleToBeCancelled = true
setHintProperties(self)
if yieldThread then
self.Broadcasted:Fire()
animateHint()
else
self.Broadcasted:Fire()
task.spawn(function()
animateHint(self)
end)
end
end
function HS:cancelBroadcast()
local label = self._
local broadcastCancelled = self.Cancelled
self.BroadcastCancelled:Fire()
cancelHint(self)
end
return HS