Port some more corescripts to Yuescript
This commit is contained in:
parent
58df0a7c90
commit
3e5996b701
|
|
@ -0,0 +1,834 @@
|
|||
local Create = assert(LoadLibrary("RbxUtility")).Create
|
||||
local gui = script.Parent:FindFirstChild("ControlFrame") or script.Parent
|
||||
local Dev_Container = Create("Frame")({
|
||||
Name = "DevConsoleContainer",
|
||||
Parent = gui,
|
||||
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||
BackgroundTransparency = 0.9,
|
||||
Position = UDim2.new(0, 100, 0, 10),
|
||||
Size = UDim2.new(0.5, 20, 0.5, 20),
|
||||
Visible = false
|
||||
})
|
||||
local ToggleConsole = Create("BindableFunction")({
|
||||
Name = "ToggleDevConsole",
|
||||
Parent = gui
|
||||
})
|
||||
local devConsoleInitialized = false
|
||||
local initializeDeveloperConsole
|
||||
initializeDeveloperConsole = function()
|
||||
if devConsoleInitialized then
|
||||
return
|
||||
end
|
||||
devConsoleInitialized = true
|
||||
local LOCAL_CONSOLE = 1
|
||||
local SERVER_CONSOLE = 2
|
||||
local MAX_LIST_SIZE = 1000
|
||||
local minimumSize = Vector2.new(245, 180)
|
||||
local currentConsole = LOCAL_CONSOLE
|
||||
local localMessageList = { }
|
||||
local serverMessageList = { }
|
||||
local localOffset = 0
|
||||
local serverOffset = 0
|
||||
local errorToggleOn = true
|
||||
local warningToggleOn = true
|
||||
local infoToggleOn = true
|
||||
local outputToggleOn = true
|
||||
local wordWrapToggleOn = false
|
||||
local textHolderSize = 0
|
||||
local frameNumber = 0
|
||||
local Dev_Body = Create("Frame")({
|
||||
Name = "Body",
|
||||
Parent = Dev_Container,
|
||||
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||
BackgroundTransparency = 0.5,
|
||||
Position = UDim2.new(0, 0, 0, 21),
|
||||
Size = UDim2.new(1, 0, 1, -25)
|
||||
})
|
||||
local Dev_OptionsHolder = Create("Frame")({
|
||||
Name = "OptionsHolder",
|
||||
Parent = Dev_Body,
|
||||
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(0, 220, 0, 0),
|
||||
Size = UDim2.new(1, -255, 0, 24),
|
||||
ClipsDescendants = true
|
||||
})
|
||||
local Dev_OptionsBar = Create("Frame")({
|
||||
Name = "OptionsBar",
|
||||
Parent = Dev_OptionsHolder,
|
||||
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(0, -250, 0, 4),
|
||||
Size = UDim2.new(0, 234, 0, 18)
|
||||
})
|
||||
local Dev_ErrorToggleFilter = Create("TextButton")({
|
||||
Name = "ErrorToggleButton",
|
||||
Parent = Dev_OptionsBar,
|
||||
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||
BorderColor3 = Color3.new(1, 0, 0),
|
||||
Position = UDim2.new(0, 115, 0, 0),
|
||||
Size = UDim2.new(0, 18, 0, 18),
|
||||
Font = "SourceSansBold",
|
||||
FontSize = Enum.FontSize.Size14,
|
||||
Text = "",
|
||||
TextColor3 = Color3.new(1, 0, 0)
|
||||
})
|
||||
Create("Frame")({
|
||||
Name = "CheckFrame",
|
||||
Parent = Dev_ErrorToggleFilter,
|
||||
BackgroundColor3 = Color3.new(1, 0, 0),
|
||||
BorderColor3 = Color3.new(1, 0, 0),
|
||||
Position = UDim2.new(0, 4, 0, 4),
|
||||
Size = UDim2.new(0, 10, 0, 10)
|
||||
})
|
||||
local Dev_InfoToggleFilter = Create("TextButton")({
|
||||
Name = "InfoToggleButton",
|
||||
Parent = Dev_OptionsBar,
|
||||
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||
BorderColor3 = Color3.new(0.4, 0.5, 1.0),
|
||||
Position = UDim2.new(0, 65, 0, 0),
|
||||
Size = UDim2.new(0, 18, 0, 18),
|
||||
Font = "SourceSansBold",
|
||||
FontSize = Enum.FontSize.Size14,
|
||||
Text = "",
|
||||
TextColor3 = Color3.new(0.4, 0.5, 1.0)
|
||||
})
|
||||
Create("Frame")({
|
||||
Name = "CheckFrame",
|
||||
Parent = Dev_InfoToggleFilter,
|
||||
BackgroundColor3 = Color3.new(0.4, 0.5, 1.0),
|
||||
BorderColor3 = Color3.new(0.4, 0.5, 1.0),
|
||||
Position = UDim2.new(0, 4, 0, 4),
|
||||
Size = UDim2.new(0, 10, 0, 10)
|
||||
})
|
||||
local Dev_OutputToggleFilter = Create("TextButton")({
|
||||
Name = "OutputToggleButton",
|
||||
Parent = Dev_OptionsBar,
|
||||
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||
BorderColor3 = Color3.new(1, 1, 1.0),
|
||||
Position = UDim2.new(0, 40, 0, 0),
|
||||
Size = UDim2.new(0, 18, 0, 18),
|
||||
Font = "SourceSansBold",
|
||||
FontSize = Enum.FontSize.Size14,
|
||||
Text = "",
|
||||
TextColor3 = Color3.new(1, 1, 1.0)
|
||||
})
|
||||
Create("Frame")({
|
||||
Name = "CheckFrame",
|
||||
Parent = Dev_OutputToggleFilter,
|
||||
BackgroundColor3 = Color3.new(1, 1, 1.0),
|
||||
BorderColor3 = Color3.new(1, 1, 1.0),
|
||||
Position = UDim2.new(0, 4, 0, 4),
|
||||
Size = UDim2.new(0, 10, 0, 10)
|
||||
})
|
||||
local Dev_WarningToggleFilter = Create("TextButton")({
|
||||
Name = "WarningToggleButton",
|
||||
Parent = Dev_OptionsBar,
|
||||
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||
BorderColor3 = Color3.new(1, 0.6, 0.4),
|
||||
Position = UDim2.new(0, 90, 0, 0),
|
||||
Size = UDim2.new(0, 18, 0, 18),
|
||||
Font = "SourceSansBold",
|
||||
FontSize = Enum.FontSize.Size14,
|
||||
Text = "",
|
||||
TextColor3 = Color3.new(1, 0.6, 0.4)
|
||||
})
|
||||
Create("Frame")({
|
||||
Name = "CheckFrame",
|
||||
Parent = Dev_WarningToggleFilter,
|
||||
BackgroundColor3 = Color3.new(1, 0.6, 0.4),
|
||||
BorderColor3 = Color3.new(1, 0.6, 0.4),
|
||||
Position = UDim2.new(0, 4, 0, 4),
|
||||
Size = UDim2.new(0, 10, 0, 10)
|
||||
})
|
||||
local Dev_WordWrapToggle = Create("TextButton")({
|
||||
Name = "WordWrapToggleButton",
|
||||
Parent = Dev_OptionsBar,
|
||||
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||
BorderColor3 = Color3.new(0.8, 0.8, 0.8),
|
||||
Position = UDim2.new(0, 215, 0, 0),
|
||||
Size = UDim2.new(0, 18, 0, 18),
|
||||
Font = "SourceSansBold",
|
||||
FontSize = Enum.FontSize.Size14,
|
||||
Text = "",
|
||||
TextColor3 = Color3.new(0.8, 0.8, 0.8)
|
||||
})
|
||||
Create("Frame")({
|
||||
Name = "CheckFrame",
|
||||
Parent = Dev_WordWrapToggle,
|
||||
BackgroundColor3 = Color3.new(0.8, 0.8, 0.8),
|
||||
BorderColor3 = Color3.new(0.8, 0.8, 0.8),
|
||||
Position = UDim2.new(0, 4, 0, 4),
|
||||
Size = UDim2.new(0, 10, 0, 10),
|
||||
Visible = false
|
||||
})
|
||||
Create("TextLabel")({
|
||||
Name = "Filter",
|
||||
Parent = Dev_OptionsBar,
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(0, 0, 0, 0),
|
||||
Size = UDim2.new(0, 40, 0, 18),
|
||||
Font = "SourceSansBold",
|
||||
FontSize = Enum.FontSize.Size14,
|
||||
Text = "Filter",
|
||||
TextColor3 = Color3.new(1, 1, 1)
|
||||
})
|
||||
Create("TextLabel")({
|
||||
Name = "WordWrap",
|
||||
Parent = Dev_OptionsBar,
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(0, 150, 0, 0),
|
||||
Size = UDim2.new(0, 50, 0, 18),
|
||||
Font = "SourceSansBold",
|
||||
FontSize = Enum.FontSize.Size14,
|
||||
Text = "Word Wrap",
|
||||
TextColor3 = Color3.new(1, 1, 1)
|
||||
})
|
||||
local Dev_ScrollBar = Create("Frame")({
|
||||
Name = "ScrollBar",
|
||||
Parent = Dev_Body,
|
||||
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||
BackgroundTransparency = 0.9,
|
||||
Position = UDim2.new(1, -20, 0, 26),
|
||||
Size = UDim2.new(0, 20, 1, -50),
|
||||
Visible = false
|
||||
})
|
||||
local Dev_ScrollArea = Create("Frame")({
|
||||
Name = "ScrollArea",
|
||||
Parent = Dev_ScrollBar,
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(0, 0, 0, 23),
|
||||
Size = UDim2.new(1, 0, 1, -46)
|
||||
})
|
||||
local Dev_Handle = Create("ImageButton")({
|
||||
Name = "Handle",
|
||||
Parent = Dev_ScrollArea,
|
||||
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||
BackgroundTransparency = 0.5,
|
||||
Position = UDim2.new(0, 0, 0.2, 0),
|
||||
Size = UDim2.new(0, 20, 0, 40)
|
||||
})
|
||||
Create("ImageLabel")({
|
||||
Name = "ImageLabel",
|
||||
Parent = Dev_Handle,
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(0, 0, 0.5, -8),
|
||||
Rotation = 180,
|
||||
Size = UDim2.new(1, 0, 0, 16),
|
||||
Image = "http://www.roblox.com/Asset?id=151205881"
|
||||
})
|
||||
local Dev_DownButton = Create("ImageButton")({
|
||||
Name = "Down",
|
||||
Parent = Dev_ScrollBar,
|
||||
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||
BackgroundTransparency = 0.5,
|
||||
Position = UDim2.new(0, 0, 1, -20),
|
||||
Size = UDim2.new(0, 20, 0, 20)
|
||||
})
|
||||
Create("ImageLabel")({
|
||||
Name = "ImageLabel",
|
||||
Parent = Dev_DownButton,
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(0, 3, 0, 3),
|
||||
Size = UDim2.new(0, 14, 0, 14),
|
||||
Rotation = 180,
|
||||
Image = "http://www.roblox.com/Asset?id=151205813"
|
||||
})
|
||||
local Dev_UpButton = Create("ImageButton")({
|
||||
Name = "Up",
|
||||
Parent = Dev_ScrollBar,
|
||||
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||
BackgroundTransparency = 0.5,
|
||||
Position = UDim2.new(0, 0, 0, 0),
|
||||
Size = UDim2.new(0, 20, 0, 20)
|
||||
})
|
||||
Create("ImageLabel")({
|
||||
Name = "ImageLabel",
|
||||
Parent = Dev_UpButton,
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(0, 3, 0, 3),
|
||||
Size = UDim2.new(0, 14, 0, 14),
|
||||
Image = "http://www.roblox.com/Asset?id=151205813"
|
||||
})
|
||||
local Dev_TextBox = Create("Frame")({
|
||||
Name = "TextBox",
|
||||
Parent = Dev_Body,
|
||||
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||
BackgroundTransparency = 0.6,
|
||||
Position = UDim2.new(0, 2, 0, 26),
|
||||
Size = UDim2.new(1, -4, 1, -28),
|
||||
ClipsDescendants = true
|
||||
})
|
||||
local Dev_TextHolder = Create("Frame")({
|
||||
Name = "TextHolder",
|
||||
Parent = Dev_TextBox,
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(0, 0, 0, 0),
|
||||
Size = UDim2.new(1, 0, 1, 0)
|
||||
})
|
||||
local Dev_OptionsButton = Create("ImageButton")({
|
||||
Name = "OptionsButton",
|
||||
Parent = Dev_Body,
|
||||
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(0, 200, 0, 2),
|
||||
Size = UDim2.new(0, 20, 0, 20)
|
||||
})
|
||||
Create("ImageLabel")({
|
||||
Name = "ImageLabel",
|
||||
Parent = Dev_OptionsButton,
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(0, 0, 0, 0),
|
||||
Size = UDim2.new(1, 0, 1, 0),
|
||||
Rotation = 0,
|
||||
Image = "http://www.roblox.com/Asset?id=152093917"
|
||||
})
|
||||
local Dev_ResizeButton = Create("ImageButton")({
|
||||
Name = "ResizeButton",
|
||||
Parent = Dev_Body,
|
||||
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||
BackgroundTransparency = 0.5,
|
||||
Position = UDim2.new(1, -20, 1, -20),
|
||||
Size = UDim2.new(0, 20, 0, 20)
|
||||
})
|
||||
Create("ImageLabel")({
|
||||
Name = "ImageLabel",
|
||||
Parent = Dev_ResizeButton,
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(0, 6, 0, 6),
|
||||
Size = UDim2.new(0.8, 0, 0.8, 0),
|
||||
Rotation = 135,
|
||||
Image = "http://www.roblox.com/Asset?id=151205813"
|
||||
})
|
||||
Create("TextButton")({
|
||||
Name = "LocalConsole",
|
||||
Parent = Dev_Body,
|
||||
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||
BackgroundTransparency = 0.6,
|
||||
Position = UDim2.new(0, 7, 0, 5),
|
||||
Size = UDim2.new(0, 90, 0, 20),
|
||||
Font = "SourceSansBold",
|
||||
FontSize = Enum.FontSize.Size14,
|
||||
Text = "Local Console",
|
||||
TextColor3 = Color3.new(1, 1, 1),
|
||||
TextYAlignment = Enum.TextYAlignment.Center
|
||||
})
|
||||
Create("TextButton")({
|
||||
Name = "ServerConsole",
|
||||
Parent = Dev_Body,
|
||||
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||
BackgroundTransparency = 0.8,
|
||||
Position = UDim2.new(0, 102, 0, 5),
|
||||
Size = UDim2.new(0, 90, 0, 17),
|
||||
Font = "SourceSansBold",
|
||||
FontSize = Enum.FontSize.Size14,
|
||||
Text = "Server Console",
|
||||
TextColor3 = Color3.new(1, 1, 1),
|
||||
TextYAlignment = Enum.TextYAlignment.Center
|
||||
})
|
||||
local Dev_TitleBar = Create("Frame")({
|
||||
Name = "TitleBar",
|
||||
Parent = Dev_Container,
|
||||
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||
BackgroundTransparency = 0.5,
|
||||
Position = UDim2.new(0, 0, 0, 0),
|
||||
Size = UDim2.new(1, 0, 0, 20)
|
||||
})
|
||||
local Dev_CloseButton = Create("ImageButton")({
|
||||
Name = "CloseButton",
|
||||
Parent = Dev_TitleBar,
|
||||
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||
BackgroundTransparency = 0.5,
|
||||
Position = UDim2.new(1, -20, 0, 0),
|
||||
Size = UDim2.new(0, 20, 0, 20)
|
||||
})
|
||||
Create("ImageLabel")({
|
||||
Parent = Dev_CloseButton,
|
||||
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(0, 3, 0, 3),
|
||||
Size = UDim2.new(0, 14, 0, 14),
|
||||
Image = "http://www.roblox.com/Asset?id=151205852"
|
||||
})
|
||||
Create("TextButton")({
|
||||
Name = "TextButton",
|
||||
Parent = Dev_TitleBar,
|
||||
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||
BackgroundTransparency = 0.5,
|
||||
Position = UDim2.new(0, 0, 0, 0),
|
||||
Size = UDim2.new(1, -23, 1, 0),
|
||||
Text = ""
|
||||
})
|
||||
Create("TextLabel")({
|
||||
Name = "TitleText",
|
||||
Parent = Dev_TitleBar,
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(0, 0, 0, 0),
|
||||
Size = UDim2.new(0, 185, 0, 20),
|
||||
Font = "SourceSansBold",
|
||||
FontSize = Enum.FontSize.Size18,
|
||||
TextColor3 = Color3.new(1, 1, 1),
|
||||
Text = "Roblox Developer Console",
|
||||
TextYAlignment = Enum.TextYAlignment.Top
|
||||
})
|
||||
local previousMousePos
|
||||
local pPos
|
||||
local previousMousePosResize
|
||||
local pSize
|
||||
local previousMousePosScroll
|
||||
local pOffset
|
||||
local scrollUpIsDown = false
|
||||
local scrollDownIsDown = false
|
||||
local clean
|
||||
clean = function()
|
||||
previousMousePos = nil
|
||||
pPos = nil
|
||||
previousMousePosResize = nil
|
||||
pSize = nil
|
||||
previousMousePosScroll = nil
|
||||
pOffset = nil
|
||||
scrollUpIsDown = false
|
||||
scrollDownIsDown = false
|
||||
end
|
||||
local refreshConsolePosition
|
||||
refreshConsolePosition = function(x, y)
|
||||
if not previousMousePos then
|
||||
return
|
||||
end
|
||||
local delta = Vector2.new(x, y - previousMousePos)
|
||||
Dev_Container.Position = UDim2.new(0, pPos.X + delta.X, 0, pPos.Y + delta.Y)
|
||||
end
|
||||
Dev_TitleBar.TextButton.MouseButton1Down:connect(function(x, y)
|
||||
previousMousePos = Vector2.new(x, y)
|
||||
pPos = Dev_Container.AbsolutePosition
|
||||
end)
|
||||
Dev_TitleBar.TextButton.MouseButton1Up:connect(clean)
|
||||
local refreshConsoleSize
|
||||
refreshConsoleSize = function(x, y)
|
||||
if not previousMousePosResize then
|
||||
return
|
||||
end
|
||||
local delta = Vector2.new(x, y - previousMousePosResize)
|
||||
Dev_Container.Size = UDim2.new(0, math.max(pSize.X + delta.X, minimumSize.X), 0, math.max(pSize.Y + delta.Y, minimumSize.Y))
|
||||
end
|
||||
Dev_Container.Body.ResizeButton.MouseButton1Down:connect(function(x, y)
|
||||
previousMousePosResize = Vector2.new(x, y)
|
||||
pSize = Dev_Container.AbsoluteSize
|
||||
end)
|
||||
Dev_Container.Body.ResizeButton.MouseButton1Up:connect(clean)
|
||||
Dev_TitleBar.CloseButton.MouseButton1Down:connect(function()
|
||||
Dev_Container.Visible = false
|
||||
end)
|
||||
Dev_Container.TitleBar.CloseButton.MouseButton1Up:connect(clean)
|
||||
local optionsHidden = true
|
||||
local animating = false
|
||||
local startAnimation
|
||||
startAnimation = function()
|
||||
if animating then
|
||||
return
|
||||
end
|
||||
animating = true
|
||||
repeat
|
||||
frameNumber = frameNumber + (function()
|
||||
if optionsHidden then
|
||||
return -1
|
||||
else
|
||||
return 1
|
||||
end
|
||||
end)()
|
||||
local x = frameNumber / 5
|
||||
local smoothStep = x * x * (3 - (2 * x))
|
||||
Dev_OptionsButton.ImageLabel.Rotation = smoothStep * 5 * 9
|
||||
Dev_OptionsBar.Position = UDim2.new(0, (smoothStep * 5 * 50) - 250, 0, 4)
|
||||
wait()
|
||||
if (frameNumber <= 0 and optionsHidden) or (frameNumber >= 5 and not optionsHidden) then
|
||||
animating = false
|
||||
end
|
||||
until not animating
|
||||
end
|
||||
Dev_OptionsButton.MouseButton1Down:connect(function()
|
||||
optionsHidden = not optionsHidden
|
||||
return startAnimation()
|
||||
end)
|
||||
local repositionList
|
||||
repositionList = function()
|
||||
if currentConsole == LOCAL_CONSOLE then
|
||||
localOffset = math.min(math.max(localOffset, 0), textHolderSize - Dev_Container.Body.TextBox.AbsoluteSize.Y)
|
||||
Dev_TextHolder.Size = UDim2.new(1, 0, 0, textHolderSize)
|
||||
elseif currentConsole == SERVER_CONSOLE then
|
||||
serverOffset = math.min(math.max(serverOffset, 0), textHolderSize - Dev_Container.Body.TextBox.AbsoluteSize.Y)
|
||||
Dev_TextHolder.Size = UDim2.new(1, 0, 0, textHolderSize)
|
||||
end
|
||||
local ratio = Dev_Container.Body.TextBox.AbsoluteSize.Y / Dev_TextHolder.AbsoluteSize.Y
|
||||
if ratio >= 1 then
|
||||
Dev_Container.Body.ScrollBar.Visible = false
|
||||
Dev_Container.Body.TextBox.Size = UDim2.new(1, -4, 1, -28)
|
||||
if currentConsole == LOCAL_CONSOLE or currentConsole == SERVER_CONSOLE then
|
||||
Dev_TextHolder.Position = UDim2.new(0, 0, 1, 0 - textHolderSize)
|
||||
end
|
||||
else
|
||||
Dev_Container.Body.ScrollBar.Visible = true
|
||||
Dev_Container.Body.TextBox.Size = UDim2.new(1, -25, 1, -28)
|
||||
local backRatio = 1 - ratio
|
||||
local offsetRatio
|
||||
if currentConsole == LOCAL_CONSOLE then
|
||||
offsetRatio = localOffset / Dev_TextHolder.AbsoluteSize.Y
|
||||
elseif currentConsole == SERVER_CONSOLE then
|
||||
offsetRatio = serverOffset / Dev_TextHolder.AbsoluteSize.Y
|
||||
end
|
||||
local topRatio = math.max(0, backRatio - offsetRatio)
|
||||
local scrollHandleSize = math.max(Dev_ScrollArea.AbsoluteSize.Y * ratio, 21)
|
||||
local scrollRatio = scrollHandleSize / Dev_ScrollArea.AbsoluteSize.Y
|
||||
local ratioConversion = (1 - scrollRatio) / (1 - ratio)
|
||||
local topScrollRatio = topRatio * ratioConversion
|
||||
local sPos = math.min(Dev_ScrollArea.AbsoluteSize.Y * topScrollRatio, Dev_ScrollArea.AbsoluteSize.Y - scrollHandleSize)
|
||||
Dev_ScrollArea.Handle.Size = UDim2.new(1, 0, 0, scrollHandleSize)
|
||||
Dev_ScrollArea.Handle.Position = UDim2.new(0, 0, 0, sPos)
|
||||
Dev_TextHolder.Position = UDim2.new(0, 0, 1, 0 - textHolderSize + (function()
|
||||
if currentConsole == LOCAL_CONSOLE then
|
||||
return localOffset
|
||||
elseif currentConsole == SERVER_CONSOLE then
|
||||
return serverOffset
|
||||
end
|
||||
end)())
|
||||
end
|
||||
end
|
||||
local changeOffset
|
||||
changeOffset = function(value)
|
||||
if currentConsole == LOCAL_CONSOLE then
|
||||
localOffset = localOffset + value
|
||||
elseif currentConsole == SERVER_CONSOLE then
|
||||
serverOffset = serverOffset + value
|
||||
end
|
||||
return repositionList()
|
||||
end
|
||||
local refreshTextHolderForReal
|
||||
refreshTextHolderForReal = function()
|
||||
local childMessages = Dev_TextHolder:GetChildren()
|
||||
local messageList
|
||||
if currentConsole == LOCAL_CONSOLE then
|
||||
messageList = localMessageList
|
||||
elseif currentConsole == SERVER_CONSOLE then
|
||||
messageList = serverMessageList
|
||||
end
|
||||
local posOffset = 0
|
||||
for i = 1, #childMessages do
|
||||
childMessages[i].Visible = false
|
||||
end
|
||||
for i = 1, #messageList do
|
||||
local message
|
||||
local movePosition = false
|
||||
if i > #childMessages then
|
||||
message = Create("TextLabel")({
|
||||
Name = "Message",
|
||||
Parent = Dev_TextHolder,
|
||||
BackgroundTransparency = 1,
|
||||
TextXAlignment = "Left",
|
||||
Size = UDim2.new(1, 0, 0, 14),
|
||||
FontSize = "Size10",
|
||||
ZIndex = 1
|
||||
})
|
||||
movePosition = true
|
||||
else
|
||||
message = childMessages[i]
|
||||
end
|
||||
if (outputToggleOn or messageList[i].Type ~= Enum.MessageType.MessageOutput) and (infoToggleOn or messageList[i].Type ~= Enum.MessageType.MessageInfo) and (warningToggleOn or messageList[i].Type ~= Enum.MessageType.MessageWarning) and (errorToggleOn or messageList[i].Type ~= Enum.MessageType.MessageError) then
|
||||
do
|
||||
message.TextWrapped = wordWrapToggleOn
|
||||
message.Size = UDim2.new(0.98, 0, 0, 2000)
|
||||
message.Parent = Dev_Container
|
||||
message.Text = tostring(messageList[i].Time) .. " -- " .. tostring(messageList[i].Message)
|
||||
message.Size = UDim2.new(0.98, 0, 0, message.TextBounds.Y)
|
||||
message.Position = UDim2.new(0, 5, 0, posOffset)
|
||||
message.Parent = Dev_TextHolder
|
||||
posOffset = posOffset + message.TextBounds.Y
|
||||
end
|
||||
if movePosition then
|
||||
if (currentConsole == LOCAL_CONSOLE and localOffset > 0) or (currentConsole == SERVER_CONSOLE and serverOffset > 0) then
|
||||
changeOffset(message.TextBounds.Y)
|
||||
end
|
||||
end
|
||||
message.Visible = true
|
||||
message.TextColor3 = Color3.new((function()
|
||||
if messageList[i].Type == Enum.MessageType.MessageError then
|
||||
return 1, 0, 0
|
||||
elseif messageList[i].Type == Enum.MessageType.MessageInfo then
|
||||
return 0.4, 0.5, 1
|
||||
elseif messageList[i].Type == Enum.MessageType.MessageWarning then
|
||||
return 1, 0.6, 0.4
|
||||
else
|
||||
return 1, 1, 1
|
||||
end
|
||||
end)())
|
||||
end
|
||||
end
|
||||
textHolderSize = posOffset
|
||||
end
|
||||
local refreshQueued = false
|
||||
local refreshTextHolder
|
||||
refreshTextHolder = function()
|
||||
if refreshQueued then
|
||||
return
|
||||
end
|
||||
Delay(0.1, function()
|
||||
refreshQueued = false
|
||||
return refreshTextHolderForReal()
|
||||
end)
|
||||
refreshQueued = true
|
||||
end
|
||||
local inside = 0
|
||||
local holdingUpButton
|
||||
holdingUpButton = function()
|
||||
if scrollUpIsDown then
|
||||
return
|
||||
end
|
||||
scrollUpIsDown = true
|
||||
wait(0.6)
|
||||
inside = inside + 1
|
||||
while scrollUpIsDown and inside < 2 do
|
||||
wait()
|
||||
changeOffset(12)
|
||||
end
|
||||
inside = inside - 1
|
||||
end
|
||||
local holdingDownButton
|
||||
holdingDownButton = function()
|
||||
if scrollDownIsDown then
|
||||
return
|
||||
end
|
||||
scrollDownIsDown = true
|
||||
wait(0.6)
|
||||
inside = inside + 1
|
||||
while scrollDownIsDown and inside < 2 do
|
||||
wait()
|
||||
changeOffset(-12)
|
||||
end
|
||||
inside = inside - 1
|
||||
end
|
||||
Dev_Container.Body.ScrollBar.Up.MouseButton1Click:connect(function()
|
||||
return changeOffset(10)
|
||||
end)
|
||||
Dev_Container.Body.ScrollBar.Up.MouseButton1Down:connect(function()
|
||||
changeOffset(10)
|
||||
return holdingUpButton()
|
||||
end)
|
||||
Dev_Container.Body.ScrollBar.Up.MouseButton1Up:connect(clean)
|
||||
Dev_Container.Body.ScrollBar.Down.MouseButton1Down:connect(function()
|
||||
changeOffset(-10)
|
||||
return holdingDownButton()
|
||||
end)
|
||||
Dev_Container.Body.ScrollBar.Down.MouseButton1Up:connect(clean)
|
||||
local handleScroll
|
||||
handleScroll = function(x, y)
|
||||
if not previousMousePosScroll then
|
||||
return
|
||||
end
|
||||
local delta = (Vector2.new(x, y - previousMousePosScroll)).Y
|
||||
local backRatio = 1 - (Dev_Container.Body.TextBox.AbsoluteSize.Y / Dev_TextHolder.AbsoluteSize.Y)
|
||||
local movementSize = Dev_ScrollArea.AbsoluteSize.Y - Dev_ScrollArea.Handle.AbsoluteSize.Y
|
||||
local normalDelta = math.max(math.min(delta, movementSize), 0 - movementSize)
|
||||
local normalRatio = normalDelta / movementSize
|
||||
local textMovementSize = (backRatio * Dev_TextHolder.AbsoluteSize.Y)
|
||||
local offsetChange = textMovementSize * normalRatio
|
||||
if currentConsole == LOCAL_CONSOLE then
|
||||
localOffset = pOffset - offsetChange
|
||||
elseif currentConsole == SERVER_CONSOLE then
|
||||
serverOffset = pOffset - offsetChange
|
||||
end
|
||||
end
|
||||
Dev_ScrollArea.Handle.MouseButton1Down:connect(function(x, y)
|
||||
previousMousePosScroll = Vector2.new(x, y)
|
||||
if currentConsole == LOCAL_CONSOLE then
|
||||
pOffset = localOffset
|
||||
elseif currentConsole == SERVER_CONSOLE then
|
||||
pOffset = serverOffset
|
||||
end
|
||||
end)
|
||||
Dev_ScrollArea.Handle.MouseButton1Up:connect(clean)
|
||||
local existsInsideContainer
|
||||
existsInsideContainer = function(container, x, y)
|
||||
local pos = container.AbsolutePosition
|
||||
local size = container.AbsoluteSize
|
||||
if x < pos.X or x > pos.X + size.X or y < pos.y or y > pos.y + size.y then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
local numberWithZero
|
||||
numberWithZero = function(num)
|
||||
if num < 10 then
|
||||
return "0" .. tostring(num)
|
||||
else
|
||||
return num
|
||||
end
|
||||
end
|
||||
local str = "%s:%s:%s"
|
||||
local ConvertTimeStamp
|
||||
ConvertTimeStamp = function(timeStamp)
|
||||
local localTime = timeStamp - os.time() + math.floor(tick())
|
||||
local dayTime = localTime % 86400
|
||||
local hour = math.floor(dayTime / 3600)
|
||||
dayTime = dayTime - (hour * 3600)
|
||||
local minute = math.floor(dayTime / 60)
|
||||
dayTime = dayTime - (minute * 60)
|
||||
local h = numberWithZero(hour)
|
||||
local m = numberWithZero(minute)
|
||||
local s = numberWithZero(dayTime)
|
||||
return str:format(h, m, s)
|
||||
end
|
||||
Dev_OptionsBar.ErrorToggleButton.MouseButton1Down:connect(function()
|
||||
errorToggleOn = not errorToggleOn
|
||||
Dev_OptionsBar.ErrorToggleButton.CheckFrame.Visible = errorToggleOn
|
||||
refreshTextHolder()
|
||||
return repositionList()
|
||||
end)
|
||||
Dev_OptionsBar.WarningToggleButton.MouseButton1Down:connect(function()
|
||||
warningToggleOn = not warningToggleOn
|
||||
Dev_OptionsBar.WarningToggleButton.CheckFrame.Visible = warningToggleOn
|
||||
refreshTextHolder()
|
||||
return repositionList()
|
||||
end)
|
||||
Dev_OptionsBar.InfoToggleButton.MouseButton1Down:connect(function()
|
||||
infoToggleOn = not infoToggleOn
|
||||
Dev_OptionsBar.InfoToggleButton.CheckFrame.Visible = infoToggleOn
|
||||
refreshTextHolder()
|
||||
return repositionList()
|
||||
end)
|
||||
Dev_OptionsBar.OutputToggleButton.MouseButton1Down:connect(function()
|
||||
outputToggleOn = not outputToggleOn
|
||||
Dev_OptionsBar.OutputToggleButton.CheckFrame.Visible = outputToggleOn
|
||||
refreshTextHolder()
|
||||
return repositionList()
|
||||
end)
|
||||
Dev_OptionsBar.WordWrapToggleButton.MouseButton1Down:connect(function()
|
||||
wordWrapToggleOn = not wordWrapToggleOn
|
||||
Dev_OptionsBar.WordWrapToggleButton.CheckFrame.Visible = wordWrapToggleOn
|
||||
refreshTextHolder()
|
||||
return repositionList()
|
||||
end)
|
||||
local AddLocalMessage
|
||||
AddLocalMessage = function(str, messageType, timeStamp)
|
||||
localMessageList[#localMessageList + 1] = {
|
||||
Message = str,
|
||||
Time = ConvertTimeStamp(timeStamp),
|
||||
Type = messageType
|
||||
}
|
||||
while #localMessageList > MAX_LIST_SIZE do
|
||||
table.remove(localMessageList, 1)
|
||||
end
|
||||
refreshTextHolder()
|
||||
return repositionList()
|
||||
end
|
||||
local AddServerMessage
|
||||
AddServerMessage = function(str, messageType, timeStamp)
|
||||
serverMessageList[#serverMessageList + 1] = {
|
||||
Message = str,
|
||||
Time = ConvertTimeStamp(timeStamp),
|
||||
Type = messageType
|
||||
}
|
||||
while #serverMessageList > MAX_LIST_SIZE do
|
||||
table.remove(serverMessageList, 1)
|
||||
end
|
||||
refreshTextHolder()
|
||||
return repositionList()
|
||||
end
|
||||
Dev_Container.Body.LocalConsole.MouseButton1Click:connect(function()
|
||||
if currentConsole == SERVER_CONSOLE then
|
||||
currentConsole = LOCAL_CONSOLE
|
||||
local localConsole = Dev_Container.Body.LocalConsole
|
||||
local serverConsole = Dev_Container.Body.ServerConsole
|
||||
localConsole.Size = UDim2.new(0, 90, 0, 20)
|
||||
serverConsole.Size = UDim2.new(0, 90, 0, 17)
|
||||
localConsole.BackgroundTransparency = 0.6
|
||||
serverConsole.BackgroundTransparency = 0.8
|
||||
if game:FindFirstChild("Players") and game.Players["LocalPlayer"] then
|
||||
local mouse = game.Players.LocalPlayer:GetMouse()
|
||||
refreshConsolePosition(mouse.X, mouse.Y)
|
||||
refreshConsoleSize(mouse.X, mouse.Y)
|
||||
handleScroll(mouse.X, mouse.Y)
|
||||
end
|
||||
refreshTextHolder()
|
||||
return repositionList()
|
||||
end
|
||||
end)
|
||||
Dev_Container.Body.LocalConsole.MouseButton1Up:connect(clean)
|
||||
local serverHistoryRequested = false
|
||||
Dev_Container.Body.ServerConsole.MouseButton1Click:connect(function()
|
||||
if not serverHistoryRequested then
|
||||
serverHistoryRequested = true
|
||||
game:GetService("LogService"):RequestServerOutput()
|
||||
end
|
||||
if currentConsole == LOCAL_CONSOLE then
|
||||
currentConsole = SERVER_CONSOLE
|
||||
local localConsole = Dev_Container.Body.LocalConsole
|
||||
local serverConsole = Dev_Container.Body.ServerConsole
|
||||
serverConsole.Size = UDim2.new(0, 90, 0, 20)
|
||||
localConsole.Size = UDim2.new(0, 90, 0, 17)
|
||||
serverConsole.BackgroundTransparency = 0.6
|
||||
localConsole.BackgroundTransparency = 0.8
|
||||
if game:FindFirstChild("Players") and game.Players["LocalPlayer"] then
|
||||
local mouse = game.Players.LocalPlayer:GetMouse()
|
||||
refreshConsolePosition(mouse.X, mouse.Y)
|
||||
refreshConsoleSize(mouse.X, mouse.Y)
|
||||
handleScroll(mouse.X, mouse.Y)
|
||||
end
|
||||
refreshTextHolder()
|
||||
return repositionList()
|
||||
end
|
||||
end)
|
||||
Dev_Container.Body.ServerConsole.MouseButton1Up:connect(clean)
|
||||
if game:FindFirstChild("Players") and game.Players["LocalPlayer"] then
|
||||
local LocalMouse = game.Players.LocalPlayer:GetMouse()
|
||||
LocalMouse.Move:connect(function()
|
||||
if not Dev_Container.Visible then
|
||||
return
|
||||
end
|
||||
local mouse = game.Players.LocalPlayer:GetMouse()
|
||||
refreshConsolePosition(mouse.X, mouse.Y)
|
||||
refreshConsoleSize(mouse.X, mouse.Y)
|
||||
handleScroll(mouse.X, mouse.Y)
|
||||
refreshTextHolder()
|
||||
return repositionList()
|
||||
end)
|
||||
LocalMouse.Button1Up:connect(clean)
|
||||
LocalMouse.WheelForward:connect(function()
|
||||
if not Dev_Container.Visible then
|
||||
return
|
||||
end
|
||||
if existsInsideContainer(Dev_Container, LocalMouse.X, LocalMouse.Y) then
|
||||
return changeOffset(10)
|
||||
end
|
||||
end)
|
||||
LocalMouse.WheelBackward:connect(function()
|
||||
if not Dev_Container.Visible then
|
||||
return
|
||||
end
|
||||
if existsInsideContainer(Dev_Container, LocalMouse.X, LocalMouse.Y) then
|
||||
return changeOffset(-10)
|
||||
end
|
||||
end)
|
||||
end
|
||||
Dev_ScrollArea.Handle.MouseButton1Down:connect(function()
|
||||
return repositionList()
|
||||
end)
|
||||
local history = game:GetService("LogService"):GetLogHistory()
|
||||
for i = 1, #history do
|
||||
AddLocalMessage(history[i].message, history[i].messageType, history[i].timestamp)
|
||||
end
|
||||
local _with_0 = game:GetService("LogService")
|
||||
_with_0.MessageOut:connect(function(message, messageType)
|
||||
return AddLocalMessage(message, messageType, os.time())
|
||||
end)
|
||||
_with_0.ServerMessageOut:connect(AddServerMessage)
|
||||
return _with_0
|
||||
end
|
||||
local currentlyToggling = false
|
||||
ToggleConsole.OnInvoke = function()
|
||||
if currentlyToggling then
|
||||
return
|
||||
end
|
||||
currentlyToggling = true
|
||||
initializeDeveloperConsole()
|
||||
Dev_Container.Visible = not Dev_Container.Visible
|
||||
currentlyToggling = false
|
||||
end
|
||||
|
|
@ -0,0 +1,914 @@
|
|||
--Include
|
||||
Create = assert(LoadLibrary "RbxUtility").Create
|
||||
|
||||
-- A Few Script Globals
|
||||
gui = script.Parent\FindFirstChild"ControlFrame" or script.Parent
|
||||
|
||||
-- Dev-Console Root
|
||||
|
||||
Dev_Container = Create"Frame"
|
||||
Name: "DevConsoleContainer"
|
||||
Parent: gui
|
||||
BackgroundColor3: Color3.new 0, 0, 0
|
||||
BackgroundTransparency: 0.9
|
||||
Position: UDim2.new 0, 100, 0, 10
|
||||
Size: UDim2.new 0.5, 20, 0.5, 20
|
||||
Visible: false
|
||||
|
||||
ToggleConsole = Create"BindableFunction"
|
||||
Name: "ToggleDevConsole"
|
||||
Parent: gui
|
||||
|
||||
devConsoleInitialized = false
|
||||
initializeDeveloperConsole = ->
|
||||
return if devConsoleInitialized
|
||||
devConsoleInitialized = true
|
||||
|
||||
---Dev-Console Variables
|
||||
LOCAL_CONSOLE = 1
|
||||
SERVER_CONSOLE = 2
|
||||
|
||||
MAX_LIST_SIZE = 1000
|
||||
|
||||
minimumSize = Vector2.new 245, 180
|
||||
currentConsole = LOCAL_CONSOLE
|
||||
|
||||
localMessageList = {}
|
||||
serverMessageList = {}
|
||||
|
||||
localOffset = 0
|
||||
serverOffset = 0
|
||||
|
||||
errorToggleOn = true
|
||||
warningToggleOn = true
|
||||
infoToggleOn = true
|
||||
outputToggleOn = true
|
||||
wordWrapToggleOn = false
|
||||
|
||||
textHolderSize = 0
|
||||
|
||||
frameNumber = 0
|
||||
|
||||
--Create Dev-Console
|
||||
|
||||
Dev_Body = Create"Frame"
|
||||
Name: "Body"
|
||||
Parent: Dev_Container
|
||||
BackgroundColor3: Color3.new 0, 0, 0
|
||||
BackgroundTransparency: 0.5
|
||||
Position: UDim2.new 0, 0, 0, 21
|
||||
Size: UDim2.new 1, 0, 1, -25
|
||||
|
||||
Dev_OptionsHolder = Create"Frame"
|
||||
Name: "OptionsHolder"
|
||||
Parent: Dev_Body
|
||||
BackgroundColor3: Color3.new 0, 0, 0
|
||||
BackgroundTransparency: 1
|
||||
Position: UDim2.new 0, 220, 0, 0
|
||||
Size: UDim2.new 1, -255, 0, 24
|
||||
ClipsDescendants: true
|
||||
|
||||
Dev_OptionsBar = Create"Frame"
|
||||
Name: "OptionsBar"
|
||||
Parent: Dev_OptionsHolder
|
||||
BackgroundColor3: Color3.new 0, 0, 0
|
||||
BackgroundTransparency: 1
|
||||
Position: UDim2.new 0, -250, 0, 4
|
||||
Size: UDim2.new 0, 234, 0, 18
|
||||
|
||||
Dev_ErrorToggleFilter = Create"TextButton"
|
||||
Name: "ErrorToggleButton"
|
||||
Parent: Dev_OptionsBar
|
||||
BackgroundColor3: Color3.new 0, 0, 0
|
||||
BorderColor3: Color3.new 1, 0, 0
|
||||
Position: UDim2.new 0, 115, 0, 0
|
||||
Size: UDim2.new 0, 18, 0, 18
|
||||
Font: "SourceSansBold"
|
||||
FontSize: Enum.FontSize.Size14
|
||||
Text: ""
|
||||
TextColor3: Color3.new 1, 0, 0
|
||||
|
||||
Create"Frame"
|
||||
Name: "CheckFrame"
|
||||
Parent: Dev_ErrorToggleFilter
|
||||
BackgroundColor3: Color3.new 1, 0, 0
|
||||
BorderColor3: Color3.new 1, 0, 0
|
||||
Position: UDim2.new 0, 4, 0, 4
|
||||
Size: UDim2.new 0, 10, 0, 10
|
||||
|
||||
Dev_InfoToggleFilter = Create"TextButton"
|
||||
Name: "InfoToggleButton"
|
||||
Parent: Dev_OptionsBar
|
||||
BackgroundColor3: Color3.new 0, 0, 0
|
||||
BorderColor3: Color3.new 0.4, 0.5, 1.0
|
||||
Position: UDim2.new 0, 65, 0, 0
|
||||
Size: UDim2.new 0, 18, 0, 18
|
||||
Font: "SourceSansBold"
|
||||
FontSize: Enum.FontSize.Size14
|
||||
Text: ""
|
||||
TextColor3: Color3.new 0.4, 0.5, 1.0
|
||||
|
||||
Create"Frame"
|
||||
Name: "CheckFrame"
|
||||
Parent: Dev_InfoToggleFilter
|
||||
BackgroundColor3: Color3.new 0.4, 0.5, 1.0
|
||||
BorderColor3: Color3.new 0.4, 0.5, 1.0
|
||||
Position: UDim2.new 0, 4, 0, 4
|
||||
Size: UDim2.new 0, 10, 0, 10
|
||||
|
||||
Dev_OutputToggleFilter = Create"TextButton"
|
||||
Name: "OutputToggleButton"
|
||||
Parent: Dev_OptionsBar
|
||||
BackgroundColor3: Color3.new 0, 0, 0
|
||||
BorderColor3: Color3.new 1, 1, 1.0
|
||||
Position: UDim2.new 0, 40, 0, 0
|
||||
Size: UDim2.new 0, 18, 0, 18
|
||||
Font: "SourceSansBold"
|
||||
FontSize: Enum.FontSize.Size14
|
||||
Text: ""
|
||||
TextColor3: Color3.new 1, 1, 1.0
|
||||
|
||||
Create"Frame"
|
||||
Name: "CheckFrame"
|
||||
Parent: Dev_OutputToggleFilter
|
||||
BackgroundColor3: Color3.new 1, 1, 1.0
|
||||
BorderColor3: Color3.new 1, 1, 1.0
|
||||
Position: UDim2.new 0, 4, 0, 4
|
||||
Size: UDim2.new 0, 10, 0, 10
|
||||
|
||||
Dev_WarningToggleFilter = Create"TextButton"
|
||||
Name: "WarningToggleButton"
|
||||
Parent: Dev_OptionsBar
|
||||
BackgroundColor3: Color3.new 0, 0, 0
|
||||
BorderColor3: Color3.new 1, 0.6, 0.4
|
||||
Position: UDim2.new 0, 90, 0, 0
|
||||
Size: UDim2.new 0, 18, 0, 18
|
||||
Font: "SourceSansBold"
|
||||
FontSize: Enum.FontSize.Size14
|
||||
Text: ""
|
||||
TextColor3: Color3.new 1, 0.6, 0.4
|
||||
|
||||
Create"Frame"
|
||||
Name: "CheckFrame"
|
||||
Parent: Dev_WarningToggleFilter
|
||||
BackgroundColor3: Color3.new 1, 0.6, 0.4
|
||||
BorderColor3: Color3.new 1, 0.6, 0.4
|
||||
Position: UDim2.new 0, 4, 0, 4
|
||||
Size: UDim2.new 0, 10, 0, 10
|
||||
|
||||
Dev_WordWrapToggle = Create"TextButton"
|
||||
Name: "WordWrapToggleButton"
|
||||
Parent: Dev_OptionsBar
|
||||
BackgroundColor3: Color3.new 0, 0, 0
|
||||
BorderColor3: Color3.new 0.8, 0.8, 0.8
|
||||
Position: UDim2.new 0, 215, 0, 0
|
||||
Size: UDim2.new 0, 18, 0, 18
|
||||
Font: "SourceSansBold"
|
||||
FontSize: Enum.FontSize.Size14
|
||||
Text: ""
|
||||
TextColor3: Color3.new 0.8, 0.8, 0.8
|
||||
|
||||
Create"Frame"
|
||||
Name: "CheckFrame"
|
||||
Parent: Dev_WordWrapToggle
|
||||
BackgroundColor3: Color3.new 0.8, 0.8, 0.8
|
||||
BorderColor3: Color3.new 0.8, 0.8, 0.8
|
||||
Position: UDim2.new 0, 4, 0, 4
|
||||
Size: UDim2.new 0, 10, 0, 10
|
||||
Visible: false
|
||||
|
||||
Create"TextLabel"
|
||||
Name: "Filter"
|
||||
Parent: Dev_OptionsBar
|
||||
BackgroundTransparency: 1
|
||||
Position: UDim2.new 0, 0, 0, 0
|
||||
Size: UDim2.new 0, 40, 0, 18
|
||||
Font: "SourceSansBold"
|
||||
FontSize: Enum.FontSize.Size14
|
||||
Text: "Filter"
|
||||
TextColor3: Color3.new 1, 1, 1
|
||||
|
||||
Create"TextLabel"
|
||||
Name: "WordWrap"
|
||||
Parent: Dev_OptionsBar
|
||||
BackgroundTransparency: 1
|
||||
Position: UDim2.new 0, 150, 0, 0
|
||||
Size: UDim2.new 0, 50, 0, 18
|
||||
Font: "SourceSansBold"
|
||||
FontSize: Enum.FontSize.Size14
|
||||
Text: "Word Wrap"
|
||||
TextColor3: Color3.new 1, 1, 1,
|
||||
|
||||
Dev_ScrollBar = Create"Frame"
|
||||
Name: "ScrollBar"
|
||||
Parent: Dev_Body
|
||||
BackgroundColor3: Color3.new 0, 0, 0
|
||||
BackgroundTransparency: 0.9
|
||||
Position: UDim2.new 1, -20, 0, 26
|
||||
Size: UDim2.new 0, 20, 1, -50
|
||||
Visible: false
|
||||
|
||||
Dev_ScrollArea = Create"Frame"
|
||||
Name: "ScrollArea"
|
||||
Parent: Dev_ScrollBar
|
||||
BackgroundTransparency: 1
|
||||
Position: UDim2.new 0, 0, 0, 23
|
||||
Size: UDim2.new 1, 0, 1, -46
|
||||
|
||||
Dev_Handle = Create"ImageButton"
|
||||
Name: "Handle"
|
||||
Parent: Dev_ScrollArea
|
||||
BackgroundColor3: Color3.new 0, 0, 0
|
||||
BackgroundTransparency: 0.5
|
||||
Position: UDim2.new 0, 0, 0.2, 0
|
||||
Size: UDim2.new 0, 20, 0, 40
|
||||
|
||||
Create"ImageLabel"
|
||||
Name: "ImageLabel"
|
||||
Parent: Dev_Handle
|
||||
BackgroundTransparency: 1
|
||||
Position: UDim2.new 0, 0, 0.5, -8
|
||||
Rotation: 180
|
||||
Size: UDim2.new 1, 0, 0, 16
|
||||
Image: "http://www.roblox.com/Asset?id=151205881"
|
||||
|
||||
Dev_DownButton = Create"ImageButton"
|
||||
Name: "Down"
|
||||
Parent: Dev_ScrollBar
|
||||
BackgroundColor3: Color3.new 0, 0, 0
|
||||
BackgroundTransparency: 0.5
|
||||
Position: UDim2.new 0, 0, 1, -20
|
||||
Size: UDim2.new 0, 20, 0, 20
|
||||
|
||||
Create"ImageLabel"
|
||||
Name: "ImageLabel"
|
||||
Parent: Dev_DownButton
|
||||
BackgroundTransparency: 1
|
||||
Position: UDim2.new 0, 3, 0, 3
|
||||
Size: UDim2.new 0, 14, 0, 14
|
||||
Rotation: 180
|
||||
Image: "http://www.roblox.com/Asset?id=151205813"
|
||||
|
||||
Dev_UpButton = Create"ImageButton"
|
||||
Name: "Up"
|
||||
Parent: Dev_ScrollBar
|
||||
BackgroundColor3: Color3.new 0, 0, 0
|
||||
BackgroundTransparency: 0.5
|
||||
Position: UDim2.new 0, 0, 0, 0
|
||||
Size: UDim2.new 0, 20, 0, 20
|
||||
|
||||
Create"ImageLabel"
|
||||
Name: "ImageLabel"
|
||||
Parent: Dev_UpButton
|
||||
BackgroundTransparency: 1
|
||||
Position: UDim2.new 0, 3, 0, 3
|
||||
Size: UDim2.new 0, 14, 0, 14
|
||||
Image: "http://www.roblox.com/Asset?id=151205813"
|
||||
|
||||
Dev_TextBox = Create"Frame"
|
||||
Name: "TextBox"
|
||||
Parent: Dev_Body
|
||||
BackgroundColor3: Color3.new 0, 0, 0
|
||||
BackgroundTransparency: 0.6
|
||||
Position: UDim2.new 0, 2, 0, 26
|
||||
Size: UDim2.new 1, -4, 1, -28
|
||||
ClipsDescendants: true
|
||||
|
||||
Dev_TextHolder = Create"Frame"
|
||||
Name: "TextHolder"
|
||||
Parent: Dev_TextBox
|
||||
BackgroundTransparency: 1
|
||||
Position: UDim2.new 0, 0, 0, 0
|
||||
Size: UDim2.new 1, 0, 1, 0
|
||||
|
||||
Dev_OptionsButton = Create"ImageButton"
|
||||
Name: "OptionsButton"
|
||||
Parent: Dev_Body
|
||||
BackgroundColor3: Color3.new 0, 0, 0
|
||||
BackgroundTransparency: 1
|
||||
Position: UDim2.new 0, 200, 0, 2
|
||||
Size: UDim2.new 0, 20, 0, 20
|
||||
|
||||
Create"ImageLabel"
|
||||
Name: "ImageLabel"
|
||||
Parent: Dev_OptionsButton
|
||||
BackgroundTransparency: 1
|
||||
Position: UDim2.new 0, 0, 0, 0
|
||||
Size: UDim2.new 1, 0, 1, 0
|
||||
Rotation: 0
|
||||
Image: "http://www.roblox.com/Asset?id=152093917"
|
||||
|
||||
Dev_ResizeButton = Create"ImageButton"
|
||||
Name: "ResizeButton"
|
||||
Parent: Dev_Body
|
||||
BackgroundColor3: Color3.new 0, 0, 0
|
||||
BackgroundTransparency: 0.5
|
||||
Position: UDim2.new 1, -20, 1, -20
|
||||
Size: UDim2.new 0, 20, 0, 20
|
||||
|
||||
Create"ImageLabel"
|
||||
Name: "ImageLabel"
|
||||
Parent: Dev_ResizeButton
|
||||
BackgroundTransparency: 1
|
||||
Position: UDim2.new 0, 6, 0, 6
|
||||
Size: UDim2.new 0.8, 0, 0.8, 0
|
||||
Rotation: 135
|
||||
Image: "http://www.roblox.com/Asset?id=151205813"
|
||||
|
||||
Create"TextButton"
|
||||
Name: "LocalConsole"
|
||||
Parent: Dev_Body
|
||||
BackgroundColor3: Color3.new 0, 0, 0
|
||||
BackgroundTransparency: 0.6
|
||||
Position: UDim2.new 0, 7, 0, 5
|
||||
Size: UDim2.new 0, 90, 0, 20
|
||||
Font: "SourceSansBold"
|
||||
FontSize: Enum.FontSize.Size14
|
||||
Text: "Local Console"
|
||||
TextColor3: Color3.new 1, 1, 1
|
||||
TextYAlignment: Enum.TextYAlignment.Center
|
||||
|
||||
Create"TextButton"
|
||||
Name: "ServerConsole"
|
||||
Parent: Dev_Body
|
||||
BackgroundColor3: Color3.new 0, 0, 0
|
||||
BackgroundTransparency: 0.8
|
||||
Position: UDim2.new 0, 102, 0, 5
|
||||
Size: UDim2.new 0, 90, 0, 17
|
||||
Font: "SourceSansBold"
|
||||
FontSize: Enum.FontSize.Size14
|
||||
Text: "Server Console"
|
||||
TextColor3: Color3.new 1, 1, 1
|
||||
TextYAlignment: Enum.TextYAlignment.Center
|
||||
|
||||
Dev_TitleBar = Create"Frame"
|
||||
Name: "TitleBar"
|
||||
Parent: Dev_Container
|
||||
BackgroundColor3: Color3.new 0, 0, 0
|
||||
BackgroundTransparency: 0.5
|
||||
Position: UDim2.new 0, 0, 0, 0
|
||||
Size: UDim2.new 1, 0, 0, 20
|
||||
|
||||
Dev_CloseButton = Create"ImageButton"
|
||||
Name: "CloseButton"
|
||||
Parent: Dev_TitleBar
|
||||
BackgroundColor3: Color3.new 0, 0, 0
|
||||
BackgroundTransparency: 0.5
|
||||
Position: UDim2.new 1, -20, 0, 0
|
||||
Size: UDim2.new 0, 20, 0, 20
|
||||
|
||||
Create"ImageLabel"
|
||||
Parent: Dev_CloseButton
|
||||
BackgroundColor3: Color3.new 0, 0, 0
|
||||
BackgroundTransparency: 1
|
||||
Position: UDim2.new 0, 3, 0, 3
|
||||
Size: UDim2.new 0, 14, 0, 14
|
||||
Image: "http://www.roblox.com/Asset?id=151205852"
|
||||
|
||||
Create"TextButton"
|
||||
Name: "TextButton"
|
||||
Parent: Dev_TitleBar
|
||||
BackgroundColor3: Color3.new 0, 0, 0
|
||||
BackgroundTransparency: 0.5
|
||||
Position: UDim2.new 0, 0, 0, 0
|
||||
Size: UDim2.new 1, -23, 1, 0
|
||||
Text: ""
|
||||
|
||||
Create"TextLabel"
|
||||
Name: "TitleText"
|
||||
Parent: Dev_TitleBar
|
||||
BackgroundTransparency: 1
|
||||
Position: UDim2.new 0, 0, 0, 0
|
||||
Size: UDim2.new 0, 185, 0, 20
|
||||
Font: "SourceSansBold"
|
||||
FontSize: Enum.FontSize.Size18
|
||||
-- Text: "Server Console"
|
||||
TextColor3: Color3.new 1, 1, 1
|
||||
Text: "Roblox Developer Console"
|
||||
TextYAlignment: Enum.TextYAlignment.Top
|
||||
|
||||
---Saved Mouse Information
|
||||
local previousMousePos
|
||||
local pPos
|
||||
|
||||
local previousMousePosResize
|
||||
local pSize
|
||||
|
||||
local previousMousePosScroll
|
||||
|
||||
-- local pScrollHandle
|
||||
|
||||
local pOffset
|
||||
|
||||
scrollUpIsDown = false
|
||||
scrollDownIsDown = false
|
||||
|
||||
clean = ->
|
||||
previousMousePos = pPos = previousMousePosResize = nil
|
||||
pSize = previousMousePosScroll = pOffset = nil
|
||||
-- pScrollHandle = nil
|
||||
scrollUpIsDown = scrollDownIsDown = false
|
||||
|
||||
|
||||
---Handle Dev-Console Position
|
||||
refreshConsolePosition = (x, y) ->
|
||||
return if not previousMousePos
|
||||
|
||||
delta = Vector2.new x, y - previousMousePos
|
||||
Dev_Container.Position = UDim2.new 0, pPos.X + delta.X, 0, pPos.Y + delta.Y
|
||||
|
||||
|
||||
Dev_TitleBar.TextButton.MouseButton1Down\connect (x, y) ->
|
||||
previousMousePos = Vector2.new x, y
|
||||
pPos = Dev_Container.AbsolutePosition
|
||||
|
||||
|
||||
Dev_TitleBar.TextButton.MouseButton1Up\connect clean
|
||||
|
||||
|
||||
---Handle Dev-Console Size
|
||||
refreshConsoleSize = (x, y) ->
|
||||
return if not previousMousePosResize
|
||||
|
||||
delta = Vector2.new x, y - previousMousePosResize
|
||||
Dev_Container.Size = UDim2.new 0, math.max(pSize.X + delta.X, minimumSize.X), 0, math.max pSize.Y + delta.Y, minimumSize.Y
|
||||
|
||||
Dev_Container.Body.ResizeButton.MouseButton1Down\connect (x, y) ->
|
||||
previousMousePosResize = Vector2.new x, y
|
||||
pSize = Dev_Container.AbsoluteSize
|
||||
|
||||
|
||||
Dev_Container.Body.ResizeButton.MouseButton1Up\connect clean
|
||||
|
||||
|
||||
---Handle Dev-Console Close Button
|
||||
Dev_TitleBar.CloseButton.MouseButton1Down\connect ->
|
||||
Dev_Container.Visible = false
|
||||
|
||||
|
||||
Dev_Container.TitleBar.CloseButton.MouseButton1Up\connect clean
|
||||
|
||||
|
||||
optionsHidden = true
|
||||
animating = false
|
||||
--Options
|
||||
startAnimation = ->
|
||||
return if animating
|
||||
animating = true
|
||||
|
||||
repeat
|
||||
frameNumber += if optionsHidden
|
||||
-1
|
||||
else
|
||||
1
|
||||
|
||||
|
||||
x = frameNumber / 5
|
||||
smoothStep = x * x * (3 - (2 * x))
|
||||
Dev_OptionsButton.ImageLabel.Rotation = smoothStep * 5 * 9
|
||||
Dev_OptionsBar.Position = UDim2.new(0, (smoothStep * 5 * 50) - 250, 0, 4)
|
||||
|
||||
wait!
|
||||
if (frameNumber <= 0 and optionsHidden) or (frameNumber >= 5 and not optionsHidden)
|
||||
animating = false
|
||||
|
||||
until not animating
|
||||
|
||||
|
||||
Dev_OptionsButton.MouseButton1Down\connect ->
|
||||
optionsHidden = not optionsHidden
|
||||
startAnimation!
|
||||
|
||||
--Refresh Dev-Console Message Positions
|
||||
repositionList = ->
|
||||
if currentConsole == LOCAL_CONSOLE
|
||||
localOffset = math.min math.max(localOffset, 0), textHolderSize - Dev_Container.Body.TextBox.AbsoluteSize.Y
|
||||
Dev_TextHolder.Size = UDim2.new 1, 0, 0, textHolderSize
|
||||
elseif currentConsole == SERVER_CONSOLE
|
||||
serverOffset = math.min math.max(serverOffset, 0), textHolderSize - Dev_Container.Body.TextBox.AbsoluteSize.Y
|
||||
Dev_TextHolder.Size = UDim2.new 1, 0, 0, textHolderSize
|
||||
|
||||
|
||||
ratio = Dev_Container.Body.TextBox.AbsoluteSize.Y / Dev_TextHolder.AbsoluteSize.Y
|
||||
|
||||
if ratio >= 1
|
||||
Dev_Container.Body.ScrollBar.Visible = false
|
||||
Dev_Container.Body.TextBox.Size = UDim2.new 1, -4, 1, -28
|
||||
|
||||
if currentConsole == LOCAL_CONSOLE or currentConsole == SERVER_CONSOLE
|
||||
Dev_TextHolder.Position = UDim2.new 0, 0, 1, 0 - textHolderSize
|
||||
|
||||
else
|
||||
Dev_Container.Body.ScrollBar.Visible = true
|
||||
Dev_Container.Body.TextBox.Size = UDim2.new 1, -25, 1, -28
|
||||
|
||||
backRatio = 1 - ratio
|
||||
local offsetRatio
|
||||
|
||||
if currentConsole == LOCAL_CONSOLE
|
||||
offsetRatio = localOffset / Dev_TextHolder.AbsoluteSize.Y
|
||||
elseif currentConsole == SERVER_CONSOLE
|
||||
offsetRatio = serverOffset / Dev_TextHolder.AbsoluteSize.Y
|
||||
|
||||
|
||||
topRatio = math.max 0, backRatio - offsetRatio
|
||||
|
||||
scrollHandleSize = math.max Dev_ScrollArea.AbsoluteSize.Y * ratio, 21
|
||||
|
||||
scrollRatio = scrollHandleSize / Dev_ScrollArea.AbsoluteSize.Y
|
||||
ratioConversion = (1 - scrollRatio) / (1 - ratio)
|
||||
|
||||
topScrollRatio = topRatio * ratioConversion
|
||||
|
||||
sPos = math.min(
|
||||
Dev_ScrollArea.AbsoluteSize.Y * topScrollRatio,
|
||||
Dev_ScrollArea.AbsoluteSize.Y - scrollHandleSize
|
||||
)
|
||||
|
||||
Dev_ScrollArea.Handle.Size = UDim2.new 1, 0, 0, scrollHandleSize
|
||||
Dev_ScrollArea.Handle.Position = UDim2.new 0, 0, 0, sPos
|
||||
|
||||
Dev_TextHolder.Position = UDim2.new 0, 0, 1, 0 - textHolderSize + if currentConsole == LOCAL_CONSOLE
|
||||
localOffset
|
||||
elseif currentConsole == SERVER_CONSOLE
|
||||
serverOffset
|
||||
|
||||
|
||||
--Scroll Position
|
||||
|
||||
changeOffset = (value) ->
|
||||
if currentConsole == LOCAL_CONSOLE
|
||||
localOffset += value
|
||||
elseif currentConsole == SERVER_CONSOLE
|
||||
serverOffset += value
|
||||
|
||||
repositionList!
|
||||
|
||||
|
||||
--Refresh Dev-Console Text
|
||||
refreshTextHolderForReal = ->
|
||||
childMessages = Dev_TextHolder\GetChildren!
|
||||
|
||||
local messageList
|
||||
|
||||
messageList = if currentConsole == LOCAL_CONSOLE
|
||||
localMessageList
|
||||
elseif currentConsole == SERVER_CONSOLE
|
||||
serverMessageList
|
||||
|
||||
posOffset = 0
|
||||
|
||||
for i = 1, #childMessages
|
||||
childMessages[i].Visible = false
|
||||
|
||||
for i = 1, #messageList
|
||||
local message
|
||||
|
||||
movePosition = false
|
||||
|
||||
if i > #childMessages
|
||||
message = Create"TextLabel"
|
||||
Name: "Message"
|
||||
Parent: Dev_TextHolder
|
||||
BackgroundTransparency: 1
|
||||
TextXAlignment: "Left"
|
||||
Size: UDim2.new 1, 0, 0, 14
|
||||
FontSize: "Size10"
|
||||
ZIndex: 1
|
||||
movePosition = true
|
||||
else
|
||||
message = childMessages[i]
|
||||
|
||||
|
||||
if (outputToggleOn or messageList[i].Type ~= Enum.MessageType.MessageOutput) and
|
||||
(infoToggleOn or messageList[i].Type ~= Enum.MessageType.MessageInfo) and
|
||||
(warningToggleOn or messageList[i].Type ~= Enum.MessageType.MessageWarning) and
|
||||
(errorToggleOn or messageList[i].Type ~= Enum.MessageType.MessageError)
|
||||
|
||||
with message
|
||||
.TextWrapped = wordWrapToggleOn
|
||||
.Size = UDim2.new 0.98, 0, 0, 2000
|
||||
.Parent = Dev_Container
|
||||
.Text = "#{messageList[i].Time} -- #{messageList[i].Message}"
|
||||
.Size = UDim2.new 0.98, 0, 0, .TextBounds.Y
|
||||
.Position = UDim2.new 0, 5, 0, posOffset
|
||||
.Parent = Dev_TextHolder
|
||||
posOffset += .TextBounds.Y
|
||||
|
||||
if movePosition
|
||||
if (currentConsole == LOCAL_CONSOLE and localOffset > 0) or
|
||||
(currentConsole == SERVER_CONSOLE and serverOffset > 0)
|
||||
|
||||
changeOffset message.TextBounds.Y
|
||||
|
||||
message.Visible = true
|
||||
|
||||
message.TextColor3 = Color3.new if messageList[i].Type == Enum.MessageType.MessageError
|
||||
1, 0, 0
|
||||
elseif messageList[i].Type == Enum.MessageType.MessageInfo
|
||||
0.4, 0.5, 1
|
||||
elseif messageList[i].Type == Enum.MessageType.MessageWarning
|
||||
1, 0.6, 0.4
|
||||
else
|
||||
1, 1, 1
|
||||
|
||||
textHolderSize = posOffset
|
||||
|
||||
|
||||
-- Refreshing the textholder every 0.1 (if needed) is good enough, surely fast enough
|
||||
-- We don't want it to update 50x in a tick because there are 50 messages in that tick
|
||||
-- (Whenever for one reason or another a lot of output comes in, it can lag
|
||||
-- This will make it behave better in a situation of a lot of output comming in)
|
||||
refreshQueued = false
|
||||
refreshTextHolder = ->
|
||||
return if refreshQueued
|
||||
|
||||
Delay 0.1, ->
|
||||
refreshQueued = false
|
||||
refreshTextHolderForReal!
|
||||
|
||||
refreshQueued = true
|
||||
|
||||
|
||||
--Handle Dev-Console Scrollbar
|
||||
|
||||
inside = 0
|
||||
holdingUpButton = ->
|
||||
return if scrollUpIsDown
|
||||
|
||||
scrollUpIsDown = true
|
||||
wait 0.6
|
||||
inside += 1
|
||||
while scrollUpIsDown and inside < 2
|
||||
wait!
|
||||
changeOffset 12
|
||||
|
||||
inside -= 1
|
||||
|
||||
|
||||
holdingDownButton = ->
|
||||
return if scrollDownIsDown
|
||||
|
||||
scrollDownIsDown = true
|
||||
wait 0.6
|
||||
inside += 1
|
||||
while scrollDownIsDown and inside < 2
|
||||
wait!
|
||||
changeOffset -12
|
||||
|
||||
inside -= 1
|
||||
|
||||
|
||||
Dev_Container.Body.ScrollBar.Up.MouseButton1Click\connect ->
|
||||
changeOffset 10
|
||||
|
||||
Dev_Container.Body.ScrollBar.Up.MouseButton1Down\connect ->
|
||||
changeOffset 10
|
||||
holdingUpButton!
|
||||
|
||||
Dev_Container.Body.ScrollBar.Up.MouseButton1Up\connect clean
|
||||
|
||||
Dev_Container.Body.ScrollBar.Down.MouseButton1Down\connect ->
|
||||
changeOffset -10
|
||||
holdingDownButton!
|
||||
|
||||
Dev_Container.Body.ScrollBar.Down.MouseButton1Up\connect clean
|
||||
|
||||
handleScroll = (x, y) ->
|
||||
return if not previousMousePosScroll
|
||||
|
||||
delta = (Vector2.new x, y - previousMousePosScroll).Y
|
||||
|
||||
backRatio = 1 - (Dev_Container.Body.TextBox.AbsoluteSize.Y / Dev_TextHolder.AbsoluteSize.Y)
|
||||
|
||||
movementSize = Dev_ScrollArea.AbsoluteSize.Y - Dev_ScrollArea.Handle.AbsoluteSize.Y
|
||||
normalDelta = math.max(math.min(delta, movementSize), 0 - movementSize)
|
||||
normalRatio = normalDelta / movementSize
|
||||
|
||||
textMovementSize = (backRatio * Dev_TextHolder.AbsoluteSize.Y)
|
||||
offsetChange = textMovementSize * normalRatio
|
||||
|
||||
if currentConsole == LOCAL_CONSOLE
|
||||
localOffset = pOffset - offsetChange
|
||||
elseif currentConsole == SERVER_CONSOLE
|
||||
serverOffset = pOffset - offsetChange
|
||||
|
||||
|
||||
Dev_ScrollArea.Handle.MouseButton1Down\connect (x, y) ->
|
||||
previousMousePosScroll = Vector2.new x, y
|
||||
-- pScrollHandle = Dev_ScrollArea.Handle.AbsolutePosition
|
||||
pOffset = if currentConsole == LOCAL_CONSOLE
|
||||
localOffset
|
||||
elseif currentConsole == SERVER_CONSOLE
|
||||
serverOffset
|
||||
|
||||
|
||||
Dev_ScrollArea.Handle.MouseButton1Up\connect clean
|
||||
|
||||
existsInsideContainer = (container, x, y) ->
|
||||
pos = container.AbsolutePosition
|
||||
size = container.AbsoluteSize
|
||||
if x < pos.X or x > pos.X + size.X or y < pos.y or y > pos.y + size.y
|
||||
return false
|
||||
true
|
||||
|
||||
|
||||
-- Easy, fast, and working nicely
|
||||
numberWithZero = (num) ->
|
||||
if num < 10
|
||||
"0#{num}"
|
||||
else
|
||||
num
|
||||
|
||||
|
||||
str = "%s:%s:%s"
|
||||
|
||||
ConvertTimeStamp = (timeStamp) ->
|
||||
localTime = timeStamp - os.time! + math.floor tick!
|
||||
dayTime = localTime % 86400
|
||||
|
||||
hour = math.floor dayTime / 3600
|
||||
|
||||
dayTime -= hour * 3600
|
||||
minute = math.floor dayTime / 60
|
||||
|
||||
dayTime -= minute * 60
|
||||
|
||||
h = numberWithZero hour
|
||||
m = numberWithZero minute
|
||||
s = numberWithZero dayTime
|
||||
|
||||
str\format h, m, s
|
||||
|
||||
|
||||
--Filter
|
||||
|
||||
Dev_OptionsBar.ErrorToggleButton.MouseButton1Down\connect ->
|
||||
errorToggleOn = not errorToggleOn
|
||||
Dev_OptionsBar.ErrorToggleButton.CheckFrame.Visible = errorToggleOn
|
||||
refreshTextHolder!
|
||||
repositionList!
|
||||
|
||||
|
||||
Dev_OptionsBar.WarningToggleButton.MouseButton1Down\connect ->
|
||||
warningToggleOn = not warningToggleOn
|
||||
Dev_OptionsBar.WarningToggleButton.CheckFrame.Visible = warningToggleOn
|
||||
refreshTextHolder!
|
||||
repositionList!
|
||||
|
||||
|
||||
Dev_OptionsBar.InfoToggleButton.MouseButton1Down\connect ->
|
||||
infoToggleOn = not infoToggleOn
|
||||
Dev_OptionsBar.InfoToggleButton.CheckFrame.Visible = infoToggleOn
|
||||
refreshTextHolder!
|
||||
repositionList!
|
||||
|
||||
|
||||
Dev_OptionsBar.OutputToggleButton.MouseButton1Down\connect ->
|
||||
outputToggleOn = not outputToggleOn
|
||||
Dev_OptionsBar.OutputToggleButton.CheckFrame.Visible = outputToggleOn
|
||||
refreshTextHolder!
|
||||
repositionList!
|
||||
|
||||
|
||||
Dev_OptionsBar.WordWrapToggleButton.MouseButton1Down\connect ->
|
||||
wordWrapToggleOn = not wordWrapToggleOn
|
||||
Dev_OptionsBar.WordWrapToggleButton.CheckFrame.Visible = wordWrapToggleOn
|
||||
refreshTextHolder!
|
||||
repositionList!
|
||||
|
||||
|
||||
---Dev-Console Message Functionality
|
||||
AddLocalMessage = (str, messageType, timeStamp) ->
|
||||
localMessageList[] =
|
||||
Message: str
|
||||
Time: ConvertTimeStamp timeStamp
|
||||
Type: messageType
|
||||
|
||||
while #localMessageList > MAX_LIST_SIZE
|
||||
table.remove localMessageList, 1
|
||||
|
||||
refreshTextHolder!
|
||||
repositionList!
|
||||
|
||||
AddServerMessage = (str, messageType, timeStamp) ->
|
||||
serverMessageList[] =
|
||||
Message: str
|
||||
Time: ConvertTimeStamp timeStamp
|
||||
Type: messageType
|
||||
|
||||
while #serverMessageList > MAX_LIST_SIZE
|
||||
table.remove serverMessageList, 1
|
||||
|
||||
|
||||
refreshTextHolder!
|
||||
repositionList!
|
||||
|
||||
--Handle Dev-Console Local/Server Buttons
|
||||
Dev_Container.Body.LocalConsole.MouseButton1Click\connect ->
|
||||
if currentConsole == SERVER_CONSOLE
|
||||
currentConsole = LOCAL_CONSOLE
|
||||
localConsole = Dev_Container.Body.LocalConsole
|
||||
serverConsole = Dev_Container.Body.ServerConsole
|
||||
|
||||
localConsole.Size = UDim2.new 0, 90, 0, 20
|
||||
serverConsole.Size = UDim2.new 0, 90, 0, 17
|
||||
localConsole.BackgroundTransparency = 0.6
|
||||
serverConsole.BackgroundTransparency = 0.8
|
||||
|
||||
if game\FindFirstChild"Players" and game.Players["LocalPlayer"]
|
||||
mouse = game.Players.LocalPlayer\GetMouse!
|
||||
refreshConsolePosition mouse.X, mouse.Y
|
||||
refreshConsoleSize mouse.X, mouse.Y
|
||||
handleScroll mouse.X, mouse.Y
|
||||
|
||||
|
||||
refreshTextHolder!
|
||||
repositionList!
|
||||
|
||||
|
||||
Dev_Container.Body.LocalConsole.MouseButton1Up\connect clean
|
||||
|
||||
|
||||
serverHistoryRequested = false
|
||||
|
||||
Dev_Container.Body.ServerConsole.MouseButton1Click\connect ->
|
||||
if not serverHistoryRequested
|
||||
serverHistoryRequested = true
|
||||
game\GetService"LogService"\RequestServerOutput!
|
||||
|
||||
|
||||
if currentConsole == LOCAL_CONSOLE
|
||||
currentConsole = SERVER_CONSOLE
|
||||
localConsole = Dev_Container.Body.LocalConsole
|
||||
serverConsole = Dev_Container.Body.ServerConsole
|
||||
|
||||
serverConsole.Size = UDim2.new 0, 90, 0, 20
|
||||
localConsole.Size = UDim2.new 0, 90, 0, 17
|
||||
serverConsole.BackgroundTransparency = 0.6
|
||||
localConsole.BackgroundTransparency = 0.8
|
||||
|
||||
if game\FindFirstChild"Players" and game.Players["LocalPlayer"]
|
||||
mouse = game.Players.LocalPlayer\GetMouse!
|
||||
refreshConsolePosition mouse.X, mouse.Y
|
||||
refreshConsoleSize mouse.X, mouse.Y
|
||||
handleScroll mouse.X, mouse.Y
|
||||
|
||||
refreshTextHolder!
|
||||
repositionList!
|
||||
|
||||
|
||||
---Extra Mouse Handlers for Dev-Console
|
||||
Dev_Container.Body.ServerConsole.MouseButton1Up\connect clean
|
||||
|
||||
|
||||
if game\FindFirstChild"Players" and game.Players["LocalPlayer"]
|
||||
LocalMouse = game.Players.LocalPlayer\GetMouse!
|
||||
LocalMouse.Move\connect ->
|
||||
return if not Dev_Container.Visible
|
||||
|
||||
mouse = game.Players.LocalPlayer\GetMouse!
|
||||
refreshConsolePosition mouse.X, mouse.Y
|
||||
refreshConsoleSize mouse.X, mouse.Y
|
||||
handleScroll mouse.X, mouse.Y
|
||||
|
||||
refreshTextHolder!
|
||||
repositionList!
|
||||
|
||||
LocalMouse.Button1Up\connect clean
|
||||
|
||||
LocalMouse.WheelForward\connect ->
|
||||
return if not Dev_Container.Visible
|
||||
if existsInsideContainer Dev_Container, LocalMouse.X, LocalMouse.Y
|
||||
changeOffset 10
|
||||
|
||||
LocalMouse.WheelBackward\connect ->
|
||||
return if not Dev_Container.Visible
|
||||
if existsInsideContainer Dev_Container, LocalMouse.X, LocalMouse.Y
|
||||
changeOffset -10
|
||||
|
||||
|
||||
Dev_ScrollArea.Handle.MouseButton1Down\connect ->
|
||||
repositionList!
|
||||
|
||||
|
||||
---Populate Dev-Console with dummy messages
|
||||
|
||||
history = game\GetService"LogService"\GetLogHistory!
|
||||
|
||||
for i = 1, #history
|
||||
AddLocalMessage history[i].message, history[i].messageType, history[i].timestamp
|
||||
|
||||
with game\GetService"LogService"
|
||||
.MessageOut\connect (message, messageType) ->
|
||||
AddLocalMessage message, messageType, os.time!
|
||||
.ServerMessageOut\connect AddServerMessage
|
||||
|
||||
currentlyToggling = false
|
||||
ToggleConsole.OnInvoke = ->
|
||||
return if currentlyToggling
|
||||
|
||||
currentlyToggling = true
|
||||
initializeDeveloperConsole!
|
||||
Dev_Container.Visible = not Dev_Container.Visible
|
||||
currentlyToggling = false
|
||||
File diff suppressed because it is too large
Load Diff
2295
yue/46295863.yue
2295
yue/46295863.yue
File diff suppressed because it is too large
Load Diff
365
yue/60595411.lua
365
yue/60595411.lua
|
|
@ -1,4 +1,29 @@
|
|||
local t = { }
|
||||
local New
|
||||
New = function(className, name, props)
|
||||
if not (props ~= nil) then
|
||||
props = name
|
||||
name = nil
|
||||
end
|
||||
local obj = Instance.new(className)
|
||||
if name then
|
||||
obj.Name = name
|
||||
end
|
||||
local parent
|
||||
for k, v in pairs(props) do
|
||||
if type(k) == "string" then
|
||||
if k == "Parent" then
|
||||
parent = v
|
||||
else
|
||||
obj[k] = v
|
||||
end
|
||||
elseif type(k) == "number" and type(v) == "userdata" then
|
||||
v.Parent = obj
|
||||
end
|
||||
end
|
||||
obj.Parent = parent
|
||||
return obj
|
||||
end
|
||||
local assert = assert
|
||||
local Null
|
||||
Null = function()
|
||||
|
|
@ -201,29 +226,29 @@ JsonReader.Read = function(self)
|
|||
end
|
||||
JsonReader.ReadTrue = function(self)
|
||||
self:TestReservedWord({
|
||||
"t",
|
||||
"r",
|
||||
"u",
|
||||
"e"
|
||||
't',
|
||||
'r',
|
||||
'u',
|
||||
'e'
|
||||
})
|
||||
return true
|
||||
end
|
||||
JsonReader.ReadFalse = function(self)
|
||||
self:TestReservedWord({
|
||||
"f",
|
||||
"a",
|
||||
"l",
|
||||
"s",
|
||||
"e"
|
||||
'f',
|
||||
'a',
|
||||
'l',
|
||||
's',
|
||||
'e'
|
||||
})
|
||||
return false
|
||||
end
|
||||
JsonReader.ReadNull = function(self)
|
||||
self:TestReservedWord({
|
||||
"n",
|
||||
"u",
|
||||
"l",
|
||||
"l"
|
||||
'n',
|
||||
'u',
|
||||
'l',
|
||||
'l'
|
||||
})
|
||||
return nil
|
||||
end
|
||||
|
|
@ -389,3 +414,317 @@ Decode = function(s)
|
|||
_with_0:Read()
|
||||
return _with_0
|
||||
end
|
||||
t.DecodeJSON = function(jsonString)
|
||||
pcall(function()
|
||||
return warn('RbxUtility.DecodeJSON is deprecated, please use Game:GetService("HttpService"):JSONDecode() instead.')
|
||||
end)
|
||||
if type(jsonString) == "string" then
|
||||
return Decode(jsonString)
|
||||
end
|
||||
print("RbxUtil.DecodeJSON expects string argument!")
|
||||
return nil
|
||||
end
|
||||
t.EncodeJSON = function(jsonTable)
|
||||
pcall(function()
|
||||
return warn('RbxUtility.EncodeJSON is deprecated, please use Game:GetService("HttpService"):JSONEncode() instead.')
|
||||
end)
|
||||
return Encode(jsonTable)
|
||||
end
|
||||
t.MakeWedge = function(x, y, z, _)
|
||||
return game:GetService("Terrain"):AutoWedgeCell(x, y, z)
|
||||
end
|
||||
t.SelectTerrainRegion = function(regionToSelect, color, selectEmptyCells, selectionParent)
|
||||
local terrain = game.Workspace:FindFirstChild("Terrain")
|
||||
if not terrain then
|
||||
return
|
||||
end
|
||||
assert(regionToSelect)
|
||||
assert(color)
|
||||
if not type(regionToSelect) == "Region3" then
|
||||
error("regionToSelect (first arg), should be of type Region3, but is type", type(regionToSelect))
|
||||
end
|
||||
if not type(color) == "BrickColor" then
|
||||
error("color (second arg), should be of type BrickColor, but is type", type(color))
|
||||
end
|
||||
local GetCell = terrain.GetCell
|
||||
local WorldToCellPreferSolid = terrain.WorldToCellPreferSolid
|
||||
local CellCenterToWorld = terrain.CellCenterToWorld
|
||||
local emptyMaterial = Enum.CellMaterial.Empty
|
||||
local selectionContainer = New("Model", "SelectionContainer", {
|
||||
Archivable = false,
|
||||
Parent = (function()
|
||||
if selectionParent then
|
||||
return selectionParent
|
||||
else
|
||||
return game.Workspace
|
||||
end
|
||||
end)()
|
||||
})
|
||||
local updateSelection
|
||||
local currentKeepAliveTag
|
||||
local aliveCounter = 0
|
||||
local lastRegion
|
||||
local adornments = { }
|
||||
local reusableAdorns = { }
|
||||
local selectionPart = New("Part", "SelectionPart", {
|
||||
Transparency = 1,
|
||||
Anchored = true,
|
||||
Locked = true,
|
||||
CanCollide = false,
|
||||
Size = Vector3.new(4.2, 4.2, 4.2)
|
||||
})
|
||||
local selectionBox = Instance.new("SelectionBox")
|
||||
local createAdornment
|
||||
createAdornment = function(theColor)
|
||||
local selectionPartClone
|
||||
local selectionBoxClone
|
||||
if #reusableAdorns > 0 then
|
||||
selectionPartClone = reusableAdorns[1]["part"]
|
||||
selectionBoxClone = reusableAdorns[1]["box"]
|
||||
table.remove(reusableAdorns, 1)
|
||||
selectionBoxClone.Visible = true
|
||||
else
|
||||
selectionPartClone = selectionPart:Clone()
|
||||
selectionPartClone.Archivable = false
|
||||
selectionBoxClone = selectionBox:Clone()
|
||||
selectionBoxClone.Archivable = false
|
||||
selectionBoxClone.Adornee = selectionPartClone
|
||||
selectionBoxClone.Parent = selectionContainer
|
||||
selectionBoxClone.Adornee = selectionPartClone
|
||||
selectionBoxClone.Parent = selectionContainer
|
||||
end
|
||||
if theColor then
|
||||
selectionBoxClone.Color = theColor
|
||||
end
|
||||
return selectionPartClone, selectionBoxClone
|
||||
end
|
||||
local cleanUpAdornments
|
||||
cleanUpAdornments = function()
|
||||
for cellPos, adornTable in pairs(adornments) do
|
||||
if adornTable.KeepAlive ~= currentKeepAliveTag then
|
||||
adornTable.SelectionBox.Visible = false
|
||||
table.insert(reusableAdorns, {
|
||||
part = adornTable.SelectionPart,
|
||||
box = adornTable.SelectionBox
|
||||
})
|
||||
adornments[cellPos] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
local incrementAliveCounter
|
||||
incrementAliveCounter = function()
|
||||
aliveCounter = aliveCounter + 1
|
||||
if aliveCounter > 1000000 then
|
||||
aliveCounter = 0
|
||||
end
|
||||
return aliveCounter
|
||||
end
|
||||
local adornFullCellsInRegion
|
||||
adornFullCellsInRegion = function(region, color)
|
||||
local regionBegin = region.CFrame.p - region.Size / 2 + Vector3.new(2, 2, 2)
|
||||
local regionEnd = region.CFrame.p + region.Size / 2 - Vector3.new(2, 2, 2)
|
||||
local cellPosBegin = WorldToCellPreferSolid(terrain, regionBegin)
|
||||
local cellPosEnd = WorldToCellPreferSolid(terrain, regionEnd)
|
||||
currentKeepAliveTag = incrementAliveCounter()
|
||||
for y = cellPosBegin.y, cellPosEnd.y do
|
||||
for z = cellPosBegin.z, cellPosEnd.z do
|
||||
for x = cellPosBegin.x, cellPosEnd.x do
|
||||
local cellMaterial = GetCell(terrain, x, y, z)
|
||||
if cellMaterial ~= emptyMaterial then
|
||||
local cframePos = CellCenterToWorld(terrain, x, y, z)
|
||||
local cellPos = Vector3int16.new(x, y, z)
|
||||
local updated = false
|
||||
for cellPosAdorn, adornTable in pairs(adornments) do
|
||||
if cellPosAdorn == cellPos then
|
||||
adornTable.KeepAlive = currentKeepAliveTag
|
||||
if color then
|
||||
adornTable.SelectionBox.Color = color
|
||||
end
|
||||
updated = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not updated then
|
||||
local selectionPart, selectionBox
|
||||
selectionPart, selectionBox = createAdornment(color)
|
||||
selectionPart.Size = Vector3.new(4, 4, 4)
|
||||
selectionPart.CFrame = CFrame.new(cframePos)
|
||||
local adornTable = {
|
||||
SelectionPart = selectionPart,
|
||||
SelectionBox = selectionBox,
|
||||
KeepAlive = currentKeepAliveTag
|
||||
}
|
||||
adornments[cellPos] = adornTable
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return cleanUpAdornments()
|
||||
end
|
||||
lastRegion = regionToSelect
|
||||
if selectEmptyCells then
|
||||
local selectionPart, selectionBox
|
||||
selectionPart, selectionBox = createAdornment(color)
|
||||
selectionPart.Size = regionToSelect.Size
|
||||
selectionPart.CFrame = regionToSelect.CFrame
|
||||
adornments.SelectionPart = selectionPart
|
||||
adornments.SelectionBox = selectionBox
|
||||
updateSelection = function(newRegion, color)
|
||||
if newRegion and newRegion ~= lastRegion then
|
||||
lastRegion = newRegion
|
||||
selectionPart.Size = newRegion.Size
|
||||
selectionPart.CFrame = newRegion.CFrame
|
||||
end
|
||||
if color then
|
||||
selectionBox.Color = color
|
||||
end
|
||||
end
|
||||
else
|
||||
adornFullCellsInRegion(regionToSelect, color)
|
||||
updateSelection = function(newRegion, color)
|
||||
if newRegion and newRegion ~= lastRegion then
|
||||
lastRegion = newRegion
|
||||
return adornFullCellsInRegion(newRegion, color)
|
||||
end
|
||||
end
|
||||
end
|
||||
local destroyFunc
|
||||
destroyFunc = function()
|
||||
updateSelection = nil
|
||||
if selectionContainer ~= nil then
|
||||
selectionContainer:Destroy()
|
||||
end
|
||||
adornments = nil
|
||||
end
|
||||
return updateSelection, destroyFunc
|
||||
end
|
||||
t.CreateSignal = function()
|
||||
local this = { }
|
||||
local mBindableEvent = Instance.new("BindableEvent")
|
||||
local mAllCns = { }
|
||||
this.connect = function(self, func)
|
||||
if self ~= this then
|
||||
error("connect must be called with `:`, not `.`", 2)
|
||||
end
|
||||
if type(func) ~= "function" then
|
||||
error("Argument #1 of connect must be a function, got a " .. tostring(type(func)), 2)
|
||||
end
|
||||
local cn = mBindableEvent.Event:connect(func)
|
||||
mAllCns[cn] = true
|
||||
local pubCn = { }
|
||||
pubCn.disconnect = function(self)
|
||||
cn:disconnect()
|
||||
mAllCns[cn] = nil
|
||||
end
|
||||
pubCn.Disconnect = pubCn.disconnect
|
||||
return pubCn
|
||||
end
|
||||
this.disconnect = function(self)
|
||||
if self ~= this then
|
||||
error("disconnect must be called with `:`, not `.`", 2)
|
||||
end
|
||||
for cn, _ in pairs(mAllCns) do
|
||||
cn:disconnect()
|
||||
mAllCns[cn] = nil
|
||||
end
|
||||
end
|
||||
this.wait = function(self)
|
||||
if self ~= this then
|
||||
error("wait must be called with `:`, not `.`", 2)
|
||||
end
|
||||
return mBindableEvent.Event:wait()
|
||||
end
|
||||
this.fire = function(self, ...)
|
||||
if self ~= this then
|
||||
error("fire must be called with `:`, not `.`", 2)
|
||||
end
|
||||
return mBindableEvent:Fire(...)
|
||||
end
|
||||
this.Connect = this.connect
|
||||
this.Disconnect = this.disconnect
|
||||
this.Wait = this.wait
|
||||
this.Fire = this.fire
|
||||
return this
|
||||
end
|
||||
local Create_PrivImpl
|
||||
Create_PrivImpl = function(objectType)
|
||||
if type(objectType) ~= "string" then
|
||||
error("Argument of Create must be a string", 2)
|
||||
end
|
||||
return function(dat)
|
||||
dat = dat or { }
|
||||
local obj = Instance.new(objectType)
|
||||
local parent
|
||||
local ctor
|
||||
for k, v in pairs(dat) do
|
||||
if type(k) == "string" then
|
||||
if k == "Parent" then
|
||||
parent = v
|
||||
else
|
||||
obj[k] = v
|
||||
end
|
||||
elseif type(k) == "number" then
|
||||
if type(v) ~= "userdata" then
|
||||
error("Bad entry in Create body: Numeric keys must be paired with children, got a: " .. tostring(type(v)), 2)
|
||||
end
|
||||
v.Parent = obj
|
||||
elseif type(k) == "table" and k.__eventname then
|
||||
if type(v) ~= "function" then
|
||||
error("Bad entry in Create body: Key `[Create.E'" .. tostring(k.__eventname) .. "']` must have a function value, got: " .. tostring(v), 2)
|
||||
end
|
||||
obj[k.__eventname]:connect(v)
|
||||
elseif k == t.Create then
|
||||
if type(v) ~= "function" then
|
||||
error("Bad entry in Create body: Key `[Create]` should be paired with a constructor function, got: " .. tostring(v), 2)
|
||||
elseif ctor then
|
||||
error("Bad entry in Create body: Only one constructor function is allowed", 2)
|
||||
end
|
||||
ctor = v
|
||||
else
|
||||
error("Bad entry (" .. tostring(k) .. " => " .. tostring(v) .. ") in Create body", 2)
|
||||
end
|
||||
end
|
||||
if ctor ~= nil then
|
||||
ctor(obj)
|
||||
end
|
||||
if parent then
|
||||
obj.Parent = parent
|
||||
end
|
||||
return obj
|
||||
end
|
||||
end
|
||||
t.Create = setmetatable({ }, {
|
||||
["__call"] = function(_, ...)
|
||||
return Create_PrivImpl(...)
|
||||
end
|
||||
})
|
||||
t.Create.E = function(eventName)
|
||||
return {
|
||||
__eventname = eventName
|
||||
}
|
||||
end
|
||||
t.Help = function(funcNameOrFunc)
|
||||
if "DecodeJSON" == funcNameOrFunc or t.DecodeJSON == funcNameOrFunc then
|
||||
return "Function DecodeJSON. " .. "Arguments: (string). " .. "Side effect: returns a table with all parsed JSON values"
|
||||
elseif "EncodeJSON" == funcNameOrFunc or t.EncodeJSON == funcNameOrFunc then
|
||||
return "Function EncodeJSON. " .. "Arguments: (table). " .. "Side effect: returns a string composed of argument table in JSON data format"
|
||||
elseif "MakeWedge" == funcNameOrFunc or t.MakeWedge == funcNameOrFunc then
|
||||
return "Function MakeWedge. " .. "Arguments: (x, y, z, [default material]). " .. "Description: Makes a wedge at location x, y, z. Sets cell x, y, z to default material if " .. "parameter is provided, if not sets cell x, y, z to be whatever material it previously was. " .. "Returns true if made a wedge, false if the cell remains a block "
|
||||
elseif "SelectTerrainRegion" == funcNameOrFunc or t.SelectTerrainRegion == funcNameOrFunc then
|
||||
return "Function SelectTerrainRegion. " .. "Arguments: (regionToSelect, color, selectEmptyCells, selectionParent). " .. "Description: Selects all terrain via a series of selection boxes within the regionToSelect " .. "(this should be a region3 value). The selection box color is detemined by the color argument " .. "(should be a brickcolor value). SelectionParent is the parent that the selection model gets placed to (optional)." .. "SelectEmptyCells is bool, when true will select all cells in the " .. "region, otherwise we only select non-empty cells. Returns a function that can update the selection," .. "arguments to said function are a new region3 to select, and the adornment color (color arg is optional). " .. "Also returns a second function that takes no arguments and destroys the selection"
|
||||
elseif "CreateSignal" == funcNameOrFunc or t.CreateSignal == funcNameOrFunc then
|
||||
return "Function CreateSignal. " .. "Arguments: None. " .. "Returns: The newly created Signal object. This object is identical to the RBXScriptSignal class " .. "used for events in Objects, but is a Lua-side object so it can be used to create custom events in" .. "Lua code. " .. "Methods of the Signal object: :connect, :wait, :fire, :disconnect. " .. "For more info you can pass the method name to the Help function, or view the wiki page " .. "for this library. EG: Help('Signal:connect')."
|
||||
elseif "Signal:connect" == funcNameOrFunc then
|
||||
return "Method Signal:connect. " .. "Arguments: (function handler). " .. "Return: A connection object which can be used to disconnect the connection to this handler. " .. "Description: Connectes a handler function to this Signal, so that when |fire| is called the " .. "handler function will be called with the arguments passed to |fire|."
|
||||
elseif "Signal:wait" == funcNameOrFunc then
|
||||
return "Method Signal:wait. " .. "Arguments: None. " .. "Returns: The arguments passed to the next call to |fire|. " .. "Description: This call does not return until the next call to |fire| is made, at which point it " .. "will return the values which were passed as arguments to that |fire| call."
|
||||
elseif "Signal:fire" == funcNameOrFunc then
|
||||
return "Method Signal:fire. " .. "Arguments: Any number of arguments of any type. " .. "Returns: None. " .. "Description: This call will invoke any connected handler functions, and notify any waiting code " .. "attached to this Signal to continue, with the arguments passed to this function. Note: The calls " .. "to handlers are made asynchronously, so this call will return immediately regardless of how long " .. "it takes the connected handler functions to complete."
|
||||
elseif "Signal:disconnect" == funcNameOrFunc then
|
||||
return "Method Signal:disconnect. " .. "Arguments: None. " .. "Returns: None. " .. "Description: This call disconnects all handlers attacched to this function, note however, it " .. "does NOT make waiting code continue, as is the behavior of normal Roblox events. This method " .. "can also be called on the connection object which is returned from Signal:connect to only " .. "disconnect a single handler, as opposed to this method, which will disconnect all handlers."
|
||||
elseif "Create" == funcNameOrFunc then
|
||||
return "Function Create. " .. "Arguments: A table containing information about how to construct a collection of objects. " .. "Returns: The constructed objects. " .. "Descrition: Create is a very powerfull function, whose description is too long to fit here, and " .. "is best described via example, please see the wiki page for a description of how to use it."
|
||||
end
|
||||
end
|
||||
return t
|
||||
|
|
|
|||
607
yue/60595411.yue
607
yue/60595411.yue
|
|
@ -1,5 +1,29 @@
|
|||
t = {}
|
||||
|
||||
-- Heliodex's basic New function (basically a simplified version of melt)
|
||||
New = (className, name, props) ->
|
||||
if not props? -- no name was provided
|
||||
props = name
|
||||
name = nil
|
||||
|
||||
obj = Instance.new className
|
||||
obj.Name = name if name
|
||||
local parent
|
||||
|
||||
for k, v in pairs props
|
||||
if type(k) == "string"
|
||||
if k == "Parent"
|
||||
parent = v
|
||||
else
|
||||
obj[k] = v
|
||||
|
||||
elseif type(k) == "number" and type(v) == "userdata"
|
||||
v.Parent = obj
|
||||
|
||||
obj.Parent = parent
|
||||
obj
|
||||
-- if a bit redundant due to the Create function at the bottom
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
|
|
@ -15,9 +39,8 @@ t = {}
|
|||
assert = assert
|
||||
Null = -> Null
|
||||
|
||||
StringBuilder = {
|
||||
StringBuilder =
|
||||
buffer: {}
|
||||
}
|
||||
|
||||
StringBuilder.New ==>
|
||||
o = <>: @
|
||||
|
|
@ -105,8 +128,7 @@ JsonWriter.IsArray = (t) =>
|
|||
else
|
||||
count = math.max count, k
|
||||
|
||||
|
||||
return true, "[", "]", count
|
||||
true, "[", "]", count
|
||||
|
||||
|
||||
JsonWriter.WriteTable = (t) =>
|
||||
|
|
@ -213,15 +235,15 @@ JsonReader.Read ==>
|
|||
nil
|
||||
|
||||
JsonReader.ReadTrue ==>
|
||||
@\TestReservedWord { "t", "r", "u", "e" }
|
||||
@\TestReservedWord { 't', 'r', 'u', 'e' }
|
||||
true
|
||||
|
||||
JsonReader.ReadFalse ==>
|
||||
@\TestReservedWord { "f", "a", "l", "s", "e" }
|
||||
@\TestReservedWord { 'f', 'a', 'l', 's', 'e' }
|
||||
false
|
||||
|
||||
JsonReader.ReadNull ==>
|
||||
@\TestReservedWord { "n", "u", "l", "l" }
|
||||
@\TestReservedWord { 'n', 'u', 'l', 'l' }
|
||||
nil
|
||||
|
||||
JsonReader.TestReservedWord = (t) =>
|
||||
|
|
@ -244,7 +266,6 @@ JsonReader.ReadNumber ==>
|
|||
return result
|
||||
|
||||
|
||||
|
||||
JsonReader.ReadString ==>
|
||||
result = ""
|
||||
assert @\Next! == '"'
|
||||
|
|
@ -284,7 +305,6 @@ JsonReader.ReadBlockComment ==>
|
|||
if not done and ch == "/" and @\Peek! == "*"
|
||||
error string.format "Invalid comment: %s, '/*' illegal.", @\All!
|
||||
|
||||
|
||||
@\Next!
|
||||
|
||||
|
||||
|
|
@ -313,7 +333,6 @@ JsonReader.ReadArray ==>
|
|||
if ch ~= ","
|
||||
error string.format "Invalid array: '%s' due to: '%s'", @\All!, ch
|
||||
|
||||
|
||||
assert "]" == @\Next!
|
||||
result
|
||||
|
||||
|
|
@ -380,4 +399,570 @@ Decode = (s) ->
|
|||
|
||||
-------------------- End JSON Parser ------------------------
|
||||
|
||||
-- TODO
|
||||
t.DecodeJSON = (jsonString) ->
|
||||
try
|
||||
warn 'RbxUtility.DecodeJSON is deprecated, please use Game:GetService("HttpService"):JSONDecode() instead.'
|
||||
|
||||
if type(jsonString) == "string"
|
||||
return Decode jsonString
|
||||
|
||||
print "RbxUtil.DecodeJSON expects string argument!"
|
||||
nil
|
||||
|
||||
t.EncodeJSON = (jsonTable) ->
|
||||
try
|
||||
warn 'RbxUtility.EncodeJSON is deprecated, please use Game:GetService("HttpService"):JSONEncode() instead.'
|
||||
|
||||
Encode jsonTable
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
--------------------------------------------Terrain Utilities Begin-----------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
--makes a wedge at location x, y, z
|
||||
--sets cell x, y, z to default material if parameter is provided, if not sets cell x, y, z to be whatever material it previously w
|
||||
--returns true if made a wedge, false if the cell remains a block
|
||||
t.MakeWedge = (x, y, z, _) -> game\GetService"Terrain"\AutoWedgeCell x, y, z
|
||||
|
||||
|
||||
t.SelectTerrainRegion = (regionToSelect, color, selectEmptyCells, selectionParent) ->
|
||||
terrain = game.Workspace\FindFirstChild "Terrain"
|
||||
return if not terrain
|
||||
|
||||
assert regionToSelect
|
||||
assert color
|
||||
|
||||
if not type(regionToSelect) == "Region3"
|
||||
error "regionToSelect (first arg), should be of type Region3, but is type", type regionToSelect
|
||||
|
||||
if not type(color) == "BrickColor"
|
||||
error "color (second arg), should be of type BrickColor, but is type", type color
|
||||
|
||||
|
||||
-- frequently used terrain calls (speeds up call, no lookup necessary)
|
||||
GetCell = terrain.GetCell
|
||||
WorldToCellPreferSolid = terrain.WorldToCellPreferSolid
|
||||
CellCenterToWorld = terrain.CellCenterToWorld
|
||||
emptyMaterial = Enum.CellMaterial.Empty
|
||||
|
||||
-- container for all adornments, passed back to user
|
||||
selectionContainer = New "Model", "SelectionContainer"
|
||||
Archivable: false
|
||||
Parent: if selectionParent
|
||||
selectionParent
|
||||
else
|
||||
game.Workspace
|
||||
|
||||
local updateSelection -- function we return to allow user to update selection
|
||||
local currentKeepAliveTag -- a tag that determines whether adorns should be destroyed
|
||||
aliveCounter = 0 -- helper for currentKeepAliveTag
|
||||
local lastRegion -- used to stop updates that do nothing
|
||||
adornments = {} -- contains all adornments
|
||||
reusableAdorns = {}
|
||||
|
||||
selectionPart = New "Part", "SelectionPart"
|
||||
Transparency: 1
|
||||
Anchored: true
|
||||
Locked: true
|
||||
CanCollide: false
|
||||
Size: Vector3.new 4.2, 4.2, 4.2
|
||||
|
||||
selectionBox = Instance.new "SelectionBox"
|
||||
|
||||
-- srs translation from region3 to region3int16
|
||||
-- Region3ToRegion3int16 = (region3) ->
|
||||
-- theLowVec = region3.CFrame.p - region3.Size / 2 + Vector3.new 2, 2, 2
|
||||
-- lowCell = WorldToCellPreferSolid terrain, theLowVec
|
||||
|
||||
-- theHighVec = region3.CFrame.p + region3.Size / 2 - Vector3.new 2, 2, 2
|
||||
-- highCell = WorldToCellPreferSolid terrain, theHighVec
|
||||
|
||||
-- highIntVec = Vector3int16.new highCell.x, highCell.y, highCell.z
|
||||
-- lowIntVec = Vector3int16.new lowCell.x, lowCell.y, lowCell.z
|
||||
|
||||
-- Region3int16.new lowIntVec, highIntVec
|
||||
|
||||
-- helper function that creates the basis for a selection box
|
||||
createAdornment = (theColor) ->
|
||||
local selectionPartClone
|
||||
local selectionBoxClone
|
||||
|
||||
if #reusableAdorns > 0
|
||||
selectionPartClone = reusableAdorns[1]["part"]
|
||||
selectionBoxClone = reusableAdorns[1]["box"]
|
||||
table.remove reusableAdorns, 1
|
||||
|
||||
selectionBoxClone.Visible = true
|
||||
else
|
||||
selectionPartClone = selectionPart\Clone!
|
||||
selectionPartClone.Archivable = false
|
||||
|
||||
selectionBoxClone = selectionBox\Clone!
|
||||
|
||||
with selectionBoxClone
|
||||
.Archivable = false
|
||||
.Adornee = selectionPartClone
|
||||
.Parent = selectionContainer
|
||||
.Adornee = selectionPartClone
|
||||
.Parent = selectionContainer
|
||||
|
||||
|
||||
if theColor
|
||||
selectionBoxClone.Color = theColor
|
||||
|
||||
selectionPartClone, selectionBoxClone
|
||||
|
||||
-- iterates through all current adornments and deletes any that don't have latest tag
|
||||
cleanUpAdornments = ->
|
||||
for cellPos, adornTable in pairs adornments
|
||||
if adornTable.KeepAlive ~= currentKeepAliveTag -- old news, we should get rid of this
|
||||
adornTable.SelectionBox.Visible = false
|
||||
table.insert reusableAdorns, part: adornTable.SelectionPart, box: adornTable.SelectionBox
|
||||
adornments[cellPos] = nil
|
||||
|
||||
|
||||
-- helper function to update tag
|
||||
incrementAliveCounter = ->
|
||||
aliveCounter += 1
|
||||
if aliveCounter > 1000000
|
||||
aliveCounter = 0
|
||||
|
||||
aliveCounter
|
||||
|
||||
-- finds full cells in region and adorns each cell with a box, with the argument color
|
||||
adornFullCellsInRegion = (region, color) ->
|
||||
regionBegin = region.CFrame.p - region.Size / 2 + Vector3.new 2, 2, 2
|
||||
regionEnd = region.CFrame.p + region.Size / 2 - Vector3.new 2, 2, 2
|
||||
|
||||
cellPosBegin = WorldToCellPreferSolid terrain, regionBegin
|
||||
cellPosEnd = WorldToCellPreferSolid terrain, regionEnd
|
||||
|
||||
currentKeepAliveTag = incrementAliveCounter!
|
||||
for y = cellPosBegin.y, cellPosEnd.y
|
||||
for z = cellPosBegin.z, cellPosEnd.z
|
||||
for x = cellPosBegin.x, cellPosEnd.x
|
||||
cellMaterial = GetCell terrain, x, y, z
|
||||
|
||||
if cellMaterial ~= emptyMaterial
|
||||
cframePos = CellCenterToWorld terrain, x, y, z
|
||||
cellPos = Vector3int16.new x, y, z
|
||||
|
||||
updated = false
|
||||
for cellPosAdorn, adornTable in pairs adornments
|
||||
if cellPosAdorn == cellPos
|
||||
adornTable.KeepAlive = currentKeepAliveTag
|
||||
if color
|
||||
adornTable.SelectionBox.Color = color
|
||||
|
||||
updated = true
|
||||
break
|
||||
|
||||
|
||||
if not updated
|
||||
local selectionPart, selectionBox = createAdornment color
|
||||
selectionPart.Size = Vector3.new 4, 4, 4
|
||||
selectionPart.CFrame = CFrame.new cframePos
|
||||
adornTable =
|
||||
SelectionPart: selectionPart
|
||||
SelectionBox: selectionBox
|
||||
KeepAlive: currentKeepAliveTag
|
||||
|
||||
adornments[cellPos] = adornTable
|
||||
|
||||
cleanUpAdornments!
|
||||
|
||||
|
||||
------------------------------------- setup code ------------------------------
|
||||
lastRegion = regionToSelect
|
||||
|
||||
if selectEmptyCells -- use one big selection to represent the area selected
|
||||
local selectionPart, selectionBox = createAdornment color
|
||||
|
||||
selectionPart.Size = regionToSelect.Size
|
||||
selectionPart.CFrame = regionToSelect.CFrame
|
||||
|
||||
adornments.SelectionPart = selectionPart
|
||||
adornments.SelectionBox = selectionBox
|
||||
|
||||
updateSelection = (newRegion, color) ->
|
||||
if newRegion and newRegion ~= lastRegion
|
||||
lastRegion = newRegion
|
||||
selectionPart.Size = newRegion.Size
|
||||
selectionPart.CFrame = newRegion.CFrame
|
||||
|
||||
if color
|
||||
selectionBox.Color = color
|
||||
|
||||
|
||||
else -- use individual cell adorns to represent the area selected
|
||||
adornFullCellsInRegion regionToSelect, color
|
||||
updateSelection = (newRegion, color) ->
|
||||
if newRegion and newRegion ~= lastRegion
|
||||
lastRegion = newRegion
|
||||
adornFullCellsInRegion newRegion, color
|
||||
|
||||
|
||||
destroyFunc = ->
|
||||
updateSelection = nil
|
||||
selectionContainer?\Destroy!
|
||||
|
||||
adornments = nil
|
||||
|
||||
updateSelection, destroyFunc
|
||||
|
||||
|
||||
-----------------------------Terrain Utilities End-----------------------------
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------Signal class begin------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
--[[
|
||||
A 'Signal' object identical to the internal RBXScriptSignal object in it's public API and semantics. This function
|
||||
can be used to create "custom events" for user-made code.
|
||||
API:
|
||||
Method \connect function handler
|
||||
Arguments: The function to connect to.
|
||||
Returns: A new connection object which can be used to disconnect the connection
|
||||
Description: Connects this signal to the function specified by |handler|. That is, when |fire ...| is called for
|
||||
the signal the |handler| will be called with the arguments given to |fire ...|. Note, the functions
|
||||
connected to a signal are called in NO PARTICULAR ORDER, so connecting one function after another does
|
||||
NOT mean that the first will be called before the second as a result of a call to |fire|.
|
||||
|
||||
Method \disconnect!
|
||||
Arguments: None
|
||||
Returns: None
|
||||
Description: Disconnects all of the functions connected to this signal.
|
||||
|
||||
Method \fire ...
|
||||
Arguments: Any arguments are accepted
|
||||
Returns: None
|
||||
Description: Calls all of the currently connected functions with the given arguments.
|
||||
|
||||
Method \wait!
|
||||
Arguments: None
|
||||
Returns: The arguments given to fire
|
||||
Description: This call blocks until
|
||||
]]
|
||||
|
||||
t.CreateSignal = ->
|
||||
this = {}
|
||||
|
||||
mBindableEvent = Instance.new "BindableEvent"
|
||||
mAllCns = {} --all connection objects returned by mBindableEvent::connect
|
||||
|
||||
--main functions
|
||||
this.connect = (func) =>
|
||||
if self ~= this
|
||||
error "connect must be called with `:`, not `.`", 2
|
||||
|
||||
if type(func) ~= "function"
|
||||
error "Argument #1 of connect must be a function, got a #{type func}" , 2
|
||||
|
||||
cn = mBindableEvent.Event\connect func
|
||||
mAllCns[cn] = true
|
||||
pubCn = {}
|
||||
pubCn.disconnect ==>
|
||||
cn\disconnect!
|
||||
mAllCns[cn] = nil
|
||||
|
||||
pubCn.Disconnect = pubCn.disconnect
|
||||
pubCn
|
||||
|
||||
this.disconnect ==>
|
||||
if self ~= this
|
||||
error "disconnect must be called with `:`, not `.`", 2
|
||||
|
||||
for cn, _ in pairs mAllCns
|
||||
cn\disconnect!
|
||||
mAllCns[cn] = nil
|
||||
|
||||
this.wait ==>
|
||||
if self ~= this
|
||||
error "wait must be called with `:`, not `.`", 2
|
||||
|
||||
mBindableEvent.Event\wait!
|
||||
|
||||
|
||||
this.fire = (...) =>
|
||||
if self ~= this
|
||||
error "fire must be called with `:`, not `.`", 2
|
||||
|
||||
mBindableEvent\Fire ...
|
||||
|
||||
this.Connect = this.connect
|
||||
this.Disconnect = this.disconnect
|
||||
this.Wait = this.wait
|
||||
this.Fire = this.fire
|
||||
this
|
||||
|
||||
|
||||
------------------------------------------------- Signal class End ------------------------------------------------------
|
||||
|
||||
-- this 1s my favourite (heliodex)
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
-----------------------------------------------Create Function Begins---------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
--[[
|
||||
A "Create" function for easy creation of Roblox instances. The function accepts a string which is the classname of
|
||||
the object to be created. The function then returns another function which either accepts accepts no arguments, in
|
||||
which case it simply creates an object of the given type, or a table argument that may contain several types of data,
|
||||
in which case it mutates the object in varying ways depending on the nature of the aggregate data. These are the
|
||||
type of data and what operation each will perform:
|
||||
1) A string key mapping to some value:
|
||||
Key-Value pairs in this form will be treated as properties of the object, and will be assigned in NO PARTICULAR
|
||||
ORDER. If the order in which properties is assigned matter, then they must be assigned somewhere else than the
|
||||
|Create| call's body.
|
||||
|
||||
2) An integral key mapping to another Instance:
|
||||
Normal numeric keys mapping to Instances will be treated as children if the object being created, and will be
|
||||
parented to it. This allows nice recursive calls to Create to create a whole hierarchy of objects without a
|
||||
need for temporary variables to store references to those objects.
|
||||
|
||||
3) A key which is a value returned from Create.Event( eventname ), and a value which is a function function
|
||||
The Create.E( string ) function provides a limited way to connect to signals inside of a Create hierarchy
|
||||
for those who really want such a functionality. The name of the event whose name is passed to
|
||||
Create.E( string )
|
||||
|
||||
4) A key which is the Create function itself, and a value which is a function
|
||||
The function will be run with the argument of the object itself after all other initialization of the object is
|
||||
done by create. This provides a way to do arbitrary things involving the object from withing the create
|
||||
hierarchy.
|
||||
Note: This function is called SYNCHRONOUSLY, that means that you should only so initialization in
|
||||
it, not stuff which requires waiting, as the Create call will block until it returns. While waiting in the
|
||||
constructor callback function is possible, it is probably not a good design choice.
|
||||
Note: Since the constructor function is called after all other initialization, a Create block cannot have two
|
||||
constructor functions, as it would not be possible to call both of them last, also, this would be unnecessary.
|
||||
|
||||
|
||||
Some example usages:
|
||||
|
||||
A simple example which uses the Create function to create a model object and assign two of it's properties.
|
||||
local model = Create'Model'{
|
||||
Name = 'A New model',
|
||||
Parent = game.Workspace,
|
||||
}
|
||||
|
||||
|
||||
An example where a larger hierarchy of object is made. After the call the hierarchy will look like this:
|
||||
Model_Container
|
||||
|-ObjectValue
|
||||
| |
|
||||
| `-BoolValueChild
|
||||
`-IntValue
|
||||
|
||||
local model = Create'Model'{
|
||||
Name = 'Model_Container',
|
||||
Create'ObjectValue'{
|
||||
Create'BoolValue'{
|
||||
Name = 'BoolValueChild',
|
||||
},
|
||||
},
|
||||
Create'IntValue'{},
|
||||
}
|
||||
|
||||
|
||||
An example using the event syntax:
|
||||
|
||||
local part = Create'Part'{
|
||||
[Create.E'Touched'] = function(part)
|
||||
print("I was touched by "..part.Name)
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
An example using the general constructor syntax:
|
||||
|
||||
local model = Create'Part'{
|
||||
[Create] = function(this)
|
||||
print("Constructor running!")
|
||||
this.Name = GetGlobalFoosAndBars(this)
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
Note: It is also perfectly legal to save a reference to the function returned by a call Create, this will not cause
|
||||
any unexpected behavior. EG:
|
||||
local partCreatingFunction = Create'Part'
|
||||
local part = partCreatingFunction()
|
||||
]]
|
||||
|
||||
--the Create function need to be created as a functor, not a function, in order to support the Create.E syntax, so it
|
||||
--will be created in several steps rather than as a single function declaration.
|
||||
Create_PrivImpl = (objectType) ->
|
||||
if type(objectType) ~= "string"
|
||||
error "Argument of Create must be a string", 2
|
||||
|
||||
--return the proxy function that gives us the nice Create'string'{data} syntax
|
||||
--The first function call is a function call using Lua's single-string-argument syntax
|
||||
--The second function call is using Lua's single-table-argument syntax
|
||||
--Both can be chained together for the nice effect.
|
||||
(dat) ->
|
||||
--default to nothing, to handle the no argument given case
|
||||
dat or= {}
|
||||
|
||||
--make the object to mutate
|
||||
obj = Instance.new objectType
|
||||
local parent
|
||||
|
||||
--stored constructor function to be called after other initialization
|
||||
local ctor
|
||||
|
||||
for k, v in pairs dat
|
||||
--add property
|
||||
if type(k) == "string"
|
||||
if k == "Parent"
|
||||
-- Parent should always be set last, setting the Parent of a new object
|
||||
-- immediately makes performance worse for all subsequent property updates.
|
||||
parent = v
|
||||
else
|
||||
obj[k] = v
|
||||
|
||||
--add child
|
||||
elseif type(k) == "number"
|
||||
if type(v) ~= "userdata"
|
||||
error "Bad entry in Create body: Numeric keys must be paired with children, got a: #{type v}", 2
|
||||
|
||||
v.Parent = obj
|
||||
|
||||
--event connect
|
||||
elseif type(k) == "table" and k.__eventname
|
||||
if type(v) ~= "function"
|
||||
error "Bad entry in Create body: Key `[Create.E'#{k.__eventname}']` must have a function value, got: #{v}", 2
|
||||
|
||||
obj[k.__eventname]\connect v
|
||||
|
||||
--define constructor function
|
||||
elseif k == t.Create
|
||||
if type(v) ~= "function"
|
||||
error "Bad entry in Create body: Key `[Create]` should be paired with a constructor function, got: #{v}", 2
|
||||
|
||||
elseif ctor
|
||||
--ctor already exists, only one allowed
|
||||
error "Bad entry in Create body: Only one constructor function is allowed", 2
|
||||
|
||||
ctor = v
|
||||
else
|
||||
error "Bad entry (#{k} => #{v}) in Create body", 2
|
||||
|
||||
|
||||
--apply constructor function if it exists
|
||||
ctor? obj
|
||||
|
||||
if parent
|
||||
obj.Parent = parent
|
||||
|
||||
--return the completed object
|
||||
obj
|
||||
|
||||
|
||||
--now, create the functor:
|
||||
t.Create = <"__call">: (_, ...) -> Create_PrivImpl ...
|
||||
|
||||
--and create the "Event.E" syntax stub. Really it's just a stub to construct a table which our Create
|
||||
--function can recognize as special.
|
||||
t.Create.E = (eventName) -> __eventname: eventName
|
||||
|
||||
-------------------------------------------------Create function End----------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------Documentation Begin-----------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
t.Help = (funcNameOrFunc) ->
|
||||
switch funcNameOrFunc
|
||||
--input argument can be a string or a function. Should return a description (of arguments and expected side effects)
|
||||
when "DecodeJSON", t.DecodeJSON
|
||||
"Function DecodeJSON. " ..
|
||||
"Arguments: (string). " ..
|
||||
"Side effect: returns a table with all parsed JSON values"
|
||||
|
||||
when "EncodeJSON", t.EncodeJSON
|
||||
"Function EncodeJSON. " ..
|
||||
"Arguments: (table). " ..
|
||||
"Side effect: returns a string composed of argument table in JSON data format"
|
||||
|
||||
when "MakeWedge", t.MakeWedge
|
||||
"Function MakeWedge. " ..
|
||||
"Arguments: (x, y, z, [default material]). " ..
|
||||
"Description: Makes a wedge at location x, y, z. Sets cell x, y, z to default material if " ..
|
||||
"parameter is provided, if not sets cell x, y, z to be whatever material it previously was. " ..
|
||||
"Returns true if made a wedge, false if the cell remains a block "
|
||||
|
||||
when "SelectTerrainRegion", t.SelectTerrainRegion
|
||||
"Function SelectTerrainRegion. " ..
|
||||
"Arguments: (regionToSelect, color, selectEmptyCells, selectionParent). " ..
|
||||
"Description: Selects all terrain via a series of selection boxes within the regionToSelect " ..
|
||||
"(this should be a region3 value). The selection box color is detemined by the color argument " ..
|
||||
"(should be a brickcolor value). SelectionParent is the parent that the selection model gets placed to (optional)." ..
|
||||
"SelectEmptyCells is bool, when true will select all cells in the " ..
|
||||
"region, otherwise we only select non-empty cells. Returns a function that can update the selection," ..
|
||||
"arguments to said function are a new region3 to select, and the adornment color (color arg is optional). " ..
|
||||
"Also returns a second function that takes no arguments and destroys the selection"
|
||||
|
||||
when "CreateSignal", t.CreateSignal
|
||||
"Function CreateSignal. " ..
|
||||
"Arguments: None. " ..
|
||||
"Returns: The newly created Signal object. This object is identical to the RBXScriptSignal class " ..
|
||||
"used for events in Objects, but is a Lua-side object so it can be used to create custom events in" ..
|
||||
"Lua code. " ..
|
||||
"Methods of the Signal object: :connect, :wait, :fire, :disconnect. " ..
|
||||
"For more info you can pass the method name to the Help function, or view the wiki page " ..
|
||||
"for this library. EG: Help('Signal:connect')."
|
||||
|
||||
when "Signal:connect"
|
||||
"Method Signal:connect. " ..
|
||||
"Arguments: (function handler). " ..
|
||||
"Return: A connection object which can be used to disconnect the connection to this handler. " ..
|
||||
"Description: Connectes a handler function to this Signal, so that when |fire| is called the " ..
|
||||
"handler function will be called with the arguments passed to |fire|."
|
||||
|
||||
when "Signal:wait"
|
||||
"Method Signal:wait. " ..
|
||||
"Arguments: None. " ..
|
||||
"Returns: The arguments passed to the next call to |fire|. " ..
|
||||
"Description: This call does not return until the next call to |fire| is made, at which point it " ..
|
||||
"will return the values which were passed as arguments to that |fire| call."
|
||||
|
||||
when "Signal:fire"
|
||||
"Method Signal:fire. " ..
|
||||
"Arguments: Any number of arguments of any type. " ..
|
||||
"Returns: None. " ..
|
||||
"Description: This call will invoke any connected handler functions, and notify any waiting code " ..
|
||||
"attached to this Signal to continue, with the arguments passed to this function. Note: The calls " ..
|
||||
"to handlers are made asynchronously, so this call will return immediately regardless of how long " ..
|
||||
"it takes the connected handler functions to complete."
|
||||
|
||||
when "Signal:disconnect"
|
||||
"Method Signal:disconnect. " ..
|
||||
"Arguments: None. " ..
|
||||
"Returns: None. " ..
|
||||
"Description: This call disconnects all handlers attacched to this function, note however, it " ..
|
||||
"does NOT make waiting code continue, as is the behavior of normal Roblox events. This method " ..
|
||||
"can also be called on the connection object which is returned from Signal:connect to only " ..
|
||||
"disconnect a single handler, as opposed to this method, which will disconnect all handlers."
|
||||
|
||||
when "Create"
|
||||
"Function Create. " ..
|
||||
"Arguments: A table containing information about how to construct a collection of objects. " ..
|
||||
"Returns: The constructed objects. " ..
|
||||
"Descrition: Create is a very powerfull function, whose description is too long to fit here, and " ..
|
||||
"is best described via example, please see the wiki page for a description of how to use it."
|
||||
|
||||
--------------------------------------------Documentation Ends----------------------------------------------------------
|
||||
|
||||
t
|
||||
|
|
|
|||
Loading…
Reference in New Issue