diff --git a/NovetusLauncher/NovetusCMD/Program.cs b/NovetusLauncher/NovetusCMD/Program.cs index 1c42326..d0786ab 100644 --- a/NovetusLauncher/NovetusCMD/Program.cs +++ b/NovetusLauncher/NovetusCMD/Program.cs @@ -183,6 +183,7 @@ namespace NovetusCMD { bool StartInNo3D = false; bool OverrideINI = false; + bool RequestToOutputInfo = false; string[] lines = File.ReadAllLines(GlobalVars.ConfigDir + "\\info.txt"); //File is in System.IO string version = lines[0]; @@ -199,15 +200,19 @@ namespace NovetusCMD { ConsolePrint("Help: Command Line Arguments", 3); ConsolePrint("---------", 1); - ConsolePrint("-no3d | Launches server in NoGraphics mode", 3); - ConsolePrint("-overrideconfig | Override the launcher settings.", 3); + ConsolePrint("General", 3); + ConsolePrint("-no3d | Launches server in NoGraphics mode", 4); + ConsolePrint("-script | Loads an additional server script.", 4); + ConsolePrint("-outputinfo | Outputs all information about the running server to a text file.", 4); + ConsolePrint("-overrideconfig | Override the launcher settings.", 4); + ConsolePrint("---------", 1); + ConsolePrint("Custom server options", 3); ConsolePrint("-overrideconfig must be added in order for the below commands to function.", 5); ConsolePrint("-upnp | Turns on UPnP.", 4); ConsolePrint("-map | Sets the map.", 4); ConsolePrint("-client | Sets the client.", 4); ConsolePrint("-port | Sets the server port.", 4); ConsolePrint("-maxplayers | Sets the number of players.", 4); - ConsolePrint("-script | Loads an additional server script.", 4); ConsolePrint("---------", 1); } else @@ -260,6 +265,11 @@ namespace NovetusCMD } } + if (CommandLine["outputinfo"] != null) + { + RequestToOutputInfo = true; + } + if (CommandLine["script"] != null) { GlobalVars.AddonScriptPath = CommandLine["script"].Replace(@"\", @"\\"); @@ -286,6 +296,43 @@ namespace NovetusCMD InitUPnP(); StartWebServer(); + + if (RequestToOutputInfo) + { + string IP = SecurityFuncs.GetExternalIPAddress(); + string[] lines1 = { + SecurityFuncs.Base64Encode(IP), + SecurityFuncs.Base64Encode(GlobalVars.RobloxPort.ToString()), + SecurityFuncs.Base64Encode(GlobalVars.SelectedClient) + }; + string URI = "novetus://" + SecurityFuncs.Base64Encode(string.Join("|", lines1)); + string[] lines2 = { + SecurityFuncs.Base64Encode("localhost"), + SecurityFuncs.Base64Encode(GlobalVars.RobloxPort.ToString()), + SecurityFuncs.Base64Encode(GlobalVars.SelectedClient) + }; + string URI2 = "novetus://" + SecurityFuncs.Base64Encode(string.Join("|", lines2)); + + string text = GlobalVars.MultiLine( + "Client: " + GlobalVars.SelectedClient, + "IP: " + IP, + "Port: " + GlobalVars.RobloxPort.ToString(), + "Map: " + GlobalVars.Map, + "Players: " + GlobalVars.PlayerLimit, + "Version: Novetus " + GlobalVars.Version, + "Online URI Link:", + URI, + "Local URI Link:", + URI2, + GlobalVars.IsWebServerOn == true ? "Web Server URL:" : "", + GlobalVars.IsWebServerOn == true ? "http://" + IP + ":" + GlobalVars.WebServer.Port.ToString() : "", + GlobalVars.IsWebServerOn == true ? "Local Web Server URL:" : "", + GlobalVars.IsWebServerOn == true ? GlobalVars.LocalWebServerURI : "" + ); + + File.WriteAllText(GlobalVars.BasePath + "\\" + GlobalVars.ServerInfoFileName, GlobalVars.RemoveEmptyLines(text)); + ConsolePrint("Server Information sent to file " + GlobalVars.BasePath + "\\" + GlobalVars.ServerInfoFileName, 4); + } AppDomain.CurrentDomain.ProcessExit += new EventHandler(ProgramClose); diff --git a/NovetusLauncher/NovetusFuncs/ClientScript.cs b/NovetusLauncher/NovetusFuncs/ClientScript.cs index 860a4ce..f70e9ef 100644 --- a/NovetusLauncher/NovetusFuncs/ClientScript.cs +++ b/NovetusLauncher/NovetusFuncs/ClientScript.cs @@ -103,10 +103,10 @@ public class ClientScript if (File.Exists(GlobalVars.MapsDir + @"\\" + result + @"\\" + source)) { return result + @"\\" + source; } else { - return ""; + return source; } } catch (Exception) when (!Env.Debugging) { - return ""; + return source; } } diff --git a/NovetusLauncher/NovetusFuncs/GlobalVars.cs b/NovetusLauncher/NovetusFuncs/GlobalVars.cs index 2e10ae3..3d54629 100644 --- a/NovetusLauncher/NovetusFuncs/GlobalVars.cs +++ b/NovetusLauncher/NovetusFuncs/GlobalVars.cs @@ -6,10 +6,11 @@ * * To change this template use Tools | Options | Coding | Edit Standard Headers. */ - + using System; using System.IO; using System.Reflection; +using System.Text.RegularExpressions; public static class Env { @@ -215,9 +216,17 @@ public static class GlobalVars public static string WebServer_BodyColors = WebServer_CustomPlayerDir + "bodycolors.rbxm"; //itemmaker public static bool DisabledHelp = false; - - public static string MultiLine(params string[] args) + //cmd + public static string ServerInfoFileName = "serverinfo.txt"; + + + public static string MultiLine(params string[] args) { return string.Join(Environment.NewLine, args); } + + public static string RemoveEmptyLines(string lines) + { + return Regex.Replace(lines, @"^\s*$\n|\r", string.Empty, RegexOptions.Multiline).TrimEnd(); + } } \ No newline at end of file diff --git a/NovetusLauncher/NovetusLauncher/ServerInfo.cs b/NovetusLauncher/NovetusLauncher/ServerInfo.cs index 814dc6c..4e2f4c2 100644 --- a/NovetusLauncher/NovetusLauncher/ServerInfo.cs +++ b/NovetusLauncher/NovetusLauncher/ServerInfo.cs @@ -32,50 +32,37 @@ namespace NovetusLauncher void ServerInfoLoad(object sender, EventArgs e) { - textBox1.AppendText("Client: " + GlobalVars.SelectedClient); - textBox1.AppendText(Environment.NewLine); - string IP = SecurityFuncs.GetExternalIPAddress(); - textBox1.AppendText("IP: " + IP); - textBox1.AppendText(Environment.NewLine); - textBox1.AppendText("Port: " + GlobalVars.RobloxPort.ToString()); - textBox1.AppendText(Environment.NewLine); - textBox1.AppendText("Map: " + GlobalVars.Map); - textBox1.AppendText(Environment.NewLine); - textBox1.AppendText("Players: " + GlobalVars.PlayerLimit); - textBox1.AppendText(Environment.NewLine); - textBox1.AppendText("Version: Novetus " + GlobalVars.Version); - textBox1.AppendText(Environment.NewLine); - string[] lines = { - SecurityFuncs.Base64Encode(IP), - SecurityFuncs.Base64Encode(GlobalVars.RobloxPort.ToString()), - SecurityFuncs.Base64Encode(GlobalVars.SelectedClient) - }; - string URI = "novetus://" + SecurityFuncs.Base64Encode(string.Join("|",lines)); - textBox1.AppendText("Online URI Link:"); - textBox1.AppendText(Environment.NewLine); - textBox1.AppendText(URI); - textBox1.AppendText(Environment.NewLine); - string[] lines2 = { - SecurityFuncs.Base64Encode("localhost"), - SecurityFuncs.Base64Encode(GlobalVars.RobloxPort.ToString()), - SecurityFuncs.Base64Encode(GlobalVars.SelectedClient) - }; - string URI2 = "novetus://" + SecurityFuncs.Base64Encode(string.Join("|",lines2)); - textBox1.AppendText(Environment.NewLine); - textBox1.AppendText("Local URI Link:"); - textBox1.AppendText(Environment.NewLine); - textBox1.AppendText(URI2); - textBox1.AppendText(Environment.NewLine); - if (GlobalVars.IsWebServerOn == true) - { - textBox1.AppendText("Web Server URL:"); - textBox1.AppendText(Environment.NewLine); - textBox1.AppendText("http://" + IP + ":" + GlobalVars.WebServer.Port.ToString()); - textBox1.AppendText(Environment.NewLine); - textBox1.AppendText("Local Web Server URL:"); - textBox1.AppendText(Environment.NewLine); - textBox1.AppendText(GlobalVars.LocalWebServerURI); - } + string IP = SecurityFuncs.GetExternalIPAddress(); + string[] lines1 = { + SecurityFuncs.Base64Encode(IP), + SecurityFuncs.Base64Encode(GlobalVars.RobloxPort.ToString()), + SecurityFuncs.Base64Encode(GlobalVars.SelectedClient) + }; + string URI = "novetus://" + SecurityFuncs.Base64Encode(string.Join("|", lines1)); + string[] lines2 = { + SecurityFuncs.Base64Encode("localhost"), + SecurityFuncs.Base64Encode(GlobalVars.RobloxPort.ToString()), + SecurityFuncs.Base64Encode(GlobalVars.SelectedClient) + }; + string URI2 = "novetus://" + SecurityFuncs.Base64Encode(string.Join("|", lines2)); + string text = GlobalVars.MultiLine( + "Client: " + GlobalVars.SelectedClient, + "IP: " + IP, + "Port: " + GlobalVars.RobloxPort.ToString(), + "Map: " + GlobalVars.Map, + "Players: " + GlobalVars.PlayerLimit, + "Version: Novetus " + GlobalVars.Version, + "Online URI Link:", + URI, + "Local URI Link:", + URI2, + GlobalVars.IsWebServerOn == true ? "Web Server URL:" : "", + GlobalVars.IsWebServerOn == true ? "http://" + IP + ":" + GlobalVars.WebServer.Port.ToString() : "", + GlobalVars.IsWebServerOn == true ? "Local Web Server URL:" : "", + GlobalVars.IsWebServerOn == true ? GlobalVars.LocalWebServerURI : "" + ); + textBox1.AppendText(GlobalVars.RemoveEmptyLines(text)); + } } } diff --git a/clients/2011E/content/fonts/libraries.rbxm b/clients/2011E/content/fonts/libraries.rbxm index 71630fe..30ccf1c 100644 --- a/clients/2011E/content/fonts/libraries.rbxm +++ b/clients/2011E/content/fonts/libraries.rbxm @@ -7,7 +7,6 @@ Sorter print("Special thanks to Bitl, Carrot, iago, winsupermario1234, Khangaroo, drslicendice, coke, TheLivingBee, Raymonf, and a bunch of play - testers for help making 2011 fully stable and work. 8)") -script.Playerlist:clone().Parent = game.StarterGui script.Dialogs:clone().Parent = game.StarterGui script.Health:clone().Parent = game.StarterGui script.ReenableDialogScript:clone().Parent = game.Lighting @@ -1020,6189 +1019,5 @@ onLoad() - - - Playerlist - true - - - - false - - Init - --fixed by Carrot#0559 ---for non corescript use -local t = {} - -local function ScopedConnect(parentInstance, instance, event, signalFunc, syncFunc, removeFunc) - local eventConnection = nil - - --Connection on parentInstance is scoped by parentInstance (when destroyed, it goes away) - local tryConnect = function() - if game:IsAncestorOf(parentInstance) then - --Entering the world, make sure we are connected/synced - if not eventConnection then - eventConnection = instance[event]:connect(signalFunc) - if syncFunc then syncFunc() end - end - else - --Probably leaving the world, so disconnect for now - if eventConnection then - eventConnection:disconnect() - if removeFunc then removeFunc() end - end - end - end - - --Hook it up to ancestryChanged signal - local connection = parentInstance.AncestryChanged:connect(tryConnect) - - --Now connect us if we're already in the world - tryConnect() - - return connection -end - -local function getScreenGuiAncestor(instance) - local localInstance = instance - while localInstance and not localInstance:IsA("ScreenGui") do - localInstance = localInstance.Parent - end - return localInstance -end - -local function CreateButtons(frame, buttons, yPos, ySize) - local buttonNum = 1 - local buttonObjs = {} - for i, obj in ipairs(buttons) do - local button = Instance.new("TextButton") - button.Name = "Button" .. buttonNum - button.Font = Enum.Font.Arial - button.FontSize = Enum.FontSize.Size18 - button.AutoButtonColor = true - button.Modal = true - if obj["Style"] then - button.Style = obj.Style - else - button.Style = Enum.ButtonStyle.RobloxButton - end - if obj["ZIndex"] then - button.ZIndex = obj.ZIndex - end - button.Text = obj.Text - button.TextColor3 = Color3.new(1,1,1) - button.MouseButton1Click:connect(obj.Function) - button.Parent = frame - buttonObjs[buttonNum] = button - - buttonNum = buttonNum + 1 - end - local numButtons = buttonNum-1 - - if numButtons == 1 then - frame.Button1.Position = UDim2.new(0.35, 0, yPos.Scale, yPos.Offset) - frame.Button1.Size = UDim2.new(.4,0,ySize.Scale, ySize.Offset) - elseif numButtons == 2 then - frame.Button1.Position = UDim2.new(0.1, 0, yPos.Scale, yPos.Offset) - frame.Button1.Size = UDim2.new(.8/3,0, ySize.Scale, ySize.Offset) - - frame.Button2.Position = UDim2.new(0.55, 0, yPos.Scale, yPos.Offset) - frame.Button2.Size = UDim2.new(.35,0, ySize.Scale, ySize.Offset) - elseif numButtons >= 3 then - local spacing = .1 / numButtons - local buttonSize = .9 / numButtons - - buttonNum = 1 - while buttonNum <= numButtons do - buttonObjs[buttonNum].Position = UDim2.new(spacing*buttonNum + (buttonNum-1) * buttonSize, 0, yPos.Scale, yPos.Offset) - buttonObjs[buttonNum].Size = UDim2.new(buttonSize, 0, ySize.Scale, ySize.Offset) - buttonNum = buttonNum + 1 - end - end -end - -local function setSliderPos(newAbsPosX,slider,sliderPosition,bar,steps) - - local newStep = steps - 1 --otherwise we really get one more step than we want - local relativePosX = math.min(1, math.max(0, (newAbsPosX - bar.AbsolutePosition.X) / bar.AbsoluteSize.X )) - local wholeNum, remainder = math.modf(relativePosX * newStep) - if remainder > 0.5 then - wholeNum = wholeNum + 1 - end - relativePosX = wholeNum/newStep - - local result = math.ceil(relativePosX * newStep) - if sliderPosition.Value ~= (result + 1) then --only update if we moved a step - sliderPosition.Value = result + 1 - slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset) - end - -end - -local function cancelSlide(areaSoak) - areaSoak.Visible = false - if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end -end - -t.CreateStyledMessageDialog = function(title, message, style, buttons) - local frame = Instance.new("Frame") - frame.Size = UDim2.new(0.5, 0, 0, 165) - frame.Position = UDim2.new(0.25, 0, 0.5, -72.5) - frame.Name = "MessageDialog" - frame.Active = true - frame.Style = Enum.FrameStyle.RobloxRound - - local styleImage = Instance.new("ImageLabel") - styleImage.Name = "StyleImage" - styleImage.BackgroundTransparency = 1 - styleImage.Position = UDim2.new(0,5,0,15) - if style == "error" or style == "Error" then - styleImage.Size = UDim2.new(0, 71, 0, 71) - styleImage.Image = "http://www.roblox.com/asset/?id=42565285" - elseif style == "notify" or style == "Notify" then - styleImage.Size = UDim2.new(0, 71, 0, 71) - styleImage.Image = "http://www.roblox.com/asset/?id=42604978" - elseif style == "confirm" or style == "Confirm" then - styleImage.Size = UDim2.new(0, 74, 0, 76) - styleImage.Image = "http://www.roblox.com/asset/?id=42557901" - else - return t.CreateMessageDialog(title,message,buttons) - end - styleImage.Parent = frame - - local titleLabel = Instance.new("TextLabel") - titleLabel.Name = "Title" - titleLabel.Text = title - titleLabel.TextStrokeTransparency = 0 - titleLabel.BackgroundTransparency = 1 - titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255) - titleLabel.Position = UDim2.new(0, 80, 0, 0) - titleLabel.Size = UDim2.new(1, -80, 0, 40) - titleLabel.Font = Enum.Font.ArialBold - titleLabel.FontSize = Enum.FontSize.Size36 - titleLabel.TextXAlignment = Enum.TextXAlignment.Center - titleLabel.TextYAlignment = Enum.TextYAlignment.Center - titleLabel.Parent = frame - - local messageLabel = Instance.new("TextLabel") - messageLabel.Name = "Message" - messageLabel.Text = message - messageLabel.TextStrokeTransparency = 0 - messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255) - messageLabel.Position = UDim2.new(0.025, 80, 0, 45) - messageLabel.Size = UDim2.new(0.95, -80, 0, 55) - messageLabel.BackgroundTransparency = 1 - messageLabel.Font = Enum.Font.Arial - messageLabel.FontSize = Enum.FontSize.Size18 - messageLabel.TextWrap = true - messageLabel.TextXAlignment = Enum.TextXAlignment.Left - messageLabel.TextYAlignment = Enum.TextYAlignment.Top - messageLabel.Parent = frame - - CreateButtons(frame, buttons, UDim.new(0, 105), UDim.new(0, 40) ) - - return frame -end - -t.CreateMessageDialog = function(title, message, buttons) - local frame = Instance.new("Frame") - frame.Size = UDim2.new(0.5, 0, 0.5, 0) - frame.Position = UDim2.new(0.25, 0, 0.25, 0) - frame.Name = "MessageDialog" - frame.Active = true - frame.Style = Enum.FrameStyle.RobloxRound - - local titleLabel = Instance.new("TextLabel") - titleLabel.Name = "Title" - titleLabel.Text = title - titleLabel.BackgroundTransparency = 1 - titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255) - titleLabel.Position = UDim2.new(0, 0, 0, 0) - titleLabel.Size = UDim2.new(1, 0, 0.15, 0) - titleLabel.Font = Enum.Font.ArialBold - titleLabel.FontSize = Enum.FontSize.Size36 - titleLabel.TextXAlignment = Enum.TextXAlignment.Center - titleLabel.TextYAlignment = Enum.TextYAlignment.Center - titleLabel.Parent = frame - - local messageLabel = Instance.new("TextLabel") - messageLabel.Name = "Message" - messageLabel.Text = message - messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255) - messageLabel.Position = UDim2.new(0.025, 0, 0.175, 0) - messageLabel.Size = UDim2.new(0.95, 0, .55, 0) - messageLabel.BackgroundTransparency = 1 - messageLabel.Font = Enum.Font.Arial - messageLabel.FontSize = Enum.FontSize.Size18 - messageLabel.TextWrap = true - messageLabel.TextXAlignment = Enum.TextXAlignment.Left - messageLabel.TextYAlignment = Enum.TextYAlignment.Top - messageLabel.Parent = frame - - CreateButtons(frame, buttons, UDim.new(0.8,0), UDim.new(0.15, 0)) - - return frame -end - -t.CreateDropDownMenu = function(items, onSelect, forRoblox, whiteSkin, baseZ) - local baseZIndex = 0 - if (type(baseZ) == "number") then - baseZIndex = baseZ - end - local width = UDim.new(0, 100) - local height = UDim.new(0, 32) - - local xPos = 0.055 - local frame = Instance.new("Frame") - local textColor = Color3.new(1,1,1) - if (whiteSkin) then - textColor = Color3.new(0.5, 0.5, 0.5) - end - frame.Name = "DropDownMenu" - frame.BackgroundTransparency = 1 - frame.Size = UDim2.new(width, height) - - local dropDownMenu = Instance.new("TextButton") - dropDownMenu.Name = "DropDownMenuButton" - dropDownMenu.TextWrap = true - dropDownMenu.TextColor3 = textColor - dropDownMenu.Text = "Choose One" - dropDownMenu.Font = Enum.Font.ArialBold - dropDownMenu.FontSize = Enum.FontSize.Size18 - dropDownMenu.TextXAlignment = Enum.TextXAlignment.Left - dropDownMenu.TextYAlignment = Enum.TextYAlignment.Center - dropDownMenu.BackgroundTransparency = 1 - dropDownMenu.AutoButtonColor = true - if (whiteSkin) then - dropDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton - else - dropDownMenu.Style = Enum.ButtonStyle.RobloxButton - end - dropDownMenu.Size = UDim2.new(1,0,1,0) - dropDownMenu.Parent = frame - dropDownMenu.ZIndex = 2 + baseZIndex - - local dropDownIcon = Instance.new("ImageLabel") - dropDownIcon.Name = "Icon" - dropDownIcon.Active = false - if (whiteSkin) then - dropDownIcon.Image = "rbxasset://textures/ui/dropdown_arrow.png" - dropDownIcon.Size = UDim2.new(0,16,0,12) - dropDownIcon.Position = UDim2.new(1,-17,0.5, -6) - else - dropDownIcon.Image = "http://www.roblox.com/asset/?id=45732894" - dropDownIcon.Size = UDim2.new(0,11,0,6) - dropDownIcon.Position = UDim2.new(1,-11,0.5, -2) - end - dropDownIcon.BackgroundTransparency = 1 - dropDownIcon.Parent = dropDownMenu - dropDownIcon.ZIndex = 2 + baseZIndex - - local itemCount = #items - local dropDownItemCount = #items - local useScrollButtons = false - if dropDownItemCount > 6 then - useScrollButtons = true - dropDownItemCount = 6 - end - - local droppedDownMenu = Instance.new("TextButton") - droppedDownMenu.Name = "List" - droppedDownMenu.Text = "" - droppedDownMenu.BackgroundTransparency = 1 - --droppedDownMenu.AutoButtonColor = true - if (whiteSkin) then - droppedDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton - else - droppedDownMenu.Style = Enum.ButtonStyle.RobloxButton - end - droppedDownMenu.Visible = false - droppedDownMenu.Active = true --Blocks clicks - droppedDownMenu.Position = UDim2.new(0,0,0,0) - droppedDownMenu.Size = UDim2.new(1,0, (1 + dropDownItemCount)*.8, 0) - droppedDownMenu.Parent = frame - droppedDownMenu.ZIndex = 2 + baseZIndex - - local choiceButton = Instance.new("TextButton") - choiceButton.Name = "ChoiceButton" - choiceButton.BackgroundTransparency = 1 - choiceButton.BorderSizePixel = 0 - choiceButton.Text = "ReplaceMe" - choiceButton.TextColor3 = textColor - choiceButton.TextXAlignment = Enum.TextXAlignment.Left - choiceButton.TextYAlignment = Enum.TextYAlignment.Center - choiceButton.BackgroundColor3 = Color3.new(1, 1, 1) - choiceButton.Font = Enum.Font.Arial - choiceButton.FontSize = Enum.FontSize.Size18 - if useScrollButtons then - choiceButton.Size = UDim2.new(1,-13, .8/((dropDownItemCount + 1)*.8),0) - else - choiceButton.Size = UDim2.new(1, 0, .8/((dropDownItemCount + 1)*.8),0) - end - choiceButton.TextWrap = true - choiceButton.ZIndex = 2 + baseZIndex - - local areaSoak = Instance.new("TextButton") - areaSoak.Name = "AreaSoak" - areaSoak.Text = "" - areaSoak.BackgroundTransparency = 1 - areaSoak.Active = true - areaSoak.Size = UDim2.new(1,0,1,0) - areaSoak.Visible = false - areaSoak.ZIndex = 3 + baseZIndex - - local dropDownSelected = false - - local scrollUpButton - local scrollDownButton - local scrollMouseCount = 0 - - local setZIndex = function(baseZIndex) - droppedDownMenu.ZIndex = baseZIndex +1 - if scrollUpButton then - scrollUpButton.ZIndex = baseZIndex + 3 - end - if scrollDownButton then - scrollDownButton.ZIndex = baseZIndex + 3 - end - - local children = droppedDownMenu:GetChildren() - if children then - for i, child in ipairs(children) do - if child.Name == "ChoiceButton" then - child.ZIndex = baseZIndex + 2 - elseif child.Name == "ClickCaptureButton" then - child.ZIndex = baseZIndex - end - end - end - end - - local scrollBarPosition = 1 - local updateScroll = function() - if scrollUpButton then - scrollUpButton.Active = scrollBarPosition > 1 - end - if scrollDownButton then - scrollDownButton.Active = scrollBarPosition + dropDownItemCount <= itemCount - end - - local children = droppedDownMenu:GetChildren() - if not children then return end - - local childNum = 1 - for i, obj in ipairs(children) do - if obj.Name == "ChoiceButton" then - if childNum < scrollBarPosition or childNum >= scrollBarPosition + dropDownItemCount then - obj.Visible = false - else - obj.Position = UDim2.new(0,0,((childNum-scrollBarPosition+1)*.8)/((dropDownItemCount+1)*.8),0) - obj.Visible = true - end - obj.TextColor3 = textColor - obj.BackgroundTransparency = 1 - - childNum = childNum + 1 - end - end - end - local toggleVisibility = function() - dropDownSelected = not dropDownSelected - - areaSoak.Visible = not areaSoak.Visible - dropDownMenu.Visible = not dropDownSelected - droppedDownMenu.Visible = dropDownSelected - if dropDownSelected then - setZIndex(4 + baseZIndex) - else - setZIndex(2 + baseZIndex) - end - if useScrollButtons then - updateScroll() - end - end - droppedDownMenu.MouseButton1Click:connect(toggleVisibility) - - local updateSelection = function(text) - local foundItem = false - local children = droppedDownMenu:GetChildren() - local childNum = 1 - if children then - for i, obj in ipairs(children) do - if obj.Name == "ChoiceButton" then - if obj.Text == text then - obj.Font = Enum.Font.ArialBold - foundItem = true - scrollBarPosition = childNum - if (whiteSkin) then - obj.TextColor3 = Color3.new(90/255,142/255,233/255) - end - else - obj.Font = Enum.Font.Arial - if (whiteSkin) then - obj.TextColor3 = textColor - end - end - childNum = childNum + 1 - end - end - end - if not text then - dropDownMenu.Text = "Choose One" - scrollBarPosition = 1 - else - if not foundItem then - error("Invalid Selection Update -- " .. text) - end - - if scrollBarPosition + dropDownItemCount > itemCount + 1 then - scrollBarPosition = itemCount - dropDownItemCount + 1 - end - - dropDownMenu.Text = text - end - end - - local function scrollDown() - if scrollBarPosition + dropDownItemCount <= itemCount then - scrollBarPosition = scrollBarPosition + 1 - updateScroll() - return true - end - return false - end - local function scrollUp() - if scrollBarPosition > 1 then - scrollBarPosition = scrollBarPosition - 1 - updateScroll() - return true - end - return false - end - - if useScrollButtons then - --Make some scroll buttons - scrollUpButton = Instance.new("ImageButton") - scrollUpButton.Name = "ScrollUpButton" - scrollUpButton.BackgroundTransparency = 1 - scrollUpButton.Image = "rbxasset://textures/ui/scrollbuttonUp.png" - scrollUpButton.Size = UDim2.new(0,17,0,17) - scrollUpButton.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),0) - scrollUpButton.MouseButton1Click:connect( - function() - scrollMouseCount = scrollMouseCount + 1 - end) - scrollUpButton.MouseLeave:connect( - function() - scrollMouseCount = scrollMouseCount + 1 - end) - scrollUpButton.MouseButton1Down:connect( - function() - scrollMouseCount = scrollMouseCount + 1 - - scrollUp() - local val = scrollMouseCount - wait(0.5) - while val == scrollMouseCount do - if scrollUp() == false then - break - end - wait(0.1) - end - end) - - scrollUpButton.Parent = droppedDownMenu - - scrollDownButton = Instance.new("ImageButton") - scrollDownButton.Name = "ScrollDownButton" - scrollDownButton.BackgroundTransparency = 1 - scrollDownButton.Image = "rbxasset://textures/ui/scrollbuttonDown.png" - scrollDownButton.Size = UDim2.new(0,17,0,17) - scrollDownButton.Position = UDim2.new(1,-11,1,-11) - scrollDownButton.Parent = droppedDownMenu - scrollDownButton.MouseButton1Click:connect( - function() - scrollMouseCount = scrollMouseCount + 1 - end) - scrollDownButton.MouseLeave:connect( - function() - scrollMouseCount = scrollMouseCount + 1 - end) - scrollDownButton.MouseButton1Down:connect( - function() - scrollMouseCount = scrollMouseCount + 1 - - scrollDown() - local val = scrollMouseCount - wait(0.5) - while val == scrollMouseCount do - if scrollDown() == false then - break - end - wait(0.1) - end - end) - - local scrollbar = Instance.new("ImageLabel") - scrollbar.Name = "ScrollBar" - scrollbar.Image = "rbxasset://textures/ui/scrollbar.png" - scrollbar.BackgroundTransparency = 1 - scrollbar.Size = UDim2.new(0, 18, (dropDownItemCount*.8)/((dropDownItemCount+1)*.8), -(17) - 11 - 4) - scrollbar.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),17+2) - scrollbar.Parent = droppedDownMenu - end - - for i,item in ipairs(items) do - -- needed to maintain local scope for items in event listeners below - local button = choiceButton:clone() - if forRoblox then - button.RobloxLocked = true - end - button.Text = item - button.Parent = droppedDownMenu - if (whiteSkin) then - button.TextColor3 = textColor - end - - button.MouseButton1Click:connect(function() - --Remove Highlight - if (not whiteSkin) then - button.TextColor3 = Color3.new(1,1,1) - end - button.BackgroundTransparency = 1 - - updateSelection(item) - onSelect(item) - - toggleVisibility() - end) - button.MouseEnter:connect(function() - --Add Highlight - if (not whiteSkin) then - button.TextColor3 = Color3.new(0,0,0) - end - button.BackgroundTransparency = 0 - end) - - button.MouseLeave:connect(function() - --Remove Highlight - if (not whiteSkin) then - button.TextColor3 = Color3.new(1,1,1) - end - button.BackgroundTransparency = 1 - end) - end - - --This does the initial layout of the buttons - updateScroll() - - frame.AncestryChanged:connect(function(child,parent) - if parent == nil then - areaSoak.Parent = nil - else - areaSoak.Parent = getScreenGuiAncestor(frame) - end - end) - - dropDownMenu.MouseButton1Click:connect(toggleVisibility) - areaSoak.MouseButton1Click:connect(toggleVisibility) - return frame, updateSelection -end - -t.CreatePropertyDropDownMenu = function(instance, property, enum) - - local items = enum:GetEnumItems() - local names = {} - local nameToItem = {} - for i,obj in ipairs(items) do - names[i] = obj.Name - nameToItem[obj.Name] = obj - end - - local frame - local updateSelection - frame, updateSelection = t.CreateDropDownMenu(names, function(text) instance[property] = nameToItem[text] end) - - ScopedConnect(frame, instance, "Changed", - function(prop) - if prop == property then - updateSelection(instance[property].Name) - end - end, - function() - updateSelection(instance[property].Name) - end) - - return frame -end - -t.GetFontHeight = function(font, fontSize) - if font == nil or fontSize == nil then - error("Font and FontSize must be non-nil") - end - - if font == Enum.Font.Legacy then - if fontSize == Enum.FontSize.Size8 then - return 12 - elseif fontSize == Enum.FontSize.Size9 then - return 14 - elseif fontSize == Enum.FontSize.Size10 then - return 15 - elseif fontSize == Enum.FontSize.Size11 then - return 17 - elseif fontSize == Enum.FontSize.Size12 then - return 18 - elseif fontSize == Enum.FontSize.Size14 then - return 21 - elseif fontSize == Enum.FontSize.Size18 then - return 27 - elseif fontSize == Enum.FontSize.Size24 then - return 36 - elseif fontSize == Enum.FontSize.Size36 then - return 54 - elseif fontSize == Enum.FontSize.Size48 then - return 72 - else - error("Unknown FontSize") - end - elseif font == Enum.Font.Arial or font == Enum.Font.ArialBold then - if fontSize == Enum.FontSize.Size8 then - return 8 - elseif fontSize == Enum.FontSize.Size9 then - return 9 - elseif fontSize == Enum.FontSize.Size10 then - return 10 - elseif fontSize == Enum.FontSize.Size11 then - return 11 - elseif fontSize == Enum.FontSize.Size12 then - return 12 - elseif fontSize == Enum.FontSize.Size14 then - return 14 - elseif fontSize == Enum.FontSize.Size18 then - return 18 - elseif fontSize == Enum.FontSize.Size24 then - return 24 - elseif fontSize == Enum.FontSize.Size36 then - return 36 - elseif fontSize == Enum.FontSize.Size48 then - return 48 - else - error("Unknown FontSize") - end - else - error("Unknown Font " .. font) - end -end - -local function layoutGuiObjectsHelper(frame, guiObjects, settingsTable) - local totalPixels = frame.AbsoluteSize.Y - local pixelsRemaining = frame.AbsoluteSize.Y - for i, child in ipairs(guiObjects) do - if child:IsA("TextLabel") or child:IsA("TextButton") then - local isLabel = child:IsA("TextLabel") - if isLabel then - pixelsRemaining = pixelsRemaining - settingsTable["TextLabelPositionPadY"] - else - pixelsRemaining = pixelsRemaining - settingsTable["TextButtonPositionPadY"] - end - child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining) - child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, pixelsRemaining) - - if child.TextFits and child.TextBounds.Y < pixelsRemaining then - child.Visible = true - if isLabel then - child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable["TextLabelSizePadY"]) - else - child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable["TextButtonSizePadY"]) - end - - while not child.TextFits do - child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.AbsoluteSize.Y + 1) - end - pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y - - if isLabel then - pixelsRemaining = pixelsRemaining - settingsTable["TextLabelPositionPadY"] - else - pixelsRemaining = pixelsRemaining - settingsTable["TextButtonPositionPadY"] - end - else - child.Visible = false - pixelsRemaining = -1 - end - - else - --GuiObject - child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining) - pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y - child.Visible = (pixelsRemaining >= 0) - end - end -end - -t.LayoutGuiObjects = function(frame, guiObjects, settingsTable) - if not frame:IsA("GuiObject") then - error("Frame must be a GuiObject") - end - for i, child in ipairs(guiObjects) do - if not child:IsA("GuiObject") then - error("All elements that are layed out must be of type GuiObject") - end - end - - if not settingsTable then - settingsTable = {} - end - - if not settingsTable["TextLabelSizePadY"] then - settingsTable["TextLabelSizePadY"] = 0 - end - if not settingsTable["TextLabelPositionPadY"] then - settingsTable["TextLabelPositionPadY"] = 0 - end - if not settingsTable["TextButtonSizePadY"] then - settingsTable["TextButtonSizePadY"] = 12 - end - if not settingsTable["TextButtonPositionPadY"] then - settingsTable["TextButtonPositionPadY"] = 2 - end - - --Wrapper frame takes care of styled objects - local wrapperFrame = Instance.new("Frame") - wrapperFrame.Name = "WrapperFrame" - wrapperFrame.BackgroundTransparency = 1 - wrapperFrame.Size = UDim2.new(1,0,1,0) - wrapperFrame.Parent = frame - - for i, child in ipairs(guiObjects) do - child.Parent = wrapperFrame - end - - local recalculate = function() - wait() - layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable) - end - - frame.Changed:connect( - function(prop) - if prop == "AbsoluteSize" then - --Wait a heartbeat for it to sync in - recalculate(nil) - end - end) - frame.AncestryChanged:connect(recalculate) - - layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable) -end - - -t.CreateSlider = function(steps,width,position) - local sliderGui = Instance.new("Frame") - sliderGui.Size = UDim2.new(1,0,1,0) - sliderGui.BackgroundTransparency = 1 - sliderGui.Name = "SliderGui" - - local sliderSteps = Instance.new("IntValue") - sliderSteps.Name = "SliderSteps" - sliderSteps.Value = steps - sliderSteps.Parent = sliderGui - - local areaSoak = Instance.new("TextButton") - areaSoak.Name = "AreaSoak" - areaSoak.Text = "" - areaSoak.BackgroundTransparency = 1 - areaSoak.Active = false - areaSoak.Size = UDim2.new(1,0,1,0) - areaSoak.Visible = false - areaSoak.ZIndex = 4 - - sliderGui.AncestryChanged:connect(function(child,parent) - if parent == nil then - areaSoak.Parent = nil - else - areaSoak.Parent = getScreenGuiAncestor(sliderGui) - end - end) - - local sliderPosition = Instance.new("IntValue") - sliderPosition.Name = "SliderPosition" - sliderPosition.Value = 0 - sliderPosition.Parent = sliderGui - - local id = math.random(1,100) - - local bar = Instance.new("TextButton") - bar.Text = "" - bar.AutoButtonColor = false - bar.Name = "Bar" - bar.BackgroundColor3 = Color3.new(0,0,0) - if type(width) == "number" then - bar.Size = UDim2.new(0,width,0,5) - else - bar.Size = UDim2.new(0,200,0,5) - end - bar.BorderColor3 = Color3.new(95/255,95/255,95/255) - bar.ZIndex = 2 - bar.Parent = sliderGui - - if position["X"] and position["X"]["Scale"] and position["X"]["Offset"] and position["Y"] and position["Y"]["Scale"] and position["Y"]["Offset"] then - bar.Position = position - end - - local slider = Instance.new("ImageButton") - slider.Name = "Slider" - slider.BackgroundTransparency = 1 - slider.Image = "rbxasset://textures/ui/Slider.png" - slider.Position = UDim2.new(0,0,0.5,-10) - slider.Size = UDim2.new(0,20,0,20) - slider.ZIndex = 3 - slider.Parent = bar - - local areaSoakMouseMoveCon = nil - - areaSoak.MouseLeave:connect(function() - if areaSoak.Visible then - cancelSlide(areaSoak) - end - end) - areaSoak.MouseButton1Up:connect(function() - if areaSoak.Visible then - cancelSlide(areaSoak) - end - end) - - slider.MouseButton1Down:connect(function() - areaSoak.Visible = true - if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end - areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y) - setSliderPos(x,slider,sliderPosition,bar,steps) - end) - end) - - slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end) - - sliderPosition.Changed:connect(function(prop) - sliderPosition.Value = math.min(steps, math.max(1,sliderPosition.Value)) - local relativePosX = (sliderPosition.Value - 1) / (steps - 1) - slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset) - end) - - bar.MouseButton1Down:connect(function(x,y) - setSliderPos(x,slider,sliderPosition,bar,steps) - end) - - return sliderGui, sliderPosition, sliderSteps - -end - - - -t.CreateSliderNew = function(steps,width,position) - local sliderGui = Instance.new("Frame") - sliderGui.Size = UDim2.new(1,0,1,0) - sliderGui.BackgroundTransparency = 1 - sliderGui.Name = "SliderGui" - - local sliderSteps = Instance.new("IntValue") - sliderSteps.Name = "SliderSteps" - sliderSteps.Value = steps - sliderSteps.Parent = sliderGui - - local areaSoak = Instance.new("TextButton") - areaSoak.Name = "AreaSoak" - areaSoak.Text = "" - areaSoak.BackgroundTransparency = 1 - areaSoak.Active = false - areaSoak.Size = UDim2.new(1,0,1,0) - areaSoak.Visible = false - areaSoak.ZIndex = 6 - - sliderGui.AncestryChanged:connect(function(child,parent) - if parent == nil then - areaSoak.Parent = nil - else - areaSoak.Parent = getScreenGuiAncestor(sliderGui) - end - end) - - local sliderPosition = Instance.new("IntValue") - sliderPosition.Name = "SliderPosition" - sliderPosition.Value = 0 - sliderPosition.Parent = sliderGui - - local id = math.random(1,100) - - local sliderBarImgHeight = 7 - local sliderBarCapImgWidth = 4 - - local bar = Instance.new("ImageButton") - bar.BackgroundTransparency = 1 - bar.Image = "rbxasset://textures/ui/Slider-BKG-Center.png" - bar.Name = "Bar" - local displayWidth = 200 - if type(width) == "number" then - bar.Size = UDim2.new(0,width - (sliderBarCapImgWidth * 2),0,sliderBarImgHeight) - displayWidth = width - (sliderBarCapImgWidth * 2) - else - bar.Size = UDim2.new(0,200,0,sliderBarImgHeight) - end - bar.ZIndex = 3 - bar.Parent = sliderGui - if position["X"] and position["X"]["Scale"] and position["X"]["Offset"] and position["Y"] and position["Y"]["Scale"] and position["Y"]["Offset"] then - bar.Position = position - end - - local barLeft = bar:clone() - barLeft.Name = "BarLeft" - barLeft.Image = "rbxasset://textures/ui/Slider-BKG-Left-Cap.png" - barLeft.Size = UDim2.new(0, sliderBarCapImgWidth, 0, sliderBarImgHeight) - barLeft.Position = UDim2.new(position.X.Scale, position.X.Offset - sliderBarCapImgWidth, position.Y.Scale, position.Y.Offset) - barLeft.Parent = sliderGui - barLeft.ZIndex = 3 - - local barRight = barLeft:clone() - barRight.Name = "BarRight" - barRight.Image = "rbxasset://textures/ui/Slider-BKG-Right-Cap.png" - barRight.Position = UDim2.new(position.X.Scale, position.X.Offset + displayWidth, position.Y.Scale, position.Y.Offset) - barRight.Parent = sliderGui - - local fillLeft = barLeft:clone() - fillLeft.Name = "FillLeft" - fillLeft.Image = "rbxasset://textures/ui/Slider-Fill-Left-Cap.png" - fillLeft.Parent = sliderGui - fillLeft.ZIndex = 4 - - local fill = fillLeft:clone() - fill.Name = "Fill" - fill.Image = "rbxasset://textures/ui/Slider-Fill-Center.png" - fill.Parent = bar - fill.ZIndex = 4 - fill.Position = UDim2.new(0, 0, 0, 0) - fill.Size = UDim2.new(0.5, 0, 1, 0) - - --- bar.Visible = false - - local slider = Instance.new("ImageButton") - slider.Name = "Slider" - slider.BackgroundTransparency = 1 - slider.Image = "rbxasset://textures/ui/slider_new_tab.png" - slider.Position = UDim2.new(0,0,0.5,-14) - slider.Size = UDim2.new(0,28,0,28) - slider.ZIndex = 5 - slider.Parent = bar - - local areaSoakMouseMoveCon = nil - - areaSoak.MouseLeave:connect(function() - if areaSoak.Visible then - cancelSlide(areaSoak) - end - end) - areaSoak.MouseButton1Up:connect(function() - if areaSoak.Visible then - cancelSlide(areaSoak) - end - end) - - slider.MouseButton1Down:connect(function() - areaSoak.Visible = true - if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end - areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y) - setSliderPos(x,slider,sliderPosition,bar,steps) - end) - end) - - slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end) - - sliderPosition.Changed:connect(function(prop) - sliderPosition.Value = math.min(steps, math.max(1,sliderPosition.Value)) - local relativePosX = (sliderPosition.Value - 1) / (steps - 1) - slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset) - fill.Size = UDim2.new(relativePosX, 0, 1, 0) - end) - - bar.MouseButton1Down:connect(function(x,y) - setSliderPos(x,slider,sliderPosition,bar,steps) - end) - - return sliderGui, sliderPosition, sliderSteps - -end - - - - - -t.CreateTrueScrollingFrame = function() - local lowY = nil - local highY = nil - - local dragCon = nil - local upCon = nil - - local internalChange = false - - local descendantsChangeConMap = {} - - local scrollingFrame = Instance.new("Frame") - scrollingFrame.Name = "ScrollingFrame" - scrollingFrame.Active = true - scrollingFrame.Size = UDim2.new(1,0,1,0) - scrollingFrame.ClipsDescendants = true - - local controlFrame = Instance.new("Frame") - controlFrame.Name = "ControlFrame" - controlFrame.BackgroundTransparency = 1 - controlFrame.Size = UDim2.new(0,18,1,0) - controlFrame.Position = UDim2.new(1,-20,0,0) - controlFrame.Parent = scrollingFrame - - local scrollBottom = Instance.new("BoolValue") - scrollBottom.Value = false - scrollBottom.Name = "ScrollBottom" - scrollBottom.Parent = controlFrame - - local scrollUp = Instance.new("BoolValue") - scrollUp.Value = false - scrollUp.Name = "scrollUp" - scrollUp.Parent = controlFrame - - local scrollUpButton = Instance.new("TextButton") - scrollUpButton.Name = "ScrollUpButton" - scrollUpButton.Text = "" - scrollUpButton.AutoButtonColor = false - scrollUpButton.BackgroundColor3 = Color3.new(0,0,0) - scrollUpButton.BorderColor3 = Color3.new(1,1,1) - scrollUpButton.BackgroundTransparency = 0.5 - scrollUpButton.Size = UDim2.new(0,18,0,18) - scrollUpButton.ZIndex = 2 - scrollUpButton.Parent = controlFrame - for i = 1, 6 do - local triFrame = Instance.new("Frame") - triFrame.BorderColor3 = Color3.new(1,1,1) - triFrame.Name = "tri" .. tostring(i) - triFrame.ZIndex = 3 - triFrame.BackgroundTransparency = 0.5 - triFrame.Size = UDim2.new(0,12 - ((i -1) * 2),0,0) - triFrame.Position = UDim2.new(0,3 + (i -1),0.5,2 - (i -1)) - triFrame.Parent = scrollUpButton - end - scrollUpButton.MouseEnter:connect(function() - scrollUpButton.BackgroundTransparency = 0.1 - local upChildren = scrollUpButton:GetChildren() - for i = 1, #upChildren do - upChildren[i].BackgroundTransparency = 0.1 - end - end) - scrollUpButton.MouseLeave:connect(function() - scrollUpButton.BackgroundTransparency = 0.5 - local upChildren = scrollUpButton:GetChildren() - for i = 1, #upChildren do - upChildren[i].BackgroundTransparency = 0.5 - end - end) - - local scrollDownButton = scrollUpButton:clone() - scrollDownButton.Name = "ScrollDownButton" - scrollDownButton.Position = UDim2.new(0,0,1,-18) - local downChildren = scrollDownButton:GetChildren() - for i = 1, #downChildren do - downChildren[i].Position = UDim2.new(0,3 + (i -1),0.5,-2 + (i - 1)) - end - scrollDownButton.MouseEnter:connect(function() - scrollDownButton.BackgroundTransparency = 0.1 - local downChildren = scrollDownButton:GetChildren() - for i = 1, #downChildren do - downChildren[i].BackgroundTransparency = 0.1 - end - end) - scrollDownButton.MouseLeave:connect(function() - scrollDownButton.BackgroundTransparency = 0.5 - local downChildren = scrollDownButton:GetChildren() - for i = 1, #downChildren do - downChildren[i].BackgroundTransparency = 0.5 - end - end) - scrollDownButton.Parent = controlFrame - - local scrollTrack = Instance.new("Frame") - scrollTrack.Name = "ScrollTrack" - scrollTrack.BackgroundTransparency = 1 - scrollTrack.Size = UDim2.new(0,18,1,-38) - scrollTrack.Position = UDim2.new(0,0,0,19) - scrollTrack.Parent = controlFrame - - local scrollbar = Instance.new("TextButton") - scrollbar.BackgroundColor3 = Color3.new(0,0,0) - scrollbar.BorderColor3 = Color3.new(1,1,1) - scrollbar.BackgroundTransparency = 0.5 - scrollbar.AutoButtonColor = false - scrollbar.Text = "" - scrollbar.Active = true - scrollbar.Name = "ScrollBar" - scrollbar.ZIndex = 2 - scrollbar.BackgroundTransparency = 0.5 - scrollbar.Size = UDim2.new(0, 18, 0.1, 0) - scrollbar.Position = UDim2.new(0,0,0,0) - scrollbar.Parent = scrollTrack - - local scrollNub = Instance.new("Frame") - scrollNub.Name = "ScrollNub" - scrollNub.BorderColor3 = Color3.new(1,1,1) - scrollNub.Size = UDim2.new(0,10,0,0) - scrollNub.Position = UDim2.new(0.5,-5,0.5,0) - scrollNub.ZIndex = 2 - scrollNub.BackgroundTransparency = 0.5 - scrollNub.Parent = scrollbar - - local newNub = scrollNub:clone() - newNub.Position = UDim2.new(0.5,-5,0.5,-2) - newNub.Parent = scrollbar - - local lastNub = scrollNub:clone() - lastNub.Position = UDim2.new(0.5,-5,0.5,2) - lastNub.Parent = scrollbar - - scrollbar.MouseEnter:connect(function() - scrollbar.BackgroundTransparency = 0.1 - scrollNub.BackgroundTransparency = 0.1 - newNub.BackgroundTransparency = 0.1 - lastNub.BackgroundTransparency = 0.1 - end) - scrollbar.MouseLeave:connect(function() - scrollbar.BackgroundTransparency = 0.5 - scrollNub.BackgroundTransparency = 0.5 - newNub.BackgroundTransparency = 0.5 - lastNub.BackgroundTransparency = 0.5 - end) - - local mouseDrag = Instance.new("ImageButton") - mouseDrag.Active = false - mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0) - mouseDrag.AutoButtonColor = false - mouseDrag.BackgroundTransparency = 1 - mouseDrag.Name = "mouseDrag" - mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0) - mouseDrag.ZIndex = 10 - - local function positionScrollBar(x,y,offset) - local oldPos = scrollbar.Position - - if y < scrollTrack.AbsolutePosition.y then - scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0) - return (oldPos ~= scrollbar.Position) - end - - local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y - - if y > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then - scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0) - return (oldPos ~= scrollbar.Position) - end - local newScaleYPos = (y - scrollTrack.AbsolutePosition.y - offset)/scrollTrack.AbsoluteSize.y - if newScaleYPos + relativeSize > 1 then - newScaleYPos = 1 - relativeSize - scrollBottom.Value = true - scrollUp.Value = false - elseif newScaleYPos <= 0 then - newScaleYPos = 0 - scrollUp.Value = true - scrollBottom.Value = false - else - scrollUp.Value = false - scrollBottom.Value = false - end - scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,newScaleYPos,0) - - return (oldPos ~= scrollbar.Position) - end - - local function drillDownSetHighLow(instance) - if not instance or not instance:IsA("GuiObject") then return end - if instance == controlFrame then return end - if instance:IsDescendantOf(controlFrame) then return end - if not instance.Visible then return end - - if lowY and lowY > instance.AbsolutePosition.Y then - lowY = instance.AbsolutePosition.Y - elseif not lowY then - lowY = instance.AbsolutePosition.Y - end - if highY and highY < (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) then - highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y - elseif not highY then - highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y - end - local children = instance:GetChildren() - for i = 1, #children do - drillDownSetHighLow(children[i]) - end - end - - local function resetHighLow() - local firstChildren = scrollingFrame:GetChildren() - - for i = 1, #firstChildren do - drillDownSetHighLow(firstChildren[i]) - end - end - - local function recalculate() - internalChange = true - - local percentFrame = 0 - if scrollbar.Position.Y.Scale > 0 then - if scrollbar.Visible then - percentFrame = scrollbar.Position.Y.Scale/((scrollTrack.AbsoluteSize.Y - scrollbar.AbsoluteSize.Y)/scrollTrack.AbsoluteSize.Y) - else - percentFrame = 0 - end - end - if percentFrame > 0.99 then percentFrame = 1 end - - local hiddenYAmount = (scrollingFrame.AbsoluteSize.Y - (highY - lowY)) * percentFrame - - local guiChildren = scrollingFrame:GetChildren() - for i = 1, #guiChildren do - if guiChildren[i] ~= controlFrame then - guiChildren[i].Position = UDim2.new(guiChildren[i].Position.X.Scale,guiChildren[i].Position.X.Offset, - 0, math.ceil(guiChildren[i].AbsolutePosition.Y) - math.ceil(lowY) + hiddenYAmount) - end - end - - lowY = nil - highY = nil - resetHighLow() - internalChange = false - end - - local function setSliderSizeAndPosition() - if not highY or not lowY then return end - - local totalYSpan = math.abs(highY - lowY) - if totalYSpan == 0 then - scrollbar.Visible = false - scrollDownButton.Visible = false - scrollUpButton.Visible = false - - if dragCon then dragCon:disconnect() dragCon = nil end - if upCon then upCon:disconnect() upCon = nil end - return - end - - local percentShown = scrollingFrame.AbsoluteSize.Y/totalYSpan - if percentShown >= 1 then - scrollbar.Visible = false - scrollDownButton.Visible = false - scrollUpButton.Visible = false - recalculate() - else - scrollbar.Visible = true - scrollDownButton.Visible = true - scrollUpButton.Visible = true - - scrollbar.Size = UDim2.new(scrollbar.Size.X.Scale,scrollbar.Size.X.Offset,percentShown,0) - end - - local percentPosition = (scrollingFrame.AbsolutePosition.Y - lowY)/totalYSpan - scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,percentPosition,-scrollbar.AbsoluteSize.X/2) - - if scrollbar.AbsolutePosition.y < scrollTrack.AbsolutePosition.y then - scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0) - end - - if (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.Y) > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then - local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y - scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0) - end - end - - local buttonScrollAmountPixels = 7 - local reentrancyGuardScrollUp = false - local function doScrollUp() - if reentrancyGuardScrollUp then return end - - reentrancyGuardScrollUp = true - if positionScrollBar(0,scrollbar.AbsolutePosition.Y - buttonScrollAmountPixels,0) then - recalculate() - end - reentrancyGuardScrollUp = false - end - - local reentrancyGuardScrollDown = false - local function doScrollDown() - if reentrancyGuardScrollDown then return end - - reentrancyGuardScrollDown = true - if positionScrollBar(0,scrollbar.AbsolutePosition.Y + buttonScrollAmountPixels,0) then - recalculate() - end - reentrancyGuardScrollDown = false - end - - local function scrollUp(mouseYPos) - if scrollUpButton.Active then - scrollStamp = tick() - local current = scrollStamp - local upCon - upCon = mouseDrag.MouseButton1Up:connect(function() - scrollStamp = tick() - mouseDrag.Parent = nil - upCon:disconnect() - end) - mouseDrag.Parent = getScreenGuiAncestor(scrollbar) - doScrollUp() - wait(0.2) - local t = tick() - local w = 0.1 - while scrollStamp == current do - doScrollUp() - if mouseYPos and mouseYPos > scrollbar.AbsolutePosition.y then - break - end - if not scrollUpButton.Active then break end - if tick()-t > 5 then - w = 0 - elseif tick()-t > 2 then - w = 0.06 - end - wait(w) - end - end - end - - local function scrollDown(mouseYPos) - if scrollDownButton.Active then - scrollStamp = tick() - local current = scrollStamp - local downCon - downCon = mouseDrag.MouseButton1Up:connect(function() - scrollStamp = tick() - mouseDrag.Parent = nil - downCon:disconnect() - end) - mouseDrag.Parent = getScreenGuiAncestor(scrollbar) - doScrollDown() - wait(0.2) - local t = tick() - local w = 0.1 - while scrollStamp == current do - doScrollDown() - if mouseYPos and mouseYPos < (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.x) then - break - end - if not scrollDownButton.Active then break end - if tick()-t > 5 then - w = 0 - elseif tick()-t > 2 then - w = 0.06 - end - wait(w) - end - end - end - - scrollbar.MouseButton1Down:connect(function(x,y) - if scrollbar.Active then - scrollStamp = tick() - local mouseOffset = y - scrollbar.AbsolutePosition.y - if dragCon then dragCon:disconnect() dragCon = nil end - if upCon then upCon:disconnect() upCon = nil end - local prevY = y - local reentrancyGuardMouseScroll = false - dragCon = mouseDrag.MouseMoved:connect(function(x,y) - if reentrancyGuardMouseScroll then return end - - reentrancyGuardMouseScroll = true - if positionScrollBar(x,y,mouseOffset) then - recalculate() - end - reentrancyGuardMouseScroll = false - - end) - upCon = mouseDrag.MouseButton1Up:connect(function() - scrollStamp = tick() - mouseDrag.Parent = nil - dragCon:disconnect(); dragCon = nil - upCon:disconnect(); drag = nil - end) - mouseDrag.Parent = getScreenGuiAncestor(scrollbar) - end - end) - - local scrollMouseCount = 0 - - scrollUpButton.MouseButton1Down:connect(function() - scrollUp() - end) - scrollUpButton.MouseButton1Up:connect(function() - scrollStamp = tick() - end) - - scrollDownButton.MouseButton1Up:connect(function() - scrollStamp = tick() - end) - scrollDownButton.MouseButton1Down:connect(function() - scrollDown() - end) - - scrollbar.MouseButton1Up:connect(function() - scrollStamp = tick() - end) - - local function heightCheck(instance) - if highY and (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) > highY then - highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y - elseif not highY then - highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y - end - setSliderSizeAndPosition() - end - - local function highLowRecheck() - local oldLowY = lowY - local oldHighY = highY - lowY = nil - highY = nil - resetHighLow() - - if (lowY ~= oldLowY) or (highY ~= oldHighY) then - setSliderSizeAndPosition() - end - end - - local function descendantChanged(this, prop) - if internalChange then return end - if not this.Visible then return end - - if prop == "Size" or prop == "Position" then - wait() - highLowRecheck() - end - end - - scrollingFrame.DescendantAdded:connect(function(instance) - if not instance:IsA("GuiObject") then return end - - if instance.Visible then - wait() -- wait a heartbeat for sizes to reconfig - highLowRecheck() - end - - descendantsChangeConMap[instance] = instance.Changed:connect(function(prop) descendantChanged(instance, prop) end) - end) - - scrollingFrame.DescendantRemoving:connect(function(instance) - if not instance:IsA("GuiObject") then return end - if descendantsChangeConMap[instance] then - descendantsChangeConMap[instance]:disconnect() - descendantsChangeConMap[instance] = nil - end - wait() -- wait a heartbeat for sizes to reconfig - highLowRecheck() - end) - - scrollingFrame.Changed:connect(function(prop) - if prop == "AbsoluteSize" then - if not highY or not lowY then return end - - highLowRecheck() - setSliderSizeAndPosition() - end - end) - - return scrollingFrame, controlFrame -end - -t.CreateScrollingFrame = function(orderList,scrollStyle) - local frame = Instance.new("Frame") - frame.Name = "ScrollingFrame" - frame.BackgroundTransparency = 1 - frame.Size = UDim2.new(1,0,1,0) - - local scrollUpButton = Instance.new("ImageButton") - scrollUpButton.Name = "ScrollUpButton" - scrollUpButton.BackgroundTransparency = 1 - scrollUpButton.Image = "rbxasset://textures/ui/scrollbuttonUp.png" - scrollUpButton.Size = UDim2.new(0,17,0,17) - - - local scrollDownButton = Instance.new("ImageButton") - scrollDownButton.Name = "ScrollDownButton" - scrollDownButton.BackgroundTransparency = 1 - scrollDownButton.Image = "rbxasset://textures/ui/scrollbuttonDown.png" - scrollDownButton.Size = UDim2.new(0,17,0,17) - - local scrollbar = Instance.new("ImageButton") - scrollbar.Name = "ScrollBar" - scrollbar.Image = "rbxasset://textures/ui/scrollbar.png" - scrollbar.BackgroundTransparency = 1 - scrollbar.Size = UDim2.new(0, 18, 0, 150) - - local scrollStamp = 0 - - local scrollDrag = Instance.new("ImageButton") - scrollDrag.Image = "http://www.roblox.com/asset/?id=61367186" - scrollDrag.Size = UDim2.new(1, 0, 0, 16) - scrollDrag.BackgroundTransparency = 1 - scrollDrag.Name = "ScrollDrag" - scrollDrag.Active = true - scrollDrag.Parent = scrollbar - - local mouseDrag = Instance.new("ImageButton") - mouseDrag.Active = false - mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0) - mouseDrag.AutoButtonColor = false - mouseDrag.BackgroundTransparency = 1 - mouseDrag.Name = "mouseDrag" - mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0) - mouseDrag.ZIndex = 10 - - local style = "simple" - if scrollStyle and tostring(scrollStyle) then - style = scrollStyle - end - - local scrollPosition = 1 - local rowSize = 0 - local howManyDisplayed = 0 - - local layoutGridScrollBar = function() - howManyDisplayed = 0 - local guiObjects = {} - if orderList then - for i, child in ipairs(orderList) do - if child.Parent == frame then - table.insert(guiObjects, child) - end - end - else - local children = frame:GetChildren() - if children then - for i, child in ipairs(children) do - if child:IsA("GuiObject") then - table.insert(guiObjects, child) - end - end - end - end - if #guiObjects == 0 then - scrollUpButton.Active = false - scrollDownButton.Active = false - scrollDrag.Active = false - scrollPosition = 1 - return - end - - if scrollPosition > #guiObjects then - scrollPosition = #guiObjects - end - - if scrollPosition < 1 then scrollPosition = 1 end - - local totalPixelsY = frame.AbsoluteSize.Y - local pixelsRemainingY = frame.AbsoluteSize.Y - - local totalPixelsX = frame.AbsoluteSize.X - - local xCounter = 0 - local rowSizeCounter = 0 - local setRowSize = true - - local pixelsBelowScrollbar = 0 - local pos = #guiObjects - - local currentRowY = 0 - - pos = scrollPosition - --count up from current scroll position to fill out grid - while pos <= #guiObjects and pixelsBelowScrollbar < totalPixelsY do - xCounter = xCounter + guiObjects[pos].AbsoluteSize.X - --previous pos was the end of a row - if xCounter >= totalPixelsX then - pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY - currentRowY = 0 - xCounter = guiObjects[pos].AbsoluteSize.X - end - if guiObjects[pos].AbsoluteSize.Y > currentRowY then - currentRowY = guiObjects[pos].AbsoluteSize.Y - end - pos = pos + 1 - end - --Count wherever current row left off - pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY - currentRowY = 0 - - pos = scrollPosition - 1 - xCounter = 0 - - --objects with varying X,Y dimensions can rarely cause minor errors - --rechecking every new scrollPosition is necessary to avoid 100% of errors - - --count backwards from current scrollPosition to see if we can add more rows - while pixelsBelowScrollbar + currentRowY < totalPixelsY and pos >= 1 do - xCounter = xCounter + guiObjects[pos].AbsoluteSize.X - rowSizeCounter = rowSizeCounter + 1 - if xCounter >= totalPixelsX then - rowSize = rowSizeCounter - 1 - rowSizeCounter = 0 - xCounter = guiObjects[pos].AbsoluteSize.X - if pixelsBelowScrollbar + currentRowY <= totalPixelsY then - --It fits, so back up our scroll position - pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY - if scrollPosition <= rowSize then - scrollPosition = 1 - break - else - scrollPosition = scrollPosition - rowSize - end - currentRowY = 0 - else - break - end - end - - if guiObjects[pos].AbsoluteSize.Y > currentRowY then - currentRowY = guiObjects[pos].AbsoluteSize.Y - end - - pos = pos - 1 - end - - --Do check last time if pos = 0 - if (pos == 0) and (pixelsBelowScrollbar + currentRowY <= totalPixelsY) then - scrollPosition = 1 - end - - xCounter = 0 - --pos = scrollPosition - rowSizeCounter = 0 - setRowSize = true - local lastChildSize = 0 - - local xOffset,yOffset = 0 - if guiObjects[1] then - yOffset = math.ceil(math.floor(math.fmod(totalPixelsY,guiObjects[1].AbsoluteSize.X))/2) - xOffset = math.ceil(math.floor(math.fmod(totalPixelsX,guiObjects[1].AbsoluteSize.Y))/2) - end - - for i, child in ipairs(guiObjects) do - if i < scrollPosition then - --print("Hiding " .. child.Name) - child.Visible = false - else - if pixelsRemainingY < 0 then - --print("Out of Space " .. child.Name) - child.Visible = false - else - --print("Laying out " .. child.Name) - --GuiObject - if setRowSize then rowSizeCounter = rowSizeCounter + 1 end - if xCounter + child.AbsoluteSize.X >= totalPixelsX then - if setRowSize then - rowSize = rowSizeCounter - 1 - setRowSize = false - end - xCounter = 0 - pixelsRemainingY = pixelsRemainingY - child.AbsoluteSize.Y - end - child.Position = UDim2.new(child.Position.X.Scale,xCounter + xOffset, 0, totalPixelsY - pixelsRemainingY + yOffset) - xCounter = xCounter + child.AbsoluteSize.X - child.Visible = ((pixelsRemainingY - child.AbsoluteSize.Y) >= 0) - if child.Visible then - howManyDisplayed = howManyDisplayed + 1 - end - lastChildSize = child.AbsoluteSize - end - end - end - - scrollUpButton.Active = (scrollPosition > 1) - if lastChildSize == 0 then - scrollDownButton.Active = false - else - scrollDownButton.Active = ((pixelsRemainingY - lastChildSize.Y) < 0) - end - scrollDrag.Active = #guiObjects > howManyDisplayed - scrollDrag.Visible = scrollDrag.Active - end - - - - local layoutSimpleScrollBar = function() - local guiObjects = {} - howManyDisplayed = 0 - - if orderList then - for i, child in ipairs(orderList) do - if child.Parent == frame then - table.insert(guiObjects, child) - end - end - else - local children = frame:GetChildren() - if children then - for i, child in ipairs(children) do - if child:IsA("GuiObject") then - table.insert(guiObjects, child) - end - end - end - end - if #guiObjects == 0 then - scrollUpButton.Active = false - scrollDownButton.Active = false - scrollDrag.Active = false - scrollPosition = 1 - return - end - - if scrollPosition > #guiObjects then - scrollPosition = #guiObjects - end - - local totalPixels = frame.AbsoluteSize.Y - local pixelsRemaining = frame.AbsoluteSize.Y - - local pixelsBelowScrollbar = 0 - local pos = #guiObjects - while pixelsBelowScrollbar < totalPixels and pos >= 1 do - if pos >= scrollPosition then - pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y - else - if pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y <= totalPixels then - --It fits, so back up our scroll position - pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y - if scrollPosition <= 1 then - scrollPosition = 1 - break - else - --local ("Backing up ScrollPosition from -- " ..scrollPosition) - scrollPosition = scrollPosition - 1 - end - else - break - end - end - pos = pos - 1 - end - - pos = scrollPosition - for i, child in ipairs(guiObjects) do - if i < scrollPosition then - --print("Hiding " .. child.Name) - child.Visible = false - else - if pixelsRemaining < 0 then - --print("Out of Space " .. child.Name) - child.Visible = false - else - --print("Laying out " .. child.Name) - --GuiObject - child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining) - pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y - if (pixelsRemaining >= 0) then - child.Visible = true - howManyDisplayed = howManyDisplayed + 1 - else - child.Visible = false - end - end - end - end - scrollUpButton.Active = (scrollPosition > 1) - scrollDownButton.Active = (pixelsRemaining < 0) - scrollDrag.Active = #guiObjects > howManyDisplayed - scrollDrag.Visible = scrollDrag.Active - end - - - local moveDragger = function() - local guiObjects = 0 - local children = frame:GetChildren() - if children then - for i, child in ipairs(children) do - if child:IsA("GuiObject") then - guiObjects = guiObjects + 1 - end - end - end - - if not scrollDrag.Parent then return end - - local dragSizeY = scrollDrag.Parent.AbsoluteSize.y * (1/(guiObjects - howManyDisplayed + 1)) - if dragSizeY < 16 then dragSizeY = 16 end - scrollDrag.Size = UDim2.new(scrollDrag.Size.X.Scale,scrollDrag.Size.X.Offset,scrollDrag.Size.Y.Scale,dragSizeY) - - local relativeYPos = (scrollPosition - 1)/(guiObjects - (howManyDisplayed)) - if relativeYPos > 1 then relativeYPos = 1 - elseif relativeYPos < 0 then relativeYPos = 0 end - local absYPos = 0 - - if relativeYPos ~= 0 then - absYPos = (relativeYPos * scrollbar.AbsoluteSize.y) - (relativeYPos * scrollDrag.AbsoluteSize.y) - end - - scrollDrag.Position = UDim2.new(scrollDrag.Position.X.Scale,scrollDrag.Position.X.Offset,scrollDrag.Position.Y.Scale,absYPos) - end - - local reentrancyGuard = false - local recalculate = function() - if reentrancyGuard then - return - end - reentrancyGuard = true - wait() - local success, err = nil - if style == "grid" then - success, err = pcall(function() layoutGridScrollBar() end) - elseif style == "simple" then - success, err = pcall(function() layoutSimpleScrollBar() end) - end - if not success then print(err) end - moveDragger() - reentrancyGuard = false - end - - local doScrollUp = function() - scrollPosition = (scrollPosition) - rowSize - if scrollPosition < 1 then scrollPosition = 1 end - recalculate(nil) - end - - local doScrollDown = function() - scrollPosition = (scrollPosition) + rowSize - recalculate(nil) - end - - local scrollUp = function(mouseYPos) - if scrollUpButton.Active then - scrollStamp = tick() - local current = scrollStamp - local upCon - upCon = mouseDrag.MouseButton1Up:connect(function() - scrollStamp = tick() - mouseDrag.Parent = nil - upCon:disconnect() - end) - mouseDrag.Parent = getScreenGuiAncestor(scrollbar) - doScrollUp() - wait(0.2) - local t = tick() - local w = 0.1 - while scrollStamp == current do - doScrollUp() - if mouseYPos and mouseYPos > scrollDrag.AbsolutePosition.y then - break - end - if not scrollUpButton.Active then break end - if tick()-t > 5 then - w = 0 - elseif tick()-t > 2 then - w = 0.06 - end - wait(w) - end - end - end - - local scrollDown = function(mouseYPos) - if scrollDownButton.Active then - scrollStamp = tick() - local current = scrollStamp - local downCon - downCon = mouseDrag.MouseButton1Up:connect(function() - scrollStamp = tick() - mouseDrag.Parent = nil - downCon:disconnect() - end) - mouseDrag.Parent = getScreenGuiAncestor(scrollbar) - doScrollDown() - wait(0.2) - local t = tick() - local w = 0.1 - while scrollStamp == current do - doScrollDown() - if mouseYPos and mouseYPos < (scrollDrag.AbsolutePosition.y + scrollDrag.AbsoluteSize.x) then - break - end - if not scrollDownButton.Active then break end - if tick()-t > 5 then - w = 0 - elseif tick()-t > 2 then - w = 0.06 - end - wait(w) - end - end - end - - local y = 0 - scrollDrag.MouseButton1Down:connect(function(x,y) - if scrollDrag.Active then - scrollStamp = tick() - local mouseOffset = y - scrollDrag.AbsolutePosition.y - local dragCon - local upCon - dragCon = mouseDrag.MouseMoved:connect(function(x,y) - local barAbsPos = scrollbar.AbsolutePosition.y - local barAbsSize = scrollbar.AbsoluteSize.y - - local dragAbsSize = scrollDrag.AbsoluteSize.y - local barAbsOne = barAbsPos + barAbsSize - dragAbsSize - y = y - mouseOffset - y = y < barAbsPos and barAbsPos or y > barAbsOne and barAbsOne or y - y = y - barAbsPos - - local guiObjects = 0 - local children = frame:GetChildren() - if children then - for i, child in ipairs(children) do - if child:IsA("GuiObject") then - guiObjects = guiObjects + 1 - end - end - end - - local doublePercent = y/(barAbsSize-dragAbsSize) - local rowDiff = rowSize - local totalScrollCount = guiObjects - (howManyDisplayed - 1) - local newScrollPosition = math.floor((doublePercent * totalScrollCount) + 0.5) + rowDiff - if newScrollPosition < scrollPosition then - rowDiff = -rowDiff - end - - if newScrollPosition < 1 then - newScrollPosition = 1 - end - - scrollPosition = newScrollPosition - recalculate(nil) - end) - upCon = mouseDrag.MouseButton1Up:connect(function() - scrollStamp = tick() - mouseDrag.Parent = nil - dragCon:disconnect(); dragCon = nil - upCon:disconnect(); drag = nil - end) - mouseDrag.Parent = getScreenGuiAncestor(scrollbar) - end - end) - - local scrollMouseCount = 0 - - scrollUpButton.MouseButton1Down:connect( - function() - scrollUp() - end) - scrollUpButton.MouseButton1Up:connect(function() - scrollStamp = tick() - end) - - - scrollDownButton.MouseButton1Up:connect(function() - scrollStamp = tick() - end) - scrollDownButton.MouseButton1Down:connect( - function() - scrollDown() - end) - - scrollbar.MouseButton1Up:connect(function() - scrollStamp = tick() - end) - scrollbar.MouseButton1Down:connect( - function(x,y) - if y > (scrollDrag.AbsoluteSize.y + scrollDrag.AbsolutePosition.y) then - scrollDown(y) - elseif y < (scrollDrag.AbsolutePosition.y) then - scrollUp(y) - end - end) - - - frame.ChildAdded:connect(function() - recalculate(nil) - end) - - frame.ChildRemoved:connect(function() - recalculate(nil) - end) - - frame.Changed:connect( - function(prop) - if prop == "AbsoluteSize" then - --Wait a heartbeat for it to sync in - recalculate(nil) - end - end) - frame.AncestryChanged:connect(function() recalculate(nil) end) - - return frame, scrollUpButton, scrollDownButton, recalculate, scrollbar -end -local function binaryGrow(min, max, fits) - if min > max then - return min - end - local biggestLegal = min - - while min <= max do - local mid = min + math.floor((max - min) / 2) - if fits(mid) and (biggestLegal == nil or biggestLegal < mid) then - biggestLegal = mid - - --Try growing - min = mid + 1 - else - --Doesn't fit, shrink - max = mid - 1 - end - end - return biggestLegal -end - - -local function binaryShrink(min, max, fits) - if min > max then - return min - end - local smallestLegal = max - - while min <= max do - local mid = min + math.floor((max - min) / 2) - if fits(mid) and (smallestLegal == nil or smallestLegal > mid) then - smallestLegal = mid - - --It fits, shrink - max = mid - 1 - else - --Doesn't fit, grow - min = mid + 1 - end - end - return smallestLegal -end - - -local function getGuiOwner(instance) - while instance ~= nil do - if instance:IsA("ScreenGui") or instance:IsA("BillboardGui") then - return instance - end - instance = instance.Parent - end - return nil -end - -t.AutoTruncateTextObject = function(textLabel) - local text = textLabel.Text - - local fullLabel = textLabel:Clone() - fullLabel.Name = "Full" .. textLabel.Name - fullLabel.BorderSizePixel = 0 - fullLabel.BackgroundTransparency = 0 - fullLabel.Text = text - fullLabel.TextXAlignment = Enum.TextXAlignment.Center - fullLabel.Position = UDim2.new(0,-3,0,0) - fullLabel.Size = UDim2.new(0,100,1,0) - fullLabel.Visible = false - fullLabel.Parent = textLabel - - local shortText = nil - local mouseEnterConnection = nil - local mouseLeaveConnection= nil - - local checkForResize = function() - if getGuiOwner(textLabel) == nil then - return - end - textLabel.Text = text - if textLabel.TextFits then - --Tear down the rollover if it is active - if mouseEnterConnection then - mouseEnterConnection:disconnect() - mouseEnterConnection = nil - end - if mouseLeaveConnection then - mouseLeaveConnection:disconnect() - mouseLeaveConnection = nil - end - else - local len = string.len(text) - textLabel.Text = text .. "~" - - --Shrink the text - local textSize = binaryGrow(0, len, - function(pos) - if pos == 0 then - textLabel.Text = "~" - else - textLabel.Text = string.sub(text, 1, pos) .. "~" - end - return textLabel.TextFits - end) - shortText = string.sub(text, 1, textSize) .. "~" - textLabel.Text = shortText - - --Make sure the fullLabel fits - if not fullLabel.TextFits then - --Already too small, grow it really bit to start - fullLabel.Size = UDim2.new(0, 10000, 1, 0) - end - - --Okay, now try to binary shrink it back down - local fullLabelSize = binaryShrink(textLabel.AbsoluteSize.X,fullLabel.AbsoluteSize.X, - function(size) - fullLabel.Size = UDim2.new(0, size, 1, 0) - return fullLabel.TextFits - end) - fullLabel.Size = UDim2.new(0,fullLabelSize+6,1,0) - - --Now setup the rollover effects, if they are currently off - if mouseEnterConnection == nil then - mouseEnterConnection = textLabel.MouseEnter:connect( - function() - fullLabel.ZIndex = textLabel.ZIndex + 1 - fullLabel.Visible = true - --textLabel.Text = "" - end) - end - if mouseLeaveConnection == nil then - mouseLeaveConnection = textLabel.MouseLeave:connect( - function() - fullLabel.Visible = false - --textLabel.Text = shortText - end) - end - end - end - textLabel.AncestryChanged:connect(checkForResize) - textLabel.Changed:connect( - function(prop) - if prop == "AbsoluteSize" then - checkForResize() - end - end) - - checkForResize() - - local function changeText(newText) - text = newText - fullLabel.Text = text - checkForResize() - end - - return textLabel, changeText -end - -local function TransitionTutorialPages(fromPage, toPage, transitionFrame, currentPageValue) - if fromPage then - fromPage.Visible = false - if transitionFrame.Visible == false then - transitionFrame.Size = fromPage.Size - transitionFrame.Position = fromPage.Position - end - else - if transitionFrame.Visible == false then - transitionFrame.Size = UDim2.new(0.0,50,0.0,50) - transitionFrame.Position = UDim2.new(0.5,-25,0.5,-25) - end - end - transitionFrame.Visible = true - currentPageValue.Value = nil - - local newsize, newPosition - if toPage then - --Make it visible so it resizes - toPage.Visible = true - - newSize = toPage.Size - newPosition = toPage.Position - - toPage.Visible = false - else - newSize = UDim2.new(0.0,50,0.0,50) - newPosition = UDim2.new(0.5,-25,0.5,-25) - end - transitionFrame:TweenSizeAndPosition(newSize, newPosition, Enum.EasingDirection.InOut, Enum.EasingStyle.Quad, 0.3, true, - function(state) - if state == Enum.TweenStatus.Completed then - transitionFrame.Visible = false - if toPage then - toPage.Visible = true - currentPageValue.Value = toPage - end - end - end) -end - -t.CreateTutorial = function(name, tutorialKey, createButtons) - local frame = Instance.new("Frame") - frame.Name = "Tutorial-" .. name - frame.BackgroundTransparency = 1 - frame.Size = UDim2.new(0.6, 0, 0.6, 0) - frame.Position = UDim2.new(0.2, 0, 0.2, 0) - - local transitionFrame = Instance.new("Frame") - transitionFrame.Name = "TransitionFrame" - transitionFrame.Style = Enum.FrameStyle.RobloxRound - transitionFrame.Size = UDim2.new(0.6, 0, 0.6, 0) - transitionFrame.Position = UDim2.new(0.2, 0, 0.2, 0) - transitionFrame.Visible = false - transitionFrame.Parent = frame - - local currentPageValue = Instance.new("ObjectValue") - currentPageValue.Name = "CurrentTutorialPage" - currentPageValue.Value = nil - currentPageValue.Parent = frame - - local boolValue = Instance.new("BoolValue") - boolValue.Name = "Buttons" - boolValue.Value = createButtons - boolValue.Parent = frame - - local pages = Instance.new("Frame") - pages.Name = "Pages" - pages.BackgroundTransparency = 1 - pages.Size = UDim2.new(1,0,1,0) - pages.Parent = frame - - local function getVisiblePageAndHideOthers() - local visiblePage = nil - local children = pages:GetChildren() - if children then - for i,child in ipairs(children) do - if child.Visible then - if visiblePage then - child.Visible = false - else - visiblePage = child - end - end - end - end - return visiblePage - end - - local showTutorial = function(alwaysShow) - if alwaysShow or UserSettings().GameSettings:GetTutorialState(tutorialKey) == false then - print("Showing tutorial-",tutorialKey) - local currentTutorialPage = getVisiblePageAndHideOthers() - - local firstPage = pages:FindFirstChild("TutorialPage1") - if firstPage then - TransitionTutorialPages(currentTutorialPage, firstPage, transitionFrame, currentPageValue) - else - error("Could not find TutorialPage1") - end - end - end - - local dismissTutorial = function() - local currentTutorialPage = getVisiblePageAndHideOthers() - - if currentTutorialPage then - TransitionTutorialPages(currentTutorialPage, nil, transitionFrame, currentPageValue) - end - - UserSettings().GameSettings:SetTutorialState(tutorialKey, true) - end - - local gotoPage = function(pageNum) - local page = pages:FindFirstChild("TutorialPage" .. pageNum) - local currentTutorialPage = getVisiblePageAndHideOthers() - TransitionTutorialPages(currentTutorialPage, page, transitionFrame, currentPageValue) - end - - return frame, showTutorial, dismissTutorial, gotoPage -end - -local function CreateBasicTutorialPage(name, handleResize, skipTutorial, giveDoneButton) - local frame = Instance.new("Frame") - frame.Name = "TutorialPage" - frame.Style = Enum.FrameStyle.RobloxRound - frame.Size = UDim2.new(0.6, 0, 0.6, 0) - frame.Position = UDim2.new(0.2, 0, 0.2, 0) - frame.Visible = false - - local frameHeader = Instance.new("TextLabel") - frameHeader.Name = "Header" - frameHeader.Text = name - frameHeader.BackgroundTransparency = 1 - frameHeader.FontSize = Enum.FontSize.Size24 - frameHeader.Font = Enum.Font.ArialBold - frameHeader.TextColor3 = Color3.new(1,1,1) - frameHeader.TextXAlignment = Enum.TextXAlignment.Center - frameHeader.TextWrap = true - frameHeader.Size = UDim2.new(1,-55, 0, 22) - frameHeader.Position = UDim2.new(0,0,0,0) - frameHeader.Parent = frame - - local skipButton = Instance.new("ImageButton") - skipButton.Name = "SkipButton" - skipButton.AutoButtonColor = false - skipButton.BackgroundTransparency = 1 - skipButton.Image = "rbxasset://textures/ui/closeButton.png" - skipButton.MouseButton1Click:connect(function() - skipTutorial() - end) - skipButton.MouseEnter:connect(function() - skipButton.Image = "rbxasset://textures/ui/closeButton_dn.png" - end) - skipButton.MouseLeave:connect(function() - skipButton.Image = "rbxasset://textures/ui/closeButton.png" - end) - skipButton.Size = UDim2.new(0, 25, 0, 25) - skipButton.Position = UDim2.new(1, -25, 0, 0) - skipButton.Parent = frame - - - if giveDoneButton then - local doneButton = Instance.new("TextButton") - doneButton.Name = "DoneButton" - doneButton.Style = Enum.ButtonStyle.RobloxButtonDefault - doneButton.Text = "Done" - doneButton.TextColor3 = Color3.new(1,1,1) - doneButton.Font = Enum.Font.ArialBold - doneButton.FontSize = Enum.FontSize.Size18 - doneButton.Size = UDim2.new(0,100,0,50) - doneButton.Position = UDim2.new(0.5,-50,1,-50) - - if skipTutorial then - doneButton.MouseButton1Click:connect(function() skipTutorial() end) - end - - doneButton.Parent = frame - end - - local innerFrame = Instance.new("Frame") - innerFrame.Name = "ContentFrame" - innerFrame.BackgroundTransparency = 1 - innerFrame.Position = UDim2.new(0,0,0,25) - innerFrame.Parent = frame - - local nextButton = Instance.new("TextButton") - nextButton.Name = "NextButton" - nextButton.Text = "Next" - nextButton.TextColor3 = Color3.new(1,1,1) - nextButton.Font = Enum.Font.Arial - nextButton.FontSize = Enum.FontSize.Size18 - nextButton.Style = Enum.ButtonStyle.RobloxButtonDefault - nextButton.Size = UDim2.new(0,80, 0, 32) - nextButton.Position = UDim2.new(0.5, 5, 1, -32) - nextButton.Active = false - nextButton.Visible = false - nextButton.Parent = frame - - local prevButton = Instance.new("TextButton") - prevButton.Name = "PrevButton" - prevButton.Text = "Previous" - prevButton.TextColor3 = Color3.new(1,1,1) - prevButton.Font = Enum.Font.Arial - prevButton.FontSize = Enum.FontSize.Size18 - prevButton.Style = Enum.ButtonStyle.RobloxButton - prevButton.Size = UDim2.new(0,80, 0, 32) - prevButton.Position = UDim2.new(0.5, -85, 1, -32) - prevButton.Active = false - prevButton.Visible = false - prevButton.Parent = frame - - if giveDoneButton then - innerFrame.Size = UDim2.new(1,0,1,-75) - else - innerFrame.Size = UDim2.new(1,0,1,-22) - end - - local parentConnection = nil - - local function basicHandleResize() - if frame.Visible and frame.Parent then - local maxSize = math.min(frame.Parent.AbsoluteSize.X, frame.Parent.AbsoluteSize.Y) - handleResize(200,maxSize) - end - end - - frame.Changed:connect( - function(prop) - if prop == "Parent" then - if parentConnection ~= nil then - parentConnection:disconnect() - parentConnection = nil - end - if frame.Parent and frame.Parent:IsA("GuiObject") then - parentConnection = frame.Parent.Changed:connect( - function(parentProp) - if parentProp == "AbsoluteSize" then - wait() - basicHandleResize() - end - end) - basicHandleResize() - end - end - - if prop == "Visible" then - basicHandleResize() - end - end) - - return frame, innerFrame -end - -t.CreateTextTutorialPage = function(name, text, skipTutorialFunc) - local frame = nil - local contentFrame = nil - - local textLabel = Instance.new("TextLabel") - textLabel.BackgroundTransparency = 1 - textLabel.TextColor3 = Color3.new(1,1,1) - textLabel.Text = text - textLabel.TextWrap = true - textLabel.TextXAlignment = Enum.TextXAlignment.Left - textLabel.TextYAlignment = Enum.TextYAlignment.Center - textLabel.Font = Enum.Font.Arial - textLabel.FontSize = Enum.FontSize.Size14 - textLabel.Size = UDim2.new(1,0,1,0) - - local function handleResize(minSize, maxSize) - size = binaryShrink(minSize, maxSize, - function(size) - frame.Size = UDim2.new(0, size, 0, size) - return textLabel.TextFits - end) - frame.Size = UDim2.new(0, size, 0, size) - frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2) - end - - frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc) - textLabel.Parent = contentFrame - - return frame -end - -t.CreateImageTutorialPage = function(name, imageAsset, x, y, skipTutorialFunc, giveDoneButton) - local frame = nil - local contentFrame = nil - - local imageLabel = Instance.new("ImageLabel") - imageLabel.BackgroundTransparency = 1 - imageLabel.Image = imageAsset - imageLabel.Size = UDim2.new(0,x,0,y) - imageLabel.Position = UDim2.new(0.5,-x/2,0.5,-y/2) - - local function handleResize(minSize, maxSize) - size = binaryShrink(minSize, maxSize, - function(size) - return size >= x and size >= y - end) - if size >= x and size >= y then - imageLabel.Size = UDim2.new(0,x, 0,y) - imageLabel.Position = UDim2.new(0.5,-x/2, 0.5, -y/2) - else - if x > y then - --X is limiter, so - imageLabel.Size = UDim2.new(1,0,y/x,0) - imageLabel.Position = UDim2.new(0,0, 0.5 - (y/x)/2, 0) - else - --Y is limiter - imageLabel.Size = UDim2.new(x/y,0,1, 0) - imageLabel.Position = UDim2.new(0.5-(x/y)/2, 0, 0, 0) - end - end - size = size + 50 - frame.Size = UDim2.new(0, size, 0, size) - frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2) - end - - frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc, giveDoneButton) - imageLabel.Parent = contentFrame - - return frame -end - -t.AddTutorialPage = function(tutorial, tutorialPage) - local transitionFrame = tutorial.TransitionFrame - local currentPageValue = tutorial.CurrentTutorialPage - - if not tutorial.Buttons.Value then - tutorialPage.NextButton.Parent = nil - tutorialPage.PrevButton.Parent = nil - end - - local children = tutorial.Pages:GetChildren() - if children and #children > 0 then - tutorialPage.Name = "TutorialPage" .. (#children+1) - local previousPage = children[#children] - if not previousPage:IsA("GuiObject") then - error("All elements under Pages must be GuiObjects") - end - - if tutorial.Buttons.Value then - if previousPage.NextButton.Active then - error("NextButton already Active on previousPage, please only add pages with RbxGui.AddTutorialPage function") - end - previousPage.NextButton.MouseButton1Click:connect( - function() - TransitionTutorialPages(previousPage, tutorialPage, transitionFrame, currentPageValue) - end) - previousPage.NextButton.Active = true - previousPage.NextButton.Visible = true - - if tutorialPage.PrevButton.Active then - error("PrevButton already Active on tutorialPage, please only add pages with RbxGui.AddTutorialPage function") - end - tutorialPage.PrevButton.MouseButton1Click:connect( - function() - TransitionTutorialPages(tutorialPage, previousPage, transitionFrame, currentPageValue) - end) - tutorialPage.PrevButton.Active = true - tutorialPage.PrevButton.Visible = true - end - - tutorialPage.Parent = tutorial.Pages - else - --First child - tutorialPage.Name = "TutorialPage1" - tutorialPage.Parent = tutorial.Pages - end -end - -t.CreateSetPanel = function(userIdsForSets, objectSelected, dialogClosed, size, position, showAdminCategories, useAssetVersionId) - - if not userIdsForSets then - error("CreateSetPanel: userIdsForSets (first arg) is nil, should be a table of number ids") - end - if type(userIdsForSets) ~= "table" and type(userIdsForSets) ~= "userdata" then - error("CreateSetPanel: userIdsForSets (first arg) is of type " ..type(userIdsForSets) .. ", should be of type table or userdata") - end - if not objectSelected then - error("CreateSetPanel: objectSelected (second arg) is nil, should be a callback function!") - end - if type(objectSelected) ~= "function" then - error("CreateSetPanel: objectSelected (second arg) is of type " .. type(objectSelected) .. ", should be of type function!") - end - if dialogClosed and type(dialogClosed) ~= "function" then - error("CreateSetPanel: dialogClosed (third arg) is of type " .. type(dialogClosed) .. ", should be of type function!") - end - - if showAdminCategories == nil then -- by default, don't show beta sets - showAdminCategories = false - end - - local arrayPosition = 1 - local insertButtons = {} - local insertButtonCons = {} - local contents = nil - local setGui = nil - - -- used for water selections - local waterForceDirection = "NegX" - local waterForce = "None" - local waterGui, waterTypeChangedEvent = nil - - local Data = {} - Data.CurrentCategory = nil - Data.Category = {} - local SetCache = {} - - local userCategoryButtons = nil - - local buttonWidth = 64 - local buttonHeight = buttonWidth - - local SmallThumbnailUrl = nil - local LargeThumbnailUrl = nil - local BaseUrl = game:GetService("ContentProvider").BaseUrl:lower() - - if useAssetVersionId then - LargeThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&assetversionid=" - SmallThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&assetversionid=" - else - LargeThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&aid=" - SmallThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&aid=" - end - - local function drillDownSetZIndex(parent, index) - local children = parent:GetChildren() - for i = 1, #children do - if children[i]:IsA("GuiObject") then - children[i].ZIndex = index - end - drillDownSetZIndex(children[i], index) - end - end - - -- for terrain stamping - local currTerrainDropDownFrame = nil - local terrainShapes = {"Block","Vertical Ramp","Corner Wedge","Inverse Corner Wedge","Horizontal Ramp","Auto-Wedge"} - local terrainShapeMap = {} - for i = 1, #terrainShapes do - terrainShapeMap[terrainShapes[i]] = i - 1 - end - terrainShapeMap[terrainShapes[#terrainShapes]] = 6 - - local function createWaterGui() - local waterForceDirections = {"NegX","X","NegY","Y","NegZ","Z"} - local waterForces = {"None", "Small", "Medium", "Strong", "Max"} - - local waterFrame = Instance.new("Frame") - waterFrame.Name = "WaterFrame" - waterFrame.Style = Enum.FrameStyle.RobloxSquare - waterFrame.Size = UDim2.new(0,150,0,110) - waterFrame.Visible = false - - local waterForceLabel = Instance.new("TextLabel") - waterForceLabel.Name = "WaterForceLabel" - waterForceLabel.BackgroundTransparency = 1 - waterForceLabel.Size = UDim2.new(1,0,0,12) - waterForceLabel.Font = Enum.Font.ArialBold - waterForceLabel.FontSize = Enum.FontSize.Size12 - waterForceLabel.TextColor3 = Color3.new(1,1,1) - waterForceLabel.TextXAlignment = Enum.TextXAlignment.Left - waterForceLabel.Text = "Water Force" - waterForceLabel.Parent = waterFrame - - local waterForceDirLabel = waterForceLabel:Clone() - waterForceDirLabel.Name = "WaterForceDirectionLabel" - waterForceDirLabel.Text = "Water Force Direction" - waterForceDirLabel.Position = UDim2.new(0,0,0,50) - waterForceDirLabel.Parent = waterFrame - - local waterTypeChangedEvent = Instance.new("BindableEvent",waterFrame) - waterTypeChangedEvent.Name = "WaterTypeChangedEvent" - - local waterForceDirectionSelectedFunc = function(newForceDirection) - waterForceDirection = newForceDirection - waterTypeChangedEvent:Fire({waterForce, waterForceDirection}) - end - local waterForceSelectedFunc = function(newForce) - waterForce = newForce - waterTypeChangedEvent:Fire({waterForce, waterForceDirection}) - end - - local waterForceDirectionDropDown, forceWaterDirectionSelection = t.CreateDropDownMenu(waterForceDirections, waterForceDirectionSelectedFunc) - waterForceDirectionDropDown.Size = UDim2.new(1,0,0,25) - waterForceDirectionDropDown.Position = UDim2.new(0,0,1,3) - forceWaterDirectionSelection("NegX") - waterForceDirectionDropDown.Parent = waterForceDirLabel - - local waterForceDropDown, forceWaterForceSelection = t.CreateDropDownMenu(waterForces, waterForceSelectedFunc) - forceWaterForceSelection("None") - waterForceDropDown.Size = UDim2.new(1,0,0,25) - waterForceDropDown.Position = UDim2.new(0,0,1,3) - waterForceDropDown.Parent = waterForceLabel - - return waterFrame, waterTypeChangedEvent - end - - -- Helper Function that contructs gui elements - local function createSetGui() - - local setGui = Instance.new("ScreenGui") - setGui.Name = "SetGui" - - local setPanel = Instance.new("Frame") - setPanel.Name = "SetPanel" - setPanel.Active = true - setPanel.BackgroundTransparency = 1 - if position then - setPanel.Position = position - else - setPanel.Position = UDim2.new(0.2, 29, 0.1, 24) - end - if size then - setPanel.Size = size - else - setPanel.Size = UDim2.new(0.6, -58, 0.64, 0) - end - setPanel.Style = Enum.FrameStyle.RobloxRound - setPanel.ZIndex = 6 - setPanel.Parent = setGui - - -- Children of SetPanel - local itemPreview = Instance.new("Frame") - itemPreview.Name = "ItemPreview" - itemPreview.BackgroundTransparency = 1 - itemPreview.Position = UDim2.new(0.8,5,0.085,0) - itemPreview.Size = UDim2.new(0.21,0,0.9,0) - itemPreview.ZIndex = 6 - itemPreview.Parent = setPanel - - -- Children of ItemPreview - local textPanel = Instance.new("Frame") - textPanel.Name = "TextPanel" - textPanel.BackgroundTransparency = 1 - textPanel.Position = UDim2.new(0,0,0.45,0) - textPanel.Size = UDim2.new(1,0,0.55,0) - textPanel.ZIndex = 6 - textPanel.Parent = itemPreview - - -- Children of TextPanel - local rolloverText = Instance.new("TextLabel") - rolloverText.Name = "RolloverText" - rolloverText.BackgroundTransparency = 1 - rolloverText.Size = UDim2.new(1,0,0,48) - rolloverText.ZIndex = 6 - rolloverText.Font = Enum.Font.ArialBold - rolloverText.FontSize = Enum.FontSize.Size24 - rolloverText.Text = "" - rolloverText.TextColor3 = Color3.new(1,1,1) - rolloverText.TextWrap = true - rolloverText.TextXAlignment = Enum.TextXAlignment.Left - rolloverText.TextYAlignment = Enum.TextYAlignment.Top - rolloverText.Parent = textPanel - - local largePreview = Instance.new("ImageLabel") - largePreview.Name = "LargePreview" - largePreview.BackgroundTransparency = 1 - largePreview.Image = "" - largePreview.Size = UDim2.new(1,0,0,170) - largePreview.ZIndex = 6 - largePreview.Parent = itemPreview - - local sets = Instance.new("Frame") - sets.Name = "Sets" - sets.BackgroundTransparency = 1 - sets.Position = UDim2.new(0,0,0,5) - sets.Size = UDim2.new(0.23,0,1,-5) - sets.ZIndex = 6 - sets.Parent = setPanel - - -- Children of Sets - local line = Instance.new("Frame") - line.Name = "Line" - line.BackgroundColor3 = Color3.new(1,1,1) - line.BackgroundTransparency = 0.7 - line.BorderSizePixel = 0 - line.Position = UDim2.new(1,-3,0.06,0) - line.Size = UDim2.new(0,3,0.9,0) - line.ZIndex = 6 - line.Parent = sets - - local setsLists, controlFrame = t.CreateTrueScrollingFrame() - setsLists.Size = UDim2.new(1,-6,0.94,0) - setsLists.Position = UDim2.new(0,0,0.06,0) - setsLists.BackgroundTransparency = 1 - setsLists.Name = "SetsLists" - setsLists.ZIndex = 6 - setsLists.Parent = sets - drillDownSetZIndex(controlFrame, 7) - - local setsHeader = Instance.new("TextLabel") - setsHeader.Name = "SetsHeader" - setsHeader.BackgroundTransparency = 1 - setsHeader.Size = UDim2.new(0,47,0,24) - setsHeader.ZIndex = 6 - setsHeader.Font = Enum.Font.ArialBold - setsHeader.FontSize = Enum.FontSize.Size24 - setsHeader.Text = "Sets" - setsHeader.TextColor3 = Color3.new(1,1,1) - setsHeader.TextXAlignment = Enum.TextXAlignment.Left - setsHeader.TextYAlignment = Enum.TextYAlignment.Top - setsHeader.Parent = sets - - local cancelButton = Instance.new("TextButton") - cancelButton.Name = "CancelButton" - cancelButton.Position = UDim2.new(1,-32,0,-2) - cancelButton.Size = UDim2.new(0,34,0,34) - cancelButton.Style = Enum.ButtonStyle.RobloxButtonDefault - cancelButton.ZIndex = 6 - cancelButton.Text = "" - cancelButton.Modal = true - cancelButton.Parent = setPanel - - -- Children of Cancel Button - local cancelImage = Instance.new("ImageLabel") - cancelImage.Name = "CancelImage" - cancelImage.BackgroundTransparency = 1 - cancelImage.Image = "http://www.roblox.com/asset/?id=54135717" - cancelImage.Position = UDim2.new(0,-2,0,-2) - cancelImage.Size = UDim2.new(0,16,0,16) - cancelImage.ZIndex = 6 - cancelImage.Parent = cancelButton - - return setGui - end - - local function createSetButton(text) - local setButton = Instance.new("TextButton") - - if text then setButton.Text = text - else setButton.Text = "" end - - setButton.AutoButtonColor = false - setButton.BackgroundTransparency = 1 - setButton.BackgroundColor3 = Color3.new(1,1,1) - setButton.BorderSizePixel = 0 - setButton.Size = UDim2.new(1,-5,0,18) - setButton.ZIndex = 6 - setButton.Visible = false - setButton.Font = Enum.Font.Arial - setButton.FontSize = Enum.FontSize.Size18 - setButton.TextColor3 = Color3.new(1,1,1) - setButton.TextXAlignment = Enum.TextXAlignment.Left - - return setButton - end - - local function buildSetButton(name, setId, setImageId, i, count) - local button = createSetButton(name) - button.Text = name - button.Name = "SetButton" - button.Visible = true - - local setValue = Instance.new("IntValue") - setValue.Name = "SetId" - setValue.Value = setId - setValue.Parent = button - - local setName = Instance.new("StringValue") - setName.Name = "SetName" - setName.Value = name - setName.Parent = button - - return button - end - - local function processCategory(sets) - local setButtons = {} - local numSkipped = 0 - for i = 1, #sets do - if not showAdminCategories and sets[i].Name == "Beta" then - numSkipped = numSkipped + 1 - else - setButtons[i - numSkipped] = buildSetButton(sets[i].Name, sets[i].CategoryId, sets[i].ImageAssetId, i - numSkipped, #sets) - end - end - return setButtons - end - - local function handleResize() - wait() -- neccessary to insure heartbeat happened - - local itemPreview = setGui.SetPanel.ItemPreview - - itemPreview.LargePreview.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.X) - itemPreview.LargePreview.Position = UDim2.new(0.5,-itemPreview.LargePreview.AbsoluteSize.X/2,0,0) - itemPreview.TextPanel.Position = UDim2.new(0,0,0,itemPreview.LargePreview.AbsoluteSize.Y) - itemPreview.TextPanel.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.Y - itemPreview.LargePreview.AbsoluteSize.Y) - end - - local function makeInsertAssetButton() - local insertAssetButtonExample = Instance.new("Frame") - insertAssetButtonExample.Name = "InsertAssetButtonExample" - insertAssetButtonExample.Position = UDim2.new(0,128,0,64) - insertAssetButtonExample.Size = UDim2.new(0,64,0,64) - insertAssetButtonExample.BackgroundTransparency = 1 - insertAssetButtonExample.ZIndex = 6 - insertAssetButtonExample.Visible = false - - local assetId = Instance.new("IntValue") - assetId.Name = "AssetId" - assetId.Value = 0 - assetId.Parent = insertAssetButtonExample - - local assetName = Instance.new("StringValue") - assetName.Name = "AssetName" - assetName.Value = "" - assetName.Parent = insertAssetButtonExample - - local button = Instance.new("TextButton") - button.Name = "Button" - button.Text = "" - button.Style = Enum.ButtonStyle.RobloxButton - button.Position = UDim2.new(0.025,0,0.025,0) - button.Size = UDim2.new(0.95,0,0.95,0) - button.ZIndex = 6 - button.Parent = insertAssetButtonExample - - local buttonImage = Instance.new("ImageLabel") - buttonImage.Name = "ButtonImage" - buttonImage.Image = "" - buttonImage.Position = UDim2.new(0,-7,0,-7) - buttonImage.Size = UDim2.new(1,14,1,14) - buttonImage.BackgroundTransparency = 1 - buttonImage.ZIndex = 7 - buttonImage.Parent = button - - local configIcon = buttonImage:clone() - configIcon.Name = "ConfigIcon" - configIcon.Visible = false - configIcon.Position = UDim2.new(1,-23,1,-24) - configIcon.Size = UDim2.new(0,16,0,16) - configIcon.Image = "" - configIcon.ZIndex = 6 - configIcon.Parent = insertAssetButtonExample - - return insertAssetButtonExample - end - - local function showLargePreview(insertButton) - if insertButton:FindFirstChild("AssetId") then - delay(0,function() - game:GetService("ContentProvider"):Preload(LargeThumbnailUrl .. tostring(insertButton.AssetId.Value)) - setGui.SetPanel.ItemPreview.LargePreview.Image = LargeThumbnailUrl .. tostring(insertButton.AssetId.Value) - end) - end - if insertButton:FindFirstChild("AssetName") then - setGui.SetPanel.ItemPreview.TextPanel.RolloverText.Text = insertButton.AssetName.Value - end - end - - local function selectTerrainShape(shape) - if currTerrainDropDownFrame then - objectSelected(tostring(currTerrainDropDownFrame.AssetName.Value), tonumber(currTerrainDropDownFrame.AssetId.Value), shape) - end - end - - local function createTerrainTypeButton(name, parent) - local dropDownTextButton = Instance.new("TextButton") - dropDownTextButton.Name = name .. "Button" - dropDownTextButton.Font = Enum.Font.ArialBold - dropDownTextButton.FontSize = Enum.FontSize.Size14 - dropDownTextButton.BorderSizePixel = 0 - dropDownTextButton.TextColor3 = Color3.new(1,1,1) - dropDownTextButton.Text = name - dropDownTextButton.TextXAlignment = Enum.TextXAlignment.Left - dropDownTextButton.BackgroundTransparency = 1 - dropDownTextButton.ZIndex = parent.ZIndex + 1 - dropDownTextButton.Size = UDim2.new(0,parent.Size.X.Offset - 2,0,16) - dropDownTextButton.Position = UDim2.new(0,1,0,0) - - dropDownTextButton.MouseEnter:connect(function() - dropDownTextButton.BackgroundTransparency = 0 - dropDownTextButton.TextColor3 = Color3.new(0,0,0) - end) - - dropDownTextButton.MouseLeave:connect(function() - dropDownTextButton.BackgroundTransparency = 1 - dropDownTextButton.TextColor3 = Color3.new(1,1,1) - end) - - dropDownTextButton.MouseButton1Click:connect(function() - dropDownTextButton.BackgroundTransparency = 1 - dropDownTextButton.TextColor3 = Color3.new(1,1,1) - if dropDownTextButton.Parent and dropDownTextButton.Parent:IsA("GuiObject") then - dropDownTextButton.Parent.Visible = false - end - selectTerrainShape(terrainShapeMap[dropDownTextButton.Text]) - end) - - return dropDownTextButton - end - - local function createTerrainDropDownMenu(zIndex) - local dropDown = Instance.new("Frame") - dropDown.Name = "TerrainDropDown" - dropDown.BackgroundColor3 = Color3.new(0,0,0) - dropDown.BorderColor3 = Color3.new(1,0,0) - dropDown.Size = UDim2.new(0,200,0,0) - dropDown.Visible = false - dropDown.ZIndex = zIndex - dropDown.Parent = setGui - - for i = 1, #terrainShapes do - local shapeButton = createTerrainTypeButton(terrainShapes[i],dropDown) - shapeButton.Position = UDim2.new(0,1,0,(i - 1) * (shapeButton.Size.Y.Offset)) - shapeButton.Parent = dropDown - dropDown.Size = UDim2.new(0,200,0,dropDown.Size.Y.Offset + (shapeButton.Size.Y.Offset)) - end - - dropDown.MouseLeave:connect(function() - dropDown.Visible = false - end) - end - - - local function createDropDownMenuButton(parent) - local dropDownButton = Instance.new("ImageButton") - dropDownButton.Name = "DropDownButton" - dropDownButton.Image = "http://www.roblox.com/asset/?id=67581509" - dropDownButton.BackgroundTransparency = 1 - dropDownButton.Size = UDim2.new(0,16,0,16) - dropDownButton.Position = UDim2.new(1,-24,0,6) - dropDownButton.ZIndex = parent.ZIndex + 2 - dropDownButton.Parent = parent - - if not setGui:FindFirstChild("TerrainDropDown") then - createTerrainDropDownMenu(8) - end - - dropDownButton.MouseButton1Click:connect(function() - setGui.TerrainDropDown.Visible = true - setGui.TerrainDropDown.Position = UDim2.new(0,parent.AbsolutePosition.X,0,parent.AbsolutePosition.Y) - currTerrainDropDownFrame = parent - end) - end - - local function buildInsertButton() - local insertButton = makeInsertAssetButton() - insertButton.Name = "InsertAssetButton" - insertButton.Visible = true - - if Data.Category[Data.CurrentCategory].SetName == "High Scalability" then - createDropDownMenuButton(insertButton) - end - - local lastEnter = nil - local mouseEnterCon = insertButton.MouseEnter:connect(function() - lastEnter = insertButton - delay(0.1,function() - if lastEnter == insertButton then - showLargePreview(insertButton) - end - end) - end) - return insertButton, mouseEnterCon - end - - local function realignButtonGrid(columns) - local x = 0 - local y = 0 - for i = 1, #insertButtons do - insertButtons[i].Position = UDim2.new(0, buttonWidth * x, 0, buttonHeight * y) - x = x + 1 - if x >= columns then - x = 0 - y = y + 1 - end - end - end - - local function setInsertButtonImageBehavior(insertFrame, visible, name, assetId) - if visible then - insertFrame.AssetName.Value = name - insertFrame.AssetId.Value = assetId - local newImageUrl = SmallThumbnailUrl .. assetId - if newImageUrl ~= insertFrame.Button.ButtonImage.Image then - delay(0,function() - game:GetService("ContentProvider"):Preload(SmallThumbnailUrl .. assetId) - if insertFrame:findFirstChild("Button") then - insertFrame.Button.ButtonImage.Image = SmallThumbnailUrl .. assetId - end - end) - end - table.insert(insertButtonCons, - insertFrame.Button.MouseButton1Click:connect(function() - -- special case for water, show water selection gui - local isWaterSelected = (name == "Water") and (Data.Category[Data.CurrentCategory].SetName == "High Scalability") - waterGui.Visible = isWaterSelected - if isWaterSelected then - objectSelected(name, tonumber(assetId), nil) - else - objectSelected(name, tonumber(assetId)) - end - end) - ) - insertFrame.Visible = true - else - insertFrame.Visible = false - end - end - - local function loadSectionOfItems(setGui, rows, columns) - local pageSize = rows * columns - - if arrayPosition > #contents then return end - - local origArrayPos = arrayPosition - - local yCopy = 0 - for i = 1, pageSize + 1 do - if arrayPosition >= #contents + 1 then - break - end - - local buttonCon - insertButtons[arrayPosition], buttonCon = buildInsertButton() - table.insert(insertButtonCons,buttonCon) - insertButtons[arrayPosition].Parent = setGui.SetPanel.ItemsFrame - arrayPosition = arrayPosition + 1 - end - realignButtonGrid(columns) - - local indexCopy = origArrayPos - for index = origArrayPos, arrayPosition do - if insertButtons[index] then - if contents[index] then - - -- we don't want water to have a drop down button - if contents[index].Name == "Water" then - if Data.Category[Data.CurrentCategory].SetName == "High Scalability" then - insertButtons[index]:FindFirstChild("DropDownButton",true):Destroy() - end - end - - local assetId - if useAssetVersionId then - assetId = contents[index].AssetVersionId - else - assetId = contents[index].AssetId - end - setInsertButtonImageBehavior(insertButtons[index], true, contents[index].Name, assetId) - else - break - end - else - break - end - indexCopy = index - end - end - - local function setSetIndex() - Data.Category[Data.CurrentCategory].Index = 0 - - rows = 7 - columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth) - - contents = Data.Category[Data.CurrentCategory].Contents - if contents then - -- remove our buttons and their connections - for i = 1, #insertButtons do - insertButtons[i]:remove() - end - for i = 1, #insertButtonCons do - if insertButtonCons[i] then insertButtonCons[i]:disconnect() end - end - insertButtonCons = {} - insertButtons = {} - - arrayPosition = 1 - loadSectionOfItems(setGui, rows, columns) - end - end - - local function selectSet(button, setName, setId, setIndex) - if button and Data.Category[Data.CurrentCategory] ~= nil then - if button ~= Data.Category[Data.CurrentCategory].Button then - Data.Category[Data.CurrentCategory].Button = button - - if SetCache[setId] == nil then - SetCache[setId] = game:GetService("InsertService"):GetCollection(setId) - end - Data.Category[Data.CurrentCategory].Contents = SetCache[setId] - - Data.Category[Data.CurrentCategory].SetName = setName - Data.Category[Data.CurrentCategory].SetId = setId - end - setSetIndex() - end - end - - local function selectCategoryPage(buttons, page) - if buttons ~= Data.CurrentCategory then - if Data.CurrentCategory then - for key, button in pairs(Data.CurrentCategory) do - button.Visible = false - end - end - - Data.CurrentCategory = buttons - if Data.Category[Data.CurrentCategory] == nil then - Data.Category[Data.CurrentCategory] = {} - if #buttons > 0 then - selectSet(buttons[1], buttons[1].SetName.Value, buttons[1].SetId.Value, 0) - end - else - Data.Category[Data.CurrentCategory].Button = nil - selectSet(Data.Category[Data.CurrentCategory].ButtonFrame, Data.Category[Data.CurrentCategory].SetName, Data.Category[Data.CurrentCategory].SetId, Data.Category[Data.CurrentCategory].Index) - end - end - end - - local function selectCategory(category) - selectCategoryPage(category, 0) - end - - local function resetAllSetButtonSelection() - local setButtons = setGui.SetPanel.Sets.SetsLists:GetChildren() - for i = 1, #setButtons do - if setButtons[i]:IsA("TextButton") then - setButtons[i].Selected = false - setButtons[i].BackgroundTransparency = 1 - setButtons[i].TextColor3 = Color3.new(1,1,1) - setButtons[i].BackgroundColor3 = Color3.new(1,1,1) - end - end - end - - local function populateSetsFrame() - local currRow = 0 - for i = 1, #userCategoryButtons do - local button = userCategoryButtons[i] - button.Visible = true - button.Position = UDim2.new(0,5,0,currRow * button.Size.Y.Offset) - button.Parent = setGui.SetPanel.Sets.SetsLists - - if i == 1 then -- we will have this selected by default, so show it - button.Selected = true - button.BackgroundColor3 = Color3.new(0,204/255,0) - button.TextColor3 = Color3.new(0,0,0) - button.BackgroundTransparency = 0 - end - - button.MouseEnter:connect(function() - if not button.Selected then - button.BackgroundTransparency = 0 - button.TextColor3 = Color3.new(0,0,0) - end - end) - button.MouseLeave:connect(function() - if not button.Selected then - button.BackgroundTransparency = 1 - button.TextColor3 = Color3.new(1,1,1) - end - end) - button.MouseButton1Click:connect(function() - resetAllSetButtonSelection() - button.Selected = not button.Selected - button.BackgroundColor3 = Color3.new(0,204/255,0) - button.TextColor3 = Color3.new(0,0,0) - button.BackgroundTransparency = 0 - selectSet(button, button.Text, userCategoryButtons[i].SetId.Value, 0) - end) - - currRow = currRow + 1 - end - - local buttons = setGui.SetPanel.Sets.SetsLists:GetChildren() - - -- set first category as loaded for default - if buttons then - for i = 1, #buttons do - if buttons[i]:IsA("TextButton") then - selectSet(buttons[i], buttons[i].Text, userCategoryButtons[i].SetId.Value, 0) - selectCategory(userCategoryButtons) - break - end - end - end - end - - setGui = createSetGui() - waterGui, waterTypeChangedEvent = createWaterGui() - waterGui.Position = UDim2.new(0,55,0,0) - waterGui.Parent = setGui - setGui.Changed:connect(function(prop) -- this resizes the preview image to always be the right size - if prop == "AbsoluteSize" then - handleResize() - setSetIndex() - end - end) - - local scrollFrame, controlFrame = t.CreateTrueScrollingFrame() - scrollFrame.Size = UDim2.new(0.54,0,0.85,0) - scrollFrame.Position = UDim2.new(0.24,0,0.085,0) - scrollFrame.Name = "ItemsFrame" - scrollFrame.ZIndex = 6 - scrollFrame.Parent = setGui.SetPanel - scrollFrame.BackgroundTransparency = 1 - - drillDownSetZIndex(controlFrame,7) - - controlFrame.Parent = setGui.SetPanel - controlFrame.Position = UDim2.new(0.76, 5, 0, 0) - - local debounce = false - controlFrame.ScrollBottom.Changed:connect(function(prop) - if controlFrame.ScrollBottom.Value == true then - if debounce then return end - debounce = true - loadSectionOfItems(setGui, rows, columns) - debounce = false - end - end) - - local userData = {} - for id = 1, #userIdsForSets do - local newUserData = game:GetService("InsertService"):GetUserSets(userIdsForSets[id]) - if newUserData and #newUserData > 2 then - -- start at #3 to skip over My Decals and My Models for each account - for category = 3, #newUserData do - if newUserData[category].Name == "High Scalability" then -- we want high scalability parts to show first - table.insert(userData,1,newUserData[category]) - else - table.insert(userData, newUserData[category]) - end - end - end - - end - if userData then - userCategoryButtons = processCategory(userData) - end - - rows = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.Y/buttonHeight) - columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth) - - populateSetsFrame() - - insertPanelCloseCon = setGui.SetPanel.CancelButton.MouseButton1Click:connect(function() - setGui.SetPanel.Visible = false - if dialogClosed then dialogClosed() end - end) - - local setVisibilityFunction = function(visible) - if visible then - setGui.SetPanel.Visible = true - else - setGui.SetPanel.Visible = false - end - end - - local getVisibilityFunction = function() - if setGui then - if setGui:FindFirstChild("SetPanel") then - return setGui.SetPanel.Visible - end - end - - return false - end - - return setGui, setVisibilityFunction, getVisibilityFunction, waterTypeChangedEvent -end - -t.CreateTerrainMaterialSelector = function(size,position) - local terrainMaterialSelectionChanged = Instance.new("BindableEvent") - terrainMaterialSelectionChanged.Name = "TerrainMaterialSelectionChanged" - - local selectedButton = nil - - local frame = Instance.new("Frame") - frame.Name = "TerrainMaterialSelector" - if size then - frame.Size = size - else - frame.Size = UDim2.new(0, 245, 0, 230) - end - if position then - frame.Position = position - end - frame.BorderSizePixel = 0 - frame.BackgroundColor3 = Color3.new(0,0,0) - frame.Active = true - - terrainMaterialSelectionChanged.Parent = frame - - local waterEnabled = true -- todo: turn this on when water is ready - - local materialToImageMap = {} - local materialNames = {"Grass", "Sand", "Brick", "Granite", "Asphalt", "Iron", "Aluminum", "Gold", "Plank", "Log", "Gravel", "Cinder Block", "Stone Wall", "Concrete", "Plastic (red)", "Plastic (blue)"} - if waterEnabled then - table.insert(materialNames,"Water") - end - local currentMaterial = 1 - - function getEnumFromName(choice) - if choice == "Grass" then return 1 end - if choice == "Sand" then return 2 end - if choice == "Erase" then return 0 end - if choice == "Brick" then return 3 end - if choice == "Granite" then return 4 end - if choice == "Asphalt" then return 5 end - if choice == "Iron" then return 6 end - if choice == "Aluminum" then return 7 end - if choice == "Gold" then return 8 end - if choice == "Plank" then return 9 end - if choice == "Log" then return 10 end - if choice == "Gravel" then return 11 end - if choice == "Cinder Block" then return 12 end - if choice == "Stone Wall" then return 13 end - if choice == "Concrete" then return 14 end - if choice == "Plastic (red)" then return 15 end - if choice == "Plastic (blue)" then return 16 end - if choice == "Water" then return 17 end - end - - function getNameFromEnum(choice) - if choice == Enum.CellMaterial.Grass or choice == 1 then return "Grass"end - if choice == Enum.CellMaterial.Sand or choice == 2 then return "Sand" end - if choice == Enum.CellMaterial.Empty or choice == 0 then return "Erase" end - if choice == Enum.CellMaterial.Brick or choice == 3 then return "Brick" end - if choice == Enum.CellMaterial.Granite or choice == 4 then return "Granite" end - if choice == Enum.CellMaterial.Asphalt or choice == 5 then return "Asphalt" end - if choice == Enum.CellMaterial.Iron or choice == 6 then return "Iron" end - if choice == Enum.CellMaterial.Aluminum or choice == 7 then return "Aluminum" end - if choice == Enum.CellMaterial.Gold or choice == 8 then return "Gold" end - if choice == Enum.CellMaterial.WoodPlank or choice == 9 then return "Plank" end - if choice == Enum.CellMaterial.WoodLog or choice == 10 then return "Log" end - if choice == Enum.CellMaterial.Gravel or choice == 11 then return "Gravel" end - if choice == Enum.CellMaterial.CinderBlock or choice == 12 then return "Cinder Block" end - if choice == Enum.CellMaterial.MossyStone or choice == 13 then return "Stone Wall" end - if choice == Enum.CellMaterial.Cement or choice == 14 then return "Concrete" end - if choice == Enum.CellMaterial.RedPlastic or choice == 15 then return "Plastic (red)" end - if choice == Enum.CellMaterial.BluePlastic or choice == 16 then return "Plastic (blue)" end - - if waterEnabled then - if choice == Enum.CellMaterial.Water or choice == 17 then return "Water" end - end - end - - - local function updateMaterialChoice(choice) - currentMaterial = getEnumFromName(choice) - terrainMaterialSelectionChanged:Fire(currentMaterial) - end - - -- we so need a better way to do this - for i,v in pairs(materialNames) do - materialToImageMap[v] = {} - if v == "Grass" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=56563112" - elseif v == "Sand" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=62356652" - elseif v == "Brick" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=65961537" - elseif v == "Granite" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532153" - elseif v == "Asphalt" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532038" - elseif v == "Iron" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532093" - elseif v == "Aluminum" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531995" - elseif v == "Gold" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532118" - elseif v == "Plastic (red)" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531848" - elseif v == "Plastic (blue)" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531924" - elseif v == "Plank" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532015" - elseif v == "Log" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532051" - elseif v == "Gravel" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532206" - elseif v == "Cinder Block" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532103" - elseif v == "Stone Wall" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531804" - elseif v == "Concrete" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532059" - elseif v == "Water" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=81407474" - else materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=66887593" -- fill in the rest here!! - end - end - - local scrollFrame, scrollUp, scrollDown, recalculateScroll = t.CreateScrollingFrame(nil,"grid") - scrollFrame.Size = UDim2.new(0.85,0,1,0) - scrollFrame.Position = UDim2.new(0,0,0,0) - scrollFrame.Parent = frame - - scrollUp.Parent = frame - scrollUp.Visible = true - scrollUp.Position = UDim2.new(1,-19,0,0) - - scrollDown.Parent = frame - scrollDown.Visible = true - scrollDown.Position = UDim2.new(1,-19,1,-17) - - local function goToNewMaterial(buttonWrap, materialName) - updateMaterialChoice(materialName) - buttonWrap.BackgroundTransparency = 0 - selectedButton.BackgroundTransparency = 1 - selectedButton = buttonWrap - end - - local function createMaterialButton(name) - local buttonWrap = Instance.new("TextButton") - buttonWrap.Text = "" - buttonWrap.Size = UDim2.new(0,32,0,32) - buttonWrap.BackgroundColor3 = Color3.new(1,1,1) - buttonWrap.BorderSizePixel = 0 - buttonWrap.BackgroundTransparency = 1 - buttonWrap.AutoButtonColor = false - buttonWrap.Name = tostring(name) - - local imageButton = Instance.new("ImageButton") - imageButton.AutoButtonColor = false - imageButton.BackgroundTransparency = 1 - imageButton.Size = UDim2.new(0,30,0,30) - imageButton.Position = UDim2.new(0,1,0,1) - imageButton.Name = tostring(name) - imageButton.Parent = buttonWrap - imageButton.Image = materialToImageMap[name].Regular - - local enumType = Instance.new("NumberValue") - enumType.Name = "EnumType" - enumType.Parent = buttonWrap - enumType.Value = 0 - - imageButton.MouseEnter:connect(function() - buttonWrap.BackgroundTransparency = 0 - end) - imageButton.MouseLeave:connect(function() - if selectedButton ~= buttonWrap then - buttonWrap.BackgroundTransparency = 1 - end - end) - imageButton.MouseButton1Click:connect(function() - if selectedButton ~= buttonWrap then - goToNewMaterial(buttonWrap, tostring(name)) - end - end) - - return buttonWrap - end - - for i = 1, #materialNames do - local imageButton = createMaterialButton(materialNames[i]) - - if materialNames[i] == "Grass" then -- always start with grass as the default - selectedButton = imageButton - imageButton.BackgroundTransparency = 0 - end - - imageButton.Parent = scrollFrame - end - - local forceTerrainMaterialSelection = function(newMaterialType) - if not newMaterialType then return end - if currentMaterial == newMaterialType then return end - - local matName = getNameFromEnum(newMaterialType) - local buttons = scrollFrame:GetChildren() - for i = 1, #buttons do - if buttons[i].Name == "Plastic (blue)" and matName == "Plastic (blue)" then goToNewMaterial(buttons[i],matName) return end - if buttons[i].Name == "Plastic (red)" and matName == "Plastic (red)" then goToNewMaterial(buttons[i],matName) return end - if string.find(buttons[i].Name, matName) then - goToNewMaterial(buttons[i],matName) - return - end - end - end - - frame.Changed:connect(function ( prop ) - if prop == "AbsoluteSize" then - recalculateScroll() - end - end) - - recalculateScroll() - return frame, terrainMaterialSelectionChanged, forceTerrainMaterialSelection -end - -t.CreateLoadingFrame = function(name,size,position) - game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=35238053") - - local loadingFrame = Instance.new("Frame") - loadingFrame.Name = "LoadingFrame" - loadingFrame.Style = Enum.FrameStyle.RobloxRound - - if size then loadingFrame.Size = size - else loadingFrame.Size = UDim2.new(0,300,0,160) end - if position then loadingFrame.Position = position - else loadingFrame.Position = UDim2.new(0.5, -150, 0.5,-80) end - - local loadingBar = Instance.new("Frame") - loadingBar.Name = "LoadingBar" - loadingBar.BackgroundColor3 = Color3.new(0,0,0) - loadingBar.BorderColor3 = Color3.new(79/255,79/255,79/255) - loadingBar.Position = UDim2.new(0,0,0,41) - loadingBar.Size = UDim2.new(1,0,0,30) - loadingBar.Parent = loadingFrame - - local loadingGreenBar = Instance.new("ImageLabel") - loadingGreenBar.Name = "LoadingGreenBar" - loadingGreenBar.Image = "http://www.roblox.com/asset/?id=35238053" - loadingGreenBar.Position = UDim2.new(0,0,0,0) - loadingGreenBar.Size = UDim2.new(0,0,1,0) - loadingGreenBar.Visible = false - loadingGreenBar.Parent = loadingBar - - local loadingPercent = Instance.new("TextLabel") - loadingPercent.Name = "LoadingPercent" - loadingPercent.BackgroundTransparency = 1 - loadingPercent.Position = UDim2.new(0,0,1,0) - loadingPercent.Size = UDim2.new(1,0,0,14) - loadingPercent.Font = Enum.Font.Arial - loadingPercent.Text = "0%" - loadingPercent.FontSize = Enum.FontSize.Size14 - loadingPercent.TextColor3 = Color3.new(1,1,1) - loadingPercent.Parent = loadingBar - - local cancelButton = Instance.new("TextButton") - cancelButton.Name = "CancelButton" - cancelButton.Position = UDim2.new(0.5,-60,1,-40) - cancelButton.Size = UDim2.new(0,120,0,40) - cancelButton.Font = Enum.Font.Arial - cancelButton.FontSize = Enum.FontSize.Size18 - cancelButton.TextColor3 = Color3.new(1,1,1) - cancelButton.Text = "Cancel" - cancelButton.Style = Enum.ButtonStyle.RobloxButton - cancelButton.Parent = loadingFrame - - local loadingName = Instance.new("TextLabel") - loadingName.Name = "loadingName" - loadingName.BackgroundTransparency = 1 - loadingName.Size = UDim2.new(1,0,0,18) - loadingName.Position = UDim2.new(0,0,0,2) - loadingName.Font = Enum.Font.Arial - loadingName.Text = name - loadingName.TextColor3 = Color3.new(1,1,1) - loadingName.TextStrokeTransparency = 1 - loadingName.FontSize = Enum.FontSize.Size18 - loadingName.Parent = loadingFrame - - local cancelButtonClicked = Instance.new("BindableEvent") - cancelButtonClicked.Name = "CancelButtonClicked" - cancelButtonClicked.Parent = cancelButton - cancelButton.MouseButton1Click:connect(function() - cancelButtonClicked:Fire() - end) - - local updateLoadingGuiPercent = function(percent, tweenAction, tweenLength) - if percent and type(percent) ~= "number" then - error("updateLoadingGuiPercent expects number as argument, got",type(percent),"instead") - end - - local newSize = nil - if percent < 0 then - newSize = UDim2.new(0,0,1,0) - elseif percent > 1 then - newSize = UDim2.new(1,0,1,0) - else - newSize = UDim2.new(percent,0,1,0) - end - - if tweenAction then - if not tweenLength then - error("updateLoadingGuiPercent is set to tween new percentage, but got no tween time length! Please pass this in as third argument") - end - - if (newSize.X.Scale > 0) then - loadingGreenBar.Visible = true - loadingGreenBar:TweenSize( newSize, - Enum.EasingDirection.Out, - Enum.EasingStyle.Quad, - tweenLength, - true) - else - loadingGreenBar:TweenSize( newSize, - Enum.EasingDirection.Out, - Enum.EasingStyle.Quad, - tweenLength, - true, - function() - if (newSize.X.Scale < 0) then - loadingGreenBar.Visible = false - end - end) - end - - else - loadingGreenBar.Size = newSize - loadingGreenBar.Visible = (newSize.X.Scale > 0) - end - end - - loadingGreenBar.Changed:connect(function(prop) - if prop == "Size" then - loadingPercent.Text = tostring( math.ceil(loadingGreenBar.Size.X.Scale * 100) ) .. "%" - end - end) - - return loadingFrame, updateLoadingGuiPercent, cancelButtonClicked -end - -t.CreatePluginFrame = function (name,size,position,scrollable,parent) - function createMenuButton(size,position,text,fontsize,name,parent) - local button = Instance.new("TextButton",parent) - button.AutoButtonColor = false - button.Name = name - button.BackgroundTransparency = 1 - button.Position = position - button.Size = size - button.Font = Enum.Font.ArialBold - button.FontSize = fontsize - button.Text = text - button.TextColor3 = Color3.new(1,1,1) - button.BorderSizePixel = 0 - button.BackgroundColor3 = Color3.new(20/255,20/255,20/255) - - button.MouseEnter:connect(function ( ) - if button.Selected then return end - button.BackgroundTransparency = 0 - end) - button.MouseLeave:connect(function ( ) - if button.Selected then return end - button.BackgroundTransparency = 1 - end) - - return button - - end - - local dragBar = Instance.new("Frame",parent) - dragBar.Name = tostring(name) .. "DragBar" - dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255) - dragBar.BorderColor3 = Color3.new(0,0,0) - if size then - dragBar.Size = UDim2.new(size.X.Scale,size.X.Offset,0,20) + UDim2.new(0,20,0,0) - else - dragBar.Size = UDim2.new(0,183,0,20) - end - if position then - dragBar.Position = position - end - dragBar.Active = true - dragBar.Draggable = true - --dragBar.Visible = false - dragBar.MouseEnter:connect(function ( ) - dragBar.BackgroundColor3 = Color3.new(49/255,49/255,49/255) - end) - dragBar.MouseLeave:connect(function ( ) - dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255) - end) - - -- plugin name label - local pluginNameLabel = Instance.new("TextLabel",dragBar) - pluginNameLabel.Name = "BarNameLabel" - pluginNameLabel.Text = " " .. tostring(name) - pluginNameLabel.TextColor3 = Color3.new(1,1,1) - pluginNameLabel.TextStrokeTransparency = 0 - pluginNameLabel.Size = UDim2.new(1,0,1,0) - pluginNameLabel.Font = Enum.Font.ArialBold - pluginNameLabel.FontSize = Enum.FontSize.Size18 - pluginNameLabel.TextXAlignment = Enum.TextXAlignment.Left - pluginNameLabel.BackgroundTransparency = 1 - - -- close button - local closeButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-16,0.5,-8),"X",Enum.FontSize.Size14,"CloseButton",dragBar) - local closeEvent = Instance.new("BindableEvent") - closeEvent.Name = "CloseEvent" - closeEvent.Parent = closeButton - closeButton.MouseButton1Click:connect(function () - closeEvent:Fire() - closeButton.BackgroundTransparency = 1 - end) - - -- help button - local helpButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-51,0.5,-8),"?",Enum.FontSize.Size14,"HelpButton",dragBar) - local helpFrame = Instance.new("Frame",dragBar) - helpFrame.Name = "HelpFrame" - helpFrame.BackgroundColor3 = Color3.new(0,0,0) - helpFrame.Size = UDim2.new(0,300,0,552) - helpFrame.Position = UDim2.new(1,5,0,0) - helpFrame.Active = true - helpFrame.BorderSizePixel = 0 - helpFrame.Visible = false - - helpButton.MouseButton1Click:connect(function( ) - helpFrame.Visible = not helpFrame.Visible - if helpFrame.Visible then - helpButton.Selected = true - helpButton.BackgroundTransparency = 0 - local screenGui = getScreenGuiAncestor(helpFrame) - if screenGui then - if helpFrame.AbsolutePosition.X + helpFrame.AbsoluteSize.X > screenGui.AbsoluteSize.X then --position on left hand side - helpFrame.Position = UDim2.new(0,-5 - helpFrame.AbsoluteSize.X,0,0) - else -- position on right hand side - helpFrame.Position = UDim2.new(1,5,0,0) - end - else - helpFrame.Position = UDim2.new(1,5,0,0) - end - else - helpButton.Selected = false - helpButton.BackgroundTransparency = 1 - end - end) - - local minimizeButton = createMenuButton(UDim2.new(0,16,0,17),UDim2.new(1,-34,0.5,-8),"-",Enum.FontSize.Size14,"MinimizeButton",dragBar) - minimizeButton.TextYAlignment = Enum.TextYAlignment.Top - - local minimizeFrame = Instance.new("Frame",dragBar) - minimizeFrame.Name = "MinimizeFrame" - minimizeFrame.BackgroundColor3 = Color3.new(73/255,73/255,73/255) - minimizeFrame.BorderColor3 = Color3.new(0,0,0) - minimizeFrame.Position = UDim2.new(0,0,1,0) - if size then - minimizeFrame.Size = UDim2.new(size.X.Scale,size.X.Offset,0,50) + UDim2.new(0,20,0,0) - else - minimizeFrame.Size = UDim2.new(0,183,0,50) - end - minimizeFrame.Visible = false - - local minimizeBigButton = Instance.new("TextButton",minimizeFrame) - minimizeBigButton.Position = UDim2.new(0.5,-50,0.5,-20) - minimizeBigButton.Name = "MinimizeButton" - minimizeBigButton.Size = UDim2.new(0,100,0,40) - minimizeBigButton.Style = Enum.ButtonStyle.RobloxButton - minimizeBigButton.Font = Enum.Font.ArialBold - minimizeBigButton.FontSize = Enum.FontSize.Size18 - minimizeBigButton.TextColor3 = Color3.new(1,1,1) - minimizeBigButton.Text = "Show" - - local separatingLine = Instance.new("Frame",dragBar) - separatingLine.Name = "SeparatingLine" - separatingLine.BackgroundColor3 = Color3.new(115/255,115/255,115/255) - separatingLine.BorderSizePixel = 0 - separatingLine.Position = UDim2.new(1,-18,0.5,-7) - separatingLine.Size = UDim2.new(0,1,0,14) - - local otherSeparatingLine = separatingLine:clone() - otherSeparatingLine.Position = UDim2.new(1,-35,0.5,-7) - otherSeparatingLine.Parent = dragBar - - local widgetContainer = Instance.new("Frame",dragBar) - widgetContainer.Name = "WidgetContainer" - widgetContainer.BackgroundTransparency = 1 - widgetContainer.Position = UDim2.new(0,0,1,0) - widgetContainer.BorderColor3 = Color3.new(0,0,0) - if not scrollable then - widgetContainer.BackgroundTransparency = 0 - widgetContainer.BackgroundColor3 = Color3.new(72/255,72/255,72/255) - end - - if size then - if scrollable then - widgetContainer.Size = size - else - widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,size.Y.Scale,size.Y.Offset) - end - else - if scrollable then - widgetContainer.Size = UDim2.new(0,163,0,400) - else - widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,0,400) - end - end - if position then - widgetContainer.Position = position + UDim2.new(0,0,0,20) - end - - local frame,control,verticalDragger = nil - if scrollable then - --frame for widgets - frame,control = t.CreateTrueScrollingFrame() - frame.Size = UDim2.new(1, 0, 1, 0) - frame.BackgroundColor3 = Color3.new(72/255,72/255,72/255) - frame.BorderColor3 = Color3.new(0,0,0) - frame.Active = true - frame.Parent = widgetContainer - control.Parent = dragBar - control.BackgroundColor3 = Color3.new(72/255,72/255,72/255) - control.BorderSizePixel = 0 - control.BackgroundTransparency = 0 - control.Position = UDim2.new(1,-21,1,1) - if size then - control.Size = UDim2.new(0,21,size.Y.Scale,size.Y.Offset) - else - control.Size = UDim2.new(0,21,0,400) - end - control:FindFirstChild("ScrollDownButton").Position = UDim2.new(0,0,1,-20) - - local fakeLine = Instance.new("Frame",control) - fakeLine.Name = "FakeLine" - fakeLine.BorderSizePixel = 0 - fakeLine.BackgroundColor3 = Color3.new(0,0,0) - fakeLine.Size = UDim2.new(0,1,1,1) - fakeLine.Position = UDim2.new(1,0,0,0) - - verticalDragger = Instance.new("TextButton",widgetContainer) - verticalDragger.ZIndex = 2 - verticalDragger.AutoButtonColor = false - verticalDragger.Name = "VerticalDragger" - verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255) - verticalDragger.BorderColor3 = Color3.new(0,0,0) - verticalDragger.Size = UDim2.new(1,20,0,20) - verticalDragger.Position = UDim2.new(0,0,1,0) - verticalDragger.Active = true - verticalDragger.Text = "" - - local scrubFrame = Instance.new("Frame",verticalDragger) - scrubFrame.Name = "ScrubFrame" - scrubFrame.BackgroundColor3 = Color3.new(1,1,1) - scrubFrame.BorderSizePixel = 0 - scrubFrame.Position = UDim2.new(0.5,-5,0.5,0) - scrubFrame.Size = UDim2.new(0,10,0,1) - scrubFrame.ZIndex = 5 - local scrubTwo = scrubFrame:clone() - scrubTwo.Position = UDim2.new(0.5,-5,0.5,-2) - scrubTwo.Parent = verticalDragger - local scrubThree = scrubFrame:clone() - scrubThree.Position = UDim2.new(0.5,-5,0.5,2) - scrubThree.Parent = verticalDragger - - local areaSoak = Instance.new("TextButton",getScreenGuiAncestor(parent)) - areaSoak.Name = "AreaSoak" - areaSoak.Size = UDim2.new(1,0,1,0) - areaSoak.BackgroundTransparency = 1 - areaSoak.BorderSizePixel = 0 - areaSoak.Text = "" - areaSoak.ZIndex = 10 - areaSoak.Visible = false - areaSoak.Active = true - - local draggingVertical = false - local startYPos = nil - verticalDragger.MouseEnter:connect(function () - verticalDragger.BackgroundColor3 = Color3.new(60/255,60/255,60/255) - end) - verticalDragger.MouseLeave:connect(function () - verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255) - end) - verticalDragger.MouseButton1Down:connect(function(x,y) - draggingVertical = true - areaSoak.Visible = true - startYPos = y - end) - areaSoak.MouseButton1Up:connect(function ( ) - draggingVertical = false - areaSoak.Visible = false - end) - areaSoak.MouseMoved:connect(function(x,y) - if not draggingVertical then return end - - local yDelta = y - startYPos - if not control.ScrollDownButton.Visible and yDelta > 0 then - return - end - - if (widgetContainer.Size.Y.Offset + yDelta) < 150 then - widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,150) - control.Size = UDim2.new (0,21,0,150) - return - end - - startYPos = y - - if widgetContainer.Size.Y.Offset + yDelta >= 0 then - widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,widgetContainer.Size.Y.Offset + yDelta) - control.Size = UDim2.new(0,21,0,control.Size.Y.Offset + yDelta ) - end - end) - end - - local function switchMinimize() - minimizeFrame.Visible = not minimizeFrame.Visible - if scrollable then - frame.Visible = not frame.Visible - verticalDragger.Visible = not verticalDragger.Visible - control.Visible = not control.Visible - else - widgetContainer.Visible = not widgetContainer.Visible - end - - if minimizeFrame.Visible then - minimizeButton.Text = "+" - else - minimizeButton.Text = "-" - end - end - - minimizeBigButton.MouseButton1Click:connect(function ( ) - switchMinimize() - end) - - minimizeButton.MouseButton1Click:connect(function( ) - switchMinimize() - end) - - if scrollable then - return dragBar, frame, helpFrame, closeEvent - else - return dragBar, widgetContainer, helpFrame, closeEvent - end -end - -t.Help = - function(funcNameOrFunc) - --input argument can be a string or a function. Should return a description (of arguments and expected side effects) - if funcNameOrFunc == "CreatePropertyDropDownMenu" or funcNameOrFunc == t.CreatePropertyDropDownMenu then - return "Function CreatePropertyDropDownMenu. " .. - "Arguments: (instance, propertyName, enumType). " .. - "Side effect: returns a container with a drop-down-box that is linked to the 'property' field of 'instance' which is of type 'enumType'" - end - if funcNameOrFunc == "CreateDropDownMenu" or funcNameOrFunc == t.CreateDropDownMenu then - return "Function CreateDropDownMenu. " .. - "Arguments: (items, onItemSelected). " .. - "Side effect: Returns 2 results, a container to the gui object and a 'updateSelection' function for external updating. The container is a drop-down-box created around a list of items" - end - if funcNameOrFunc == "CreateMessageDialog" or funcNameOrFunc == t.CreateMessageDialog then - return "Function CreateMessageDialog. " .. - "Arguments: (title, message, buttons). " .. - "Side effect: Returns a gui object of a message box with 'title' and 'message' as passed in. 'buttons' input is an array of Tables contains a 'Text' and 'Function' field for the text/callback of each button" - end - if funcNameOrFunc == "CreateStyledMessageDialog" or funcNameOrFunc == t.CreateStyledMessageDialog then - return "Function CreateStyledMessageDialog. " .. - "Arguments: (title, message, style, buttons). " .. - "Side effect: Returns a gui object of a message box with 'title' and 'message' as passed in. 'buttons' input is an array of Tables contains a 'Text' and 'Function' field for the text/callback of each button, 'style' is a string, either Error, Notify or Confirm" - end - if funcNameOrFunc == "GetFontHeight" or funcNameOrFunc == t.GetFontHeight then - return "Function GetFontHeight. " .. - "Arguments: (font, fontSize). " .. - "Side effect: returns the size in pixels of the given font + fontSize" - end - if funcNameOrFunc == "LayoutGuiObjects" or funcNameOrFunc == t.LayoutGuiObjects then - - end - if funcNameOrFunc == "CreateScrollingFrame" or funcNameOrFunc == t.CreateScrollingFrame then - return "Function CreateScrollingFrame. " .. - "Arguments: (orderList, style) " .. - "Side effect: returns 4 objects, (scrollFrame, scrollUpButton, scrollDownButton, recalculateFunction). 'scrollFrame' can be filled with GuiObjects. It will lay them out and allow scrollUpButton/scrollDownButton to interact with them. Orderlist is optional (and specifies the order to layout the children. Without orderlist, it uses the children order. style is also optional, and allows for a 'grid' styling if style is passed 'grid' as a string. recalculateFunction can be called when a relayout is needed (when orderList changes)" - end - if funcNameOrFunc == "CreateTrueScrollingFrame" or funcNameOrFunc == t.CreateTrueScrollingFrame then - return "Function CreateTrueScrollingFrame. " .. - "Arguments: (nil) " .. - "Side effect: returns 2 objects, (scrollFrame, controlFrame). 'scrollFrame' can be filled with GuiObjects, and they will be clipped if not inside the frame's bounds. controlFrame has children scrollup and scrolldown, as well as a slider. controlFrame can be parented to any guiobject and it will readjust itself to fit." - end - if funcNameOrFunc == "AutoTruncateTextObject" or funcNameOrFunc == t.AutoTruncateTextObject then - return "Function AutoTruncateTextObject. " .. - "Arguments: (textLabel) " .. - "Side effect: returns 2 objects, (textLabel, changeText). The 'textLabel' input is modified to automatically truncate text (with ellipsis), if it gets too small to fit. 'changeText' is a function that can be used to change the text, it takes 1 string as an argument" - end - if funcNameOrFunc == "CreateSlider" or funcNameOrFunc == t.CreateSlider then - return "Function CreateSlider. " .. - "Arguments: (steps, width, position) " .. - "Side effect: returns 2 objects, (sliderGui, sliderPosition). The 'steps' argument specifies how many different positions the slider can hold along the bar. 'width' specifies in pixels how wide the bar should be (modifiable afterwards if desired). 'position' argument should be a UDim2 for slider positioning. 'sliderPosition' is an IntValue whose current .Value specifies the specific step the slider is currently on." - end - if funcNameOrFunc == "CreateSliderNew" or funcNameOrFunc == t.CreateSliderNew then - return "Function CreateSliderNew. " .. - "Arguments: (steps, width, position) " .. - "Side effect: returns 2 objects, (sliderGui, sliderPosition). The 'steps' argument specifies how many different positions the slider can hold along the bar. 'width' specifies in pixels how wide the bar should be (modifiable afterwards if desired). 'position' argument should be a UDim2 for slider positioning. 'sliderPosition' is an IntValue whose current .Value specifies the specific step the slider is currently on." - end - if funcNameOrFunc == "CreateLoadingFrame" or funcNameOrFunc == t.CreateLoadingFrame then - return "Function CreateLoadingFrame. " .. - "Arguments: (name, size, position) " .. - "Side effect: Creates a gui that can be manipulated to show progress for a particular action. Name appears above the loading bar, and size and position are udim2 values (both size and position are optional arguments). Returns 3 arguments, the first being the gui created. The second being updateLoadingGuiPercent, which is a bindable function. This function takes one argument (two optionally), which should be a number between 0 and 1, representing the percentage the loading gui should be at. The second argument to this function is a boolean value that if set to true will tween the current percentage value to the new percentage value, therefore our third argument is how long this tween should take. Our third returned argument is a BindableEvent, that when fired means that someone clicked the cancel button on the dialog." - end - if funcNameOrFunc == "CreateTerrainMaterialSelector" or funcNameOrFunc == t.CreateTerrainMaterialSelector then - return "Function CreateTerrainMaterialSelector. " .. - "Arguments: (size, position) " .. - "Side effect: Size and position are UDim2 values that specifies the selector's size and position. Both size and position are optional arguments. This method returns 3 objects (terrainSelectorGui, terrainSelected, forceTerrainSelection). terrainSelectorGui is just the gui object that we generate with this function, parent it as you like. TerrainSelected is a BindableEvent that is fired whenever a new terrain type is selected in the gui. ForceTerrainSelection is a function that takes an argument of Enum.CellMaterial and will force the gui to show that material as currently selected." - end - end - - - -local RbxGui - -local localTesting = true - -local screen = script.Parent -local screenResizeCon = nil - -local friendWord = "Friend" -local friendWordLowercase = "friend" - -local elementNames = {} -local elementNameToElement = {} - -local privilegeOwner = 255 -local privilegeAdmin = 240 -local privilegeMember = 128 -local privilegeVisitor = 10 -local privilegeBanned = 0 - -local inContextMenu = false -local contextMenu3d = false - -local bigEasingStyle = Enum.EasingStyle.Back -local smallEasingStyle = Enum.EasingStyle.Quart - -local personalServerContextAdded = false -local personalServerPlace = false -local success = pcall(function() personalServerPlace = game.IsPersonalServer end) -if not success then - personalServerPlace = false -end - -local friendRequestBlacklist = {} -local otherPlayerBlacklist = {} - -local currentSortName = "" - -local function waitForChild(instance, name) - while not instance:FindFirstChild(name) do - instance.ChildAdded:wait() - end -end - -local function waitForProperty(instance, prop) - while not instance[prop] do - instance.Changed:wait() - end -end - -local function Color3I(r,g,b) - return Color3.new(r/255,g/255,b/255) -end - -function robloxLock(instance) -end - -function ArrayRemove(t, obj) - for i, obj2 in ipairs(t) do - if obj == obj2 then - table.remove(t, i) - return true - end - end - return false -end - -local function getPlayers() - local result = {} - local players = game:GetService("Players"):GetChildren() - if players then - for i, player in ipairs(players) do - if player:IsA("Player") then - table.insert(result, player) - end - end - end - return result -end - -local brickColorTable = {} -for i = 0, 63 do - brickColorTable[BrickColor.palette(i).Name] = BrickColor.palette(i).Color -end - -local function remapColor(i, j) - brickColorTable[BrickColor.palette(i).Name] = BrickColor.palette(j).Color -end - -remapColor(13, 12) -remapColor(14, 12) -remapColor(15, 12) -remapColor(61, 29) -remapColor(63, 62) -remapColor(56, 50) -remapColor(45, 53) -remapColor(51, 20) -remapColor(4, 20) -remapColor(59, 35) -remapColor(60, 29) - -local function getColor(brickColor) - if brickColorTable[brickColor.Name] then - return brickColorTable[brickColor.Name] - else - return brickColor.Color; - end -end - - - -local function getTeams() - local result = {} - local teams = game:GetService("Teams"):GetChildren() - for i, team in ipairs(teams) do - if team:IsA("Team") then - table.insert(result, team) - end - end - return result -end - -local supportFriends = false -local currentBoardType = "PlayerList" -local currentStatCount = 0 - -local createBoardsFunction = nil - - -local playerTable = {} -local teamTable = {} -local teamColorTable = {} - -local removePlayerFunction = nil -local recreatePlayerFunction = nil -local addPlayerFunction = function(player) - if recreatePlayerFunction then - recreatePlayerFunction(player) - end -end -local sortPlayerListsFunction = nil - -local minimizedState = nil -local bigWindowImposter = nil -local smallWindowPosition = UDim2.new(0, -20, 0,5) -local smallWindowSize = UDim2.new(1,0,1,0) -local bigWindowSize = UDim2.new(0.6,0,0.6,0) -local bigWindowPosition = UDim2.new(.2, 0, .2,0) - -local smallWindowHeaderYSize = 32 - -local debounceTeamsChanged = false - -local currentWindowState = "Small" -local previousWindowState = nil -local transitionWindowsFunction = nil - -local container = nil -local topRightTrayContainer = nil - -local playerContextMenu = nil -local contextMenuElements = {} -local updateContextMenuItems = nil - -local function addContextMenuLabel(getText1, getText2, isVisible) - local t = {} - t.Type = "Label" - t.GetText1 = getText1 - t.GetText2 = getText2 - t.IsVisible = isVisible - table.insert(contextMenuElements, t) -end -local function addContextMenuButton(text, isVisible, isActive, doIt) - local t = {} - t.Text = text - t.Type = "Button" - t.IsVisible = isVisible - t.IsActive = isActive - t.DoIt = doIt - table.insert(contextMenuElements, t) -end - -local function getFriendStatus(player) - if player == game.Players.LocalPlayer then - return Enum.FriendStatus.NotFriend - else - local success, result = pcall(function() return game.Players.LocalPlayer:GetFriendStatus(player) end) - if success then - return result - else - return Enum.FriendStatus.NotFriend - end - end -end - - -local function getPrivilegeType(player) - local rank = player.PersonalServerRank - if rank >= privilegeOwner then - return privilegeOwner - elseif rank < privilegeOwner and rank >= privilegeAdmin then - return privilegeAdmin - elseif rank < privilegeAdmin and rank >= privilegeMember then - return privilegeMember - elseif rank < privilegeMember and rank >= privilegeVisitor then - return privilegeVisitor - else - return privilegeBanned - end -end - ---Populate the ContextMenus -addContextMenuLabel( - --GetText1 - function(player) - return "Loading..." - end, - --GetText2 - nil, - --IsVisible - function(player) - return getFriendStatus(player) == Enum.FriendStatus.Unknown - end) - -addContextMenuButton("Send " .. friendWord .. " Request", - --IsVisible - function(player) - return (not otherPlayerBlacklist[player]) and (getFriendStatus(player) == Enum.FriendStatus.NotFriend) - end, - --IsActive - function(player) - return true - end, - --DoIt? - function(player) - otherPlayerBlacklist[player] = true - return game.Players.LocalPlayer:RequestFriendship(player) - end -) -addContextMenuButton("Un" .. friendWordLowercase, - --IsVisible - function(player) - return getFriendStatus(player) == Enum.FriendStatus.Friend - end, - --IsActive - function(player) - return true - end, - --DoIt - function(player) - return game.Players.LocalPlayer:RevokeFriendship(player) - end -) -addContextMenuButton("Accept " .. friendWord .. " Request", - --IsVisible - function(player) - return (not friendRequestBlacklist[player]) and (getFriendStatus(player) == Enum.FriendStatus.FriendRequestReceived) - end, - --IsActive - function(player) - return true - end, - --DoIt - function(player) - return game.Players.LocalPlayer:RequestFriendship(player) - end -) - -addContextMenuButton("Deny " .. friendWord .. " Request", - --IsVisible - function(player) - return getFriendStatus(player) == Enum.FriendStatus.FriendRequestReceived - end, - --IsActive - function(player) - return true - end, - --DoIt - function(player) - friendRequestBlacklist[player] = true - return game.Players.LocalPlayer:RevokeFriendship(player) - end -) - -addContextMenuButton("Cancel " .. friendWord .. " Request", - --IsVisible - function(player) - return false -- disable cancel request for now (can lead to griefing) - --return getFriendStatus(player) == Enum.FriendStatus.FriendRequestSent - end, - --IsActive - function(player) - return true - end, - --DoIt - function(player) - otherPlayerBlacklist[player] = false - return game.Players.LocalPlayer:RevokeFriendship(player) - end -) - -function addPersonalServerContext() - if personalServerContextAdded then return end - personalServerContextAdded = true - addContextMenuButton("Ban", - --IsVisible - function(player) - return ( getPrivilegeType(game.Players.LocalPlayer) >= privilegeAdmin and (getPrivilegeType(player) < privilegeAdmin) ) - end, - --IsActive - function(player) - return true - end, - --DoIt - function(player) - player.PersonalServerRank = privilegeBanned - return true - end - ) - addContextMenuButton("Promote to Visitor", - --IsVisible - function(player) - return ( getPrivilegeType(game.Players.LocalPlayer) >= privilegeAdmin ) and ( getPrivilegeType(player) == privilegeBanned ) - end, - --IsActive - function(player) - return true - end, - --DoIt - function(player) - game:GetService("PersonalServerService"):Promote(player) - return true - end - ) - addContextMenuButton("Promote to Member", - --IsVisible - function(player) - return ( getPrivilegeType(game.Players.LocalPlayer) >= privilegeAdmin ) and ( getPrivilegeType(player) == privilegeVisitor ) - end, - --IsActive - function(player) - return true - end, - --DoIt - function(player) - game:GetService("PersonalServerService"):Promote(player) - return true - end - ) - addContextMenuButton("Promote to Admin", - --IsVisible - function(player) - return ( getPrivilegeType(game.Players.LocalPlayer) == privilegeOwner ) and ( getPrivilegeType(player) == privilegeMember ) - end, - --IsActive - function(player) - return true - end, - --DoIt - function(player) - game:GetService("PersonalServerService"):Promote(player) - return true - end - ) - addContextMenuButton("Demote to Member", - --IsVisible - function(player) - return ( getPrivilegeType(game.Players.LocalPlayer) == privilegeOwner ) and ( getPrivilegeType(player) == privilegeAdmin ) - end, - --IsActive - function(player) - return true - end, - --DoIt - function(player) - game:GetService("PersonalServerService"):Demote(player) - return true - end - ) - addContextMenuButton("Demote to Visitor", - --IsVisible - function(player) - return ( getPrivilegeType(game.Players.LocalPlayer) >= privilegeAdmin ) and ( getPrivilegeType(player) == privilegeMember ) - end, - --IsActive - function(player) - return true - end, - --DoIt - function(player) - game:GetService("PersonalServerService"):Demote(player) - return true - end - ) -end - -local function setupBuildToolManagement() - local buildToolManagerAssetId = 64164692 - game:GetService("ScriptContext"):AddCoreScript(buildToolManagerAssetId,game.Players.LocalPlayer,"BuildToolManager") -end - - -local function getStatColumns(players) - for i, player in ipairs(players) do - local leaderstats = player:FindFirstChild("leaderstats") - if leaderstats then - local stats = {} - local children = leaderstats:GetChildren() - if children then - for i, stat in ipairs(children) do - if stat:IsA("IntValue") then - table.insert(stats, stat) - else - --TODO: This should check for IntValue only but current ScoreHud does not - table.insert(stats, stat) - end - end - end - return stats - end - end - return nil -end - -local function determineBoardType() - local players = getPlayers() - - local foundLeaderstats = false - local numStats = 0 - local foundTeam = false - - local stats = getStatColumns(players) - if stats then - foundLeaderstats = true - numStats = #stats - end - - for i, player in ipairs(players) do - if not foundTeam then - if not player.Neutral then - foundTeam = true - break - end - end - end - - if foundLeaderstats and foundTeam then - return "TeamScore", numStats - elseif foundLeaderstats then - return "PlayerScore", numStats - elseif foundTeam then - return "TeamList", numStats - else - return "PlayerList", numStats - end -end - -local function toggleBigWindow() - if container == nil then - return - end - - if currentWindowState == "Big" then - --Hide it - if previousWindowState == nil or previousWindowState == "Big" or previousWindowState == "None" then - transitionWindowsFunction("None") - else - transitionWindowsFunction("Small") - end - else - previousWindowState = currentWindowState - transitionWindowsFunction("Big") - end -end -local previousBigPlayerList = nil -local function rebuildBoard(owner, boardType, numStats) - if topRightTrayContainer == nil then - topRightTrayContainer = owner:FindFirstChild("PlayerListTopRightFrame") - if topRightTrayContainer == nil then - topRightTrayContainer = Instance.new("Frame") - topRightTrayContainer.Name = "PlayerListTopRightFrame" - topRightTrayContainer.BackgroundTransparency = 1 - topRightTrayContainer.Size = UDim2.new(0.2, 16, 0.42, 16) - topRightTrayContainer.Position = UDim2.new(0.8, 0, 0, 0) - topRightTrayContainer.Parent = container - end - end - if minimizedState == nil then - minimizedState = Instance.new("Frame") - minimizedState.Name = "MinimizedPlayerlist" - minimizedState.BackgroundTransparency = 1 - minimizedState.Position = UDim2.new(1, -166, 0,0) - minimizedState.Size = UDim2.new(0, 151, 0, 30) - - playerListButton = Instance.new("ImageButton") - playerListButton.Name = "GoSmallButton" - playerListButton.Image = "rbxasset://textures/ui/playerlist_hidden_small.png" - playerListButton.BackgroundTransparency = 1 - playerListButton.Size = UDim2.new(0.0, 35, 0, 30) - playerListButton.Position = UDim2.new(1, -35, 0, 0) - playerListButton.MouseButton1Click:connect( - function() - transitionWindowsFunction("Small") - end) - playerListButton.Parent = minimizedState - - minimizedState.Visible = false - robloxLock(minimizedState) - minimizedState.Parent = topRightTrayContainer - end - if bigWindowImposter == nil then - bigWindowImposter = owner:FindFirstChild("BigPlayerListWindowImposter") - if bigWindowImposter == nil then - bigWindowImposter = Instance.new("Frame") - bigWindowImposter.Name = "BigPlayerListWindowImposter" - bigWindowImposter.Visible = false - bigWindowImposter.BackgroundColor3 = Color3.new(0,0,0) - bigWindowImposter.BackgroundTransparency = 0.7 - bigWindowImposter.BorderSizePixel = 0 - bigWindowImposter.Size = UDim2.new(0.4, 7, 0.4, 7) - bigWindowImposter.Position = UDim2.new(0.3, 0, 0.3, 0) - robloxLock(bigWindowImposter) - bigWindowImposter.Parent = container - end - end - if container == nil or container ~= owner then - container = owner - - topRightTrayContainer.Parent = container - bigWindowImposter.Parent = container - end - - local smallVisible = true - local bigVisible = false - if container then - if topRightTrayContainer then - --Delete the old boards - if topRightTrayContainer:FindFirstChild("SmallPlayerlist") then - smallVisible = topRightTrayContainer.SmallPlayerlist.Visible - topRightTrayContainer.SmallPlayerlist.Parent = nil - end - end - if container:FindFirstChild("BigPlayerlist") then - bigVisible = container.BigPlayerlist.Visible or (previousBigPlayerList ~= nil) - container.BigPlayerlist.Parent = nil - if previousBigPlayerList ~= nil then - pcall(function() game.GuiService:RemoveCenterDialog(previousBigPlayerList) end) - previousBigPlayerList = nil - end - end - end - - local smallBoard, bigBoard = createBoardsFunction(boardType, numStats) - if smallBoard then - smallBoard.Visible = smallVisible - smallBoard.Parent = topRightTrayContainer - recalculateSmallPlayerListSize(smallBoard) - end - if bigBoard then - if bigVisible then - previousBigPlayerList = bigBoard - local centerDialogSupported, msg = pcall(function() game.GuiService:AddCenterDialog(previousBigPlayerList, Enum.CenterDialogType.PlayerInitiatedDialog, - function() - previousBigPlayerList.Visible = true - end, - function() - previousBigPlayerList.Visible = false - end) - end) - bigBoard.Visible = bigVisible - else - bigBoard.Visible = false - end - bigBoard.Parent = container - end - return container -end - -function recalculateSmallPlayerListSize(smallPlayerList) -end - - -local function showBigPlayerWindow() - if container:FindFirstChild("BigPlayerlist") then - if container.BigPlayerlist.Visible then - return - end - end - - bigWindowImposter.Visible = true - bigWindowImposter:TweenSizeAndPosition(bigWindowSize, bigWindowPosition, Enum.EasingDirection.Out, bigEasingStyle, 0.3, true, - function(state) - if state == Enum.TweenStatus.Completed then - bigWindowImposter.Visible = false - if container:FindFirstChild("BigPlayerlist") then - container.BigPlayerlist.Visible = true - end - end - end) -end - -local function hideBigPlayerWindow(completed) - if playerContextMenu then - playerContextMenu.Visible = false - end - - if container:FindFirstChild("BigPlayerlist") then - if container.BigPlayerlist.Visible == false and bigWindowImposter.Visible == false then - if completed then - completed() - end - --Already completely hidden - return - end - container.BigPlayerlist.Visible = false - end - - local completedFunction = completed - bigWindowImposter.Visible = true - bigWindowImposter:TweenSizeAndPosition(UDim2.new(0.4, 0, 0.4, 0), UDim2.new(0.3, 0, 0.3, 0), Enum.EasingDirection.In, Enum.EasingStyle.Quart, 0.15, true, - function(state) - if state == Enum.TweenStatus.Completed then - bigWindowImposter.Visible = false - if completedFunction then - completedFunction() - end - end - end) -end -local function hideSmallPlayerWindow(completed) - if playerContextMenu then - playerContextMenu.Visible = false - end - if topRightTrayContainer:FindFirstChild("SmallPlayerlist") then - local completedFunction = completed - if topRightTrayContainer.SmallPlayerlist.Visible then - topRightTrayContainer.SmallPlayerlist:TweenPosition(UDim2.new(1,0,smallWindowPosition.Y.Scale, smallWindowPosition.Y.Offset), Enum.EasingDirection.Out, smallEasingStyle, 0.3, true, - function(state) - if state == Enum.TweenStatus.Completed then - if topRightTrayContainer:FindFirstChild("SmallPlayerlist") then - topRightTrayContainer.SmallPlayerlist.Visible = false - end - if completedFunction then - completedFunction() - end - end - end) - return - end - end - if completed then - completed() - end -end - - -transitionWindowsFunction = function(desiredState) - if desiredState == "Big" then - minimizedState.Visible = false - hideSmallPlayerWindow() - - if previousBigPlayerList ~= nil then - if previousBigPlayerList ~= container:FindFirstChild("BigPlayerlist") then - pcall(function() game.GuiService:RemoveCenterDialog(previousBigPlayerList) end) - previousBigPlayerList = nil - previousBigPlayerList = container:FindFirstChild("BigPlayerlist") - end - else - previousBigPlayerList = container:FindFirstChild("BigPlayerlist") - end - - if previousBigPlayerList then - local firstShow = false - local centerDialogSupported, msg = pcall(function() game.GuiService:AddCenterDialog(previousBigPlayerList, Enum.CenterDialogType.PlayerInitiatedDialog, - function() - if not firstShow then - showBigPlayerWindow() - firstShow = true - else - previousBigPlayerList.Visible = true - end - end, - function() - if previousBigPlayerList then - previousBigPlayerList.Visible = false - end - end) - end) - if centerDialogSupported == false then - print("Exception", msg) - showBigPlayerWindow() - end - else - showBigPlayerWindow() - end - currentWindowState = "Big" - elseif desiredState == "Small" then - minimizedState.Visible = false - if previousBigPlayerList ~= nil then - pcall(function() game.GuiService:RemoveCenterDialog(previousBigPlayerList) end) - previousBigPlayerList = nil - end - - hideBigPlayerWindow() - if topRightTrayContainer:FindFirstChild("SmallPlayerlist") then - if not topRightTrayContainer.SmallPlayerlist.Visible or topRightTrayContainer.SmallPlayerlist.Position ~= smallWindowPosition then - topRightTrayContainer.SmallPlayerlist.Visible = true - topRightTrayContainer.SmallPlayerlist:TweenPosition(smallWindowPosition, Enum.EasingDirection.Out, smallEasingStyle, 0.3, true) - end - end - currentWindowState = "Small" - elseif desiredState == "None" then - if previousBigPlayerList ~= nil then - pcall(function() game.GuiService:RemoveCenterDialog(previousBigPlayerList) end) - previousBigPlayerList = nil - end - - local smallDone = false - local bigDone = false - hideSmallPlayerWindow( - function() - smallDone = true - if bigDone and smallDone then - minimizedState.Visible = true - end - end) - hideBigPlayerWindow( - function() - bigDone = true - if bigDone and smallDone then - minimizedState.Visible = true - end - end) - currentWindowState = "None" - end -end - -local function getStatValuesForPlayer(player) - local leaderstats = player:FindFirstChild("leaderstats") - if leaderstats then - local children = leaderstats:GetChildren() - if children then - local result = {} - --Just go based on position - for i, stat in ipairs(children) do - if stat:IsA("IntValue") then - table.insert(result, stat) - else - table.insert(result, 0) - end - end - - return result, leaderstats - end - end - return nil -end - ---ChildAdded on Player (if it's name is "leaderstats") - -if UserSettings and LoadLibrary then - - RbxGui,msg = t - - local function createTeamName(name, color) - local fontHeight = 20 - local frame = Instance.new("Frame") - frame.Name = "Team-" .. name - frame.BorderSizePixel = 0 - frame.BackgroundTransparency = 0.5 - frame.BackgroundColor3 = Color3.new(1,1,1) - frame.Size = UDim2.new(1, 0, 0, fontHeight) - frame.Position = UDim2.new(0,0,0,0) - - local label = Instance.new("TextLabel") - label.Name = "NameLabel" - label.Text = " " .. name - label.Font = Enum.Font.ArialBold - label.FontSize = Enum.FontSize.Size18 - label.Position = UDim2.new(0,0,0,0) - label.Size = UDim2.new(1,0,1,0) - label.TextColor3 = Color3.new(1,1,1) - label.BackgroundTransparency = 0.5 - label.BackgroundColor3 = getColor(color) - label.BorderSizePixel = 0 - label.TextXAlignment = Enum.TextXAlignment.Left - - local changeFunc = nil - label, changeFunc = RbxGui.AutoTruncateTextObject(label) - label.Parent = frame - - return frame, changeFunc - end - - local function getFriendStatusIcon(friendStatus) - if friendStatus == Enum.FriendStatus.Unknown or friendStatus == Enum.FriendStatus.NotFriend then - return nil - elseif friendStatus == Enum.FriendStatus.Friend then - return "rbxasset://textures/ui/PlayerlistFriendIcon.png" - elseif friendStatus == Enum.FriendStatus.FriendRequestSent then - return "rbxasset://textures/ui/PlayerlistFriendRequestSentIcon.png" - elseif friendStatus == Enum.FriendStatus.FriendRequestReceived then - return "rbxasset://textures/ui/PlayerlistFriendRequestReceivedIcon.png" - else - error("Unknown FriendStatus: " .. friendStatus) - end - end - - local function getMembershipTypeIcon(membershipType, playerName) - if membershipType == Enum.MembershipType.None then - return "rbxasset://../../../shareddata/charcustom/custom/icons/"..playerName..".png" - elseif membershipType == Enum.MembershipType.BuildersClub then - return "rbxasset://textures/ui/TinyBcIcon.png" - elseif membershipType == Enum.MembershipType.TurboBuildersClub then - return "rbxasset://textures/ui/TinyTbcIcon.png" - elseif membershipType == Enum.MembershipType.OutrageousBuildersClub then - return "rbxasset://textures/ui/TinyObcIcon.png" - else - error("Uknown membershipType" .. membershipType) - end - end - - - local function updatePlayerFriendStatus(nameObject, friendStatus) - local fontHeight = 20 - - local friendIconImage = getFriendStatusIcon(friendStatus) - nameObject.MembershipTypeLabel.FriendStatusLabel.Visible = (friendIconImage ~= nil) - - if friendIconImage ~= nil then - --Show friend icon - nameObject.MembershipTypeLabel.FriendStatusLabel.Image = friendIconImage - nameObject.NameLabel.Position =UDim2.new(0,2*fontHeight,0,1) - nameObject.NameLabel.Size = UDim2.new(1,-2*fontHeight,1,-2) - else - --Hide the friend icon - nameObject.NameLabel.Position = UDim2.new(0,fontHeight+1,0,1) - nameObject.NameLabel.Size = UDim2.new(1,-(fontHeight+1),1,-2) - end - end - local function updatePlayerName(nameObject, membershipStatus, teamColor) - local fontHeight = 20 - - local playerName = nameObject.NameLabel.Text - - nameObject.Size = UDim2.new(1,0,0,fontHeight) - nameObject.MembershipTypeLabel.Image = getMembershipTypeIcon(membershipStatus, playerName) - end - - - local function updatePlayerNameColor(player, teamColor) - local function updatePlayerNameColorHelper(nameObject) - if teamColor ~= nil then - nameObject.NameLabel.TextColor3 = getColor(teamColor) - nameObject.NameLabel.FullNameLabel.TextColor3 = getColor(teamColor) - else - nameObject.NameLabel.TextColor3 = Color3.new(1,1,1) - nameObject.NameLabel.FullNameLabel.TextColor3 = Color3.new(1,1,1) - end - end - - updatePlayerNameColorHelper(playerTable[player].NameObjectSmall) - updatePlayerNameColorHelper(playerTable[player].NameObjectBig) - end - - - local function createPlayerName(name, membershipStatus, teamColor, friendStatus) - local frame = Instance.new("Frame") - frame.Name = "Player_" .. name - frame.BackgroundColor3 = Color3.new(1,1,1) - frame.BackgroundTransparency = 0.5 - frame.BorderSizePixel = 0 - - local membershipStatusLabel = Instance.new("ImageLabel") - membershipStatusLabel.Name = "MembershipTypeLabel" - membershipStatusLabel.BackgroundTransparency = 1 - membershipStatusLabel.Size = UDim2.new(1,0,1,0) - membershipStatusLabel.Position = UDim2.new(0,0,0,0) - membershipStatusLabel.SizeConstraint = Enum.SizeConstraint.RelativeYY - membershipStatusLabel.Parent = frame - - local friendStatusLabel = Instance.new("ImageLabel") - friendStatusLabel.Name = "FriendStatusLabel" - friendStatusLabel.Visible = false - friendStatusLabel.BackgroundTransparency = 1 - friendStatusLabel.Size = UDim2.new(1,0,1,0) - friendStatusLabel.Position = UDim2.new(1,0,0,0) - friendStatusLabel.Parent = membershipStatusLabel - - local changeNameFunction - local nameLabel = Instance.new("TextLabel") - nameLabel.Name = "NameLabel" - nameLabel.Text = name - nameLabel.Font = Enum.Font.ArialBold - nameLabel.FontSize = Enum.FontSize.Size14 - nameLabel.TextColor3 = Color3.new(1,1,1) - nameLabel.BackgroundTransparency = 1 - nameLabel.BackgroundColor3 = Color3.new(0,0,0) - nameLabel.TextXAlignment = Enum.TextXAlignment.Left - nameLabel, changeNameFunction = RbxGui.AutoTruncateTextObject(nameLabel) - nameLabel.Parent = frame - - updatePlayerName(frame, membershipStatus, teamColor) - if supportFriends and not friendRequestBlacklist[game.Players:FindFirstChild(name)] then - updatePlayerFriendStatus(frame, friendStatus) - else - updatePlayerFriendStatus(frame, Enum.FriendStatus.NotFriend) - end - return frame, changeNameFunction - end - - local function createStatColumn(i, numColumns, isTeam, color3, isHeader, stat) - local textLabel = Instance.new("TextButton") - textLabel.Name = "Stat" .. i - textLabel.AutoButtonColor = false - textLabel.TextColor3 = Color3.new(1,1,1) - textLabel.TextXAlignment = Enum.TextXAlignment.Right - textLabel.TextYAlignment = Enum.TextYAlignment.Center - textLabel.FontSize = Enum.FontSize.Size14 - - if isHeader then - textLabel.FontSize = Enum.FontSize.Size18 - else - textLabel.FontSize = Enum.FontSize.Size14 - end - if isHeader or isTeam then - textLabel.Font = Enum.Font.ArialBold - else - textLabel.Font = Enum.Font.Arial - end - - if isTeam then - textLabel.BackgroundColor3 = color3 - textLabel.Text = 0 - else - textLabel.BackgroundColor3 = Color3.new(0,0,0) - textLabel.Text = "" - end - textLabel.BackgroundTransparency = 1 - if i == numColumns then - textLabel.Size = UDim2.new(1/numColumns, -6, 1, 0) - else - textLabel.Size = UDim2.new(1/numColumns, -4, 1, 0) - end - - textLabel.Position = UDim2.new((i-1) * (1/numColumns), 0, 0, 0) - - local truncLabel, changer = RbxGui.AutoTruncateTextObject(textLabel) - - if isHeader then - local mouseCon = {} - - mouseCon[1] = truncLabel.MouseEnter:connect(function() - truncLabel.BackgroundTransparency = 0.2 - end) - mouseCon[2] = truncLabel.MouseLeave:connect(function() - truncLabel.BackgroundTransparency = 1 - end) - - mouseCon[3] = truncLabel.MouseButton1Click:connect(function() - sortPlayerListsFunction(truncLabel:GetChildren()[1].Name, (currentSortName == truncLabel:GetChildren()[1].Name) ) - truncLabel.BackgroundTransparency = 1 - end) - - mouseCon[4] = truncLabel:GetChildren()[1].MouseButton1Click:connect(function() - sortPlayerListsFunction(textLabel.Name, (currentSortName == truncLabel.Name) ) - truncLabel.BackgroundTransparency = 1 - end) - - mouseCon[5] = nil - mouseCon[5] = truncLabel.AncestryChanged:connect(function(child,parent) - if parent == nil then - for i,connection in pairs(mouseCon) do - connection:disconnect() - end - end - end) - end - - return truncLabel, changer - end - - local function createStatHeaders(stats, numColumns, isBig) - local frame = Instance.new("Frame") - frame.Name = "Headers" - frame.BorderSizePixel = 0 - frame.BackgroundColor3 = Color3.new(0,0,0) - frame.BackgroundTransparency = 1 - - local nameSize - if isBig then - nameSize = 0.5 - elseif numColumns == 1 then - nameSize = 0.7 - elseif numColumns == 2 then - nameSize = 0.6 - else - nameSize = 0.45 - end - frame.Size = UDim2.new(1-nameSize, 0, 1,0) - if isBig then - frame.Position = UDim2.new(nameSize,-25, 0,0) - else - frame.Position = UDim2.new(nameSize,0, 0,0) - end - - local i = 1 - while i <= numColumns do - local headerColumn, changeText = createStatColumn(i, numColumns, false, nil, true,stats[i]) - changeText(stats[i].Name) - headerColumn.Parent = frame - i = i + 1 - end - return frame, textChangers - end - - local function createStatColumns(nameObject, numColumns, isTeam, isBig) - local frame = Instance.new("Frame") - frame.Name = nameObject.Name .. "_WithStats" - frame.BorderSizePixel = 0 - frame.BackgroundColor3 = nameObject.BackgroundColor3 - frame.BackgroundTransparency = nameObject.BackgroundTransparency - frame.Size = nameObject.Size - frame.Position = nameObject.Position - - nameObject.BackgroundTransparency = 1 - - if numColumns == 0 then - nameObject.Size = UDim2.new(1,0,1,0) - nameObject.Position = UDim2.new(0,0,0,0) - nameObject.Parent = frame - return frame - end - - local statFrame = Instance.new("Frame") - statFrame.Name = "Stats" - if isTeam then - statFrame.BorderSizePixel = 0 - statFrame.BackgroundColor3 = nameObject.NameLabel.BackgroundColor3 - statFrame.BackgroundTransparency = nameObject.NameLabel.BackgroundTransparency - else - statFrame.BackgroundTransparency = 1 - end - - local nameSize - if isBig then - nameSize = 0.5 - elseif numColumns == 1 then - nameSize = 0.7 - elseif numColumns == 2 then - nameSize = 0.6 - else - nameSize = 0.45 - end - nameObject.Size = UDim2.new(nameSize, 0, 1, 0) - nameObject.Position = UDim2.new(0, 0, 0, 0) - statFrame.Size = UDim2.new(1-nameSize,0, 1,0) - statFrame.Position = UDim2.new(nameSize,0, 0,0) - - nameObject.Parent = frame - statFrame.Parent = frame - - local textChangers = {} - local i = 1 - while i <= numColumns do - local statColumn, changeText = createStatColumn(i, numColumns, isTeam, statFrame.BackgroundColor3) - statColumn.Parent = statFrame - table.insert(textChangers, changeText) - - i = i + 1 - end - - return frame, statFrame, textChangers - end - - local function createAlternatingRows(objects) - for i, line in ipairs(objects) do - if i % 2 == 0 then - line.BackgroundTransparency = 1 - else - line.BackgroundTransparency = 0.95 - end - end - end - local removeFromTeam = nil - - local function clearTableEntry(obj, tableInfo) - if tableInfo.MainObjectSmall then - tableInfo.MainObjectSmall.Parent = nil - tableInfo.MainObjectSmall = nil - end - if tableInfo.MainObjectBig then - tableInfo.MainObjectBig.Parent = nil - tableInfo.MainObjectBig = nil - end - if tableInfo.Connections then - for i, connection in ipairs(tableInfo.Connections) do - connection:disconnect() - end - tableInfo.Connections = nil - end - if tableInfo.LeaderStatConnections then - for i, connection in ipairs(tableInfo.LeaderStatConnections) do - connection:disconnect() - end - tableInfo.LeaderStatConnections = nil - end - if tableInfo.CurrentTeam then - removeFromTeam(obj) - tableInfo.CurrentTeam = nil - end - if tableInfo.Players then - for i, player in ipairs(tableInfo.Players) do - playerTable[player].CurrentTeam = nil - end - tableInfo.Players = {} - end - if tableInfo.StatValues then - tableInfo.StatValues = nil - end - end - - local function resetPlayerTable() - for player, info in pairs(playerTable) do - clearTableEntry(player, info) - playerTable[player] = nil - end - playerTable = {} - end - - local function resetTeamTable() - for team, info in pairs(teamTable) do - clearTableEntry(team, info) - teamTable[team] = nil - end - teamTable = {} - teamColorTable = {} - end - - local function getBoardTypeInfo() - local isTeam = (currentBoardType == "TeamScore" or currentBoardType == "TeamList") - local isScore = (currentBoardType == "TeamScore" or currentBoardType == "PlayerScore") - return isTeam, isScore - end - - - local function recomputeTeamScore(team, column) - if not team or team == "Neutral" then - return - end - - local function recomputeScoreHelper(statChangers) - if statChangers and column <= #statChangers then - local sum = 0 - for i, p in ipairs(teamTable[team].Players) do - if playerTable[p].StatValues and column <= #playerTable[p].StatValues then - sum = sum + playerTable[p].StatValues[column].Value - end - end - statChangers[column](sum) - end - end - - recomputeScoreHelper(teamTable[team].StatChangersSmall) - recomputeScoreHelper(teamTable[team].StatChangersBig) - end - local function recomputeCompleteTeamScore(team) - local col = 1 - while col <= currentStatCount do - recomputeTeamScore(team, col) - col = col + 1 - end - end - removeFromTeam = function(player) - if playerTable[player].CurrentTeam ~= nil and teamTable[playerTable[player].CurrentTeam] ~= nil then - ArrayRemove(teamTable[playerTable[player].CurrentTeam].Players, player) - recomputeCompleteTeamScore(playerTable[player].CurrentTeam) - playerTable[player].CurrentTeam = nil - end - end - - local function assignToTeam(player) - local isTeam, isScore = getBoardTypeInfo() - - if isTeam then - local newTeam = nil - - if player.Neutral or teamColorTable[player.TeamColor.Name] == nil then - newTeam = "Neutral" - else - newTeam = teamColorTable[player.TeamColor.Name] - end - - if playerTable[player].CurrentTeam == newTeam then - return - end - - local oldTeam = playerTable[player].LastTeam - removeFromTeam(player) - - playerTable[player].CurrentTeam = newTeam - - if teamTable[oldTeam] and teamTable[oldTeam]["NameChangeFuncBig"] then - if #teamTable[oldTeam].Players < 1 then - teamTable[oldTeam]["NameChangeFuncBig"](" " .. oldTeam.Name) - else - teamTable[oldTeam]["NameChangeFuncBig"](" " .. oldTeam.Name .. " (" .. tostring(#teamTable[oldTeam].Players) ..")") - end - end - - if teamTable[newTeam] then - table.insert(teamTable[newTeam].Players, player) - if newTeam["Name"] then - if teamTable[newTeam]["NameChangeFuncBig"] then - if #teamTable[newTeam].Players < 1 then - teamTable[newTeam]["NameChangeFuncBig"](" " .. newTeam.Name) - else - teamTable[newTeam]["NameChangeFuncBig"](" " .. newTeam.Name .. " (" .. tostring(#teamTable[newTeam].Players) ..")") - end - end - end - end - - if newTeam == "Neutral" then - updatePlayerNameColor(player, nil) - else - updatePlayerNameColor(player, player.TeamColor) - end - - playerTable[player].LastTeam = newTeam - - recomputeCompleteTeamScore(newTeam) - - --Relayout - if sortPlayerListsFunction then - sortPlayerListsFunction() - end - end - end - - local function buildTeamObject(team, numStatColumns, suffix) - local isTeam, isScore = getBoardTypeInfo() - local teamObject, changeFunc = createTeamName(team.Name, team.TeamColor) - teamObject.NameLabel.Text = " " .. team.Name .. " (0)" - if not teamTable[team] then - teamTable[team] = {} - end - teamTable[team]["NameObject" .. suffix] = teamObject - teamTable[team]["NameChangeFunc" .. suffix] = changeFunc - if isScore then - local statObject - local textChangers - teamObject, statObject, textChangers = createStatColumns(teamObject, numStatColumns, true, suffix == "Big") - teamTable[team]["StatObject" .. suffix] = statObject - teamTable[team]["StatChangers" .. suffix] = textChangers - end - teamTable[team]["MainObject" .. suffix] = teamObject - changeFunc(" " .. team.Name) - if not teamTable[team].Players then - teamTable[team].Players = {} - else - if suffix ~= "Small" and #teamTable[team].Players > 0 then - changeFunc(" " .. team.Name .. " (" .. tostring(#teamTable[team].Players) ..")") - end - end - - return teamObject - end - - local currentContextMenuPlayer = nil - local function updatePlayerContextMenu(player,x,y) - currentContextMenuPlayer = player - local elementHeight = 18 - local function highlight(button) - button.TextColor3 = Color3.new(0,0,0) - button.BackgroundColor3 = Color3.new(0.8,0.8,0.8) - end - local function clearHighlight(button) - button.TextColor3 = Color3.new(1,1,1) - button.BackgroundColor3 = Color3.new(0,0,0) - end - if playerContextMenu == nil then - elementNames = {} - elementNameToElement = {} - - for i, contextElement in ipairs(contextMenuElements) do - table.insert(elementNames, contextElement.Text) - elementNameToElement[tostring(contextElement.Text)] = contextElement - end - - playerContextMenu = Instance.new("TextButton") - playerContextMenu.Name = "PlayerListContextMenu" - playerContextMenu.Style = Enum.ButtonStyle.RobloxButton - playerContextMenu.Text = "" - playerContextMenu.Visible = false - playerContextMenu.ZIndex = 4 - - playerContextMenu.MouseLeave:connect(function() - local menuChildren = playerContextMenu:GetChildren() - for i = 1, #menuChildren do - if menuChildren[i].Name == "ChoiceButton" then - menuChildren[i].TextColor3 = Color3.new(1,1,1) - menuChildren[i].BackgroundTransparency = 1 - end - end - playerContextMenu.Visible = false - inContextMenu = false - end) - - playerContextMenu.MouseEnter:connect(function() - inContextMenu = true - end) - - for i = 1, #elementNames do - local newElementButton = Instance.new("TextButton") - newElementButton.Name = "ChoiceButton" - newElementButton.Text = elementNames[i] - newElementButton.TextColor3 = Color3.new(1,1,1) - newElementButton.Font = Enum.Font.Arial - newElementButton.FontSize = Enum.FontSize.Size14 - newElementButton.BackgroundTransparency = 1 - newElementButton.TextWrap = true - newElementButton.Size = UDim2.new(1,0,0,elementHeight) - newElementButton.Position = UDim2.new(0,0,0,elementHeight * (i - 1)) - newElementButton.ZIndex = playerContextMenu.ZIndex + 1 - - newElementButton.MouseEnter:connect(function() - newElementButton.TextColor3 = Color3.new(0,0,0) - newElementButton.BackgroundTransparency = 0 - end) - - newElementButton.MouseLeave:connect(function() - newElementButton.TextColor3 = Color3.new(1,1,1) - newElementButton.BackgroundTransparency = 1 - end) - - newElementButton.MouseButton1Click:connect(function() - local element = elementNameToElement[newElementButton.Text] - pcall(function() element.DoIt(currentContextMenuPlayer) end) - playerContextMenu.Visible = false - newElementButton.TextColor3 = Color3.new(1,1,1) - newElementButton.BackgroundTransparency = 1 - end) - - newElementButton.Parent = playerContextMenu - end - - robloxLock(playerContextMenu) - playerContextMenu.Parent = script.Parent - - end - - local visibleElements = 0 - for i, contextElement in ipairs(contextMenuElements) do - local isVisible = false - - if contextElement.IsVisible then - local success, visible = pcall(function() return contextElement.IsVisible(currentContextMenuPlayer) end) - if success then - isVisible = visible - else - print("Error in IsVisible call: " .. visible) - end - end - - if isVisible then - local foundElement = false - for i = 1, #elementNames do - if elementNames[i] == contextElement.Text then - foundElement = true - break - end - end - if not foundElement then - table.insert(elementNames,contextElement.Text) - end - visibleElements = visibleElements + 1 - else - for i = 1, #elementNames do - if elementNames[i] == contextElement.Text then - table.remove(elementNames,i) - break - end - end - end - end - playerContextMenu.Size = UDim2.new(0, 150, 0, elementHeight + (elementHeight * visibleElements) ) - - if x and y then - x = x - (playerContextMenu.AbsoluteSize.X/2) - if x + playerContextMenu.AbsoluteSize.X >= script.Parent.AbsoluteSize.X then - x = script.Parent.AbsoluteSize.X - playerContextMenu.AbsoluteSize.X - end - playerContextMenu.Position = UDim2.new(0, x, 0, y - 3) - end - - local elementPos = 0 - local contextChildren = playerContextMenu:GetChildren() - for i = 1, #contextChildren do - if contextChildren[i]:IsA("GuiObject") and contextChildren[i].Name == "ChoiceButton" then - contextChildren[i].Visible = false - for j = 1, #elementNames do - if elementNames[j] == contextChildren[i].Text then - contextChildren[i].Visible = true - contextChildren[i].Position = UDim2.new(0,0,0,elementPos * elementHeight) - elementPos = elementPos + 1 - break - end - end - end - end - end - - local function playerContextMenuHasItems() - if playerContextMenu then - local children = playerContextMenu:GetChildren() - for i = 1, #children do - if children[i]:IsA("GuiObject") and children[i].Name == "ChoiceButton" and children[i].Visible then - return true - end - end - end - return false - end - - local function showPlayerMenu(player, x, y) - updatePlayerContextMenu(player,x,y) - if not playerContextMenuHasItems() then return end -- don't show if we have nothing to show - playerContextMenu.Visible = true - end - - local function buildPlayerObject(player, numStatColumns, suffix) - if not player then return nil end - - local isTeam, isScore = getBoardTypeInfo() - - local playerObject = nil - local changePlayerNameFunction = nil - local currentColor = nil - if isTeam and not player.Neutral then - currentColor = player.TeamColor.Color - else - currentColor = Color3.new(1,1,1) - end - playerObject, changePlayerNameFunction = createPlayerName(player.Name, player.MembershipType, currentColor, getFriendStatus(player)) - - if not playerTable[player] then - playerTable[player] = {} - end - if not playerTable[player].Connections then - playerTable[player].Connections = {} - end - if not playerTable[player].CurrentTeam then - playerTable[player].CurrentTeam = nil - end - if not playerTable[player].LastTeam then - playerTable[player].LastTeam = nil - end - playerTable[player]["NameObject" .. suffix] = playerObject - playerTable[player]["ChangeName" .. suffix] = changePlayerNameFunction - - if isScore then - local statObject = nil - local textChangers = nil - playerObject, statObject, textChangers = createStatColumns(playerObject, numStatColumns, false, suffix == "Big") - playerTable[player]["StatObject" .. suffix]= statObject - playerTable[player]["StatChangers" .. suffix] = textChangers - - local statValues, leaderstats = getStatValuesForPlayer(player) - if not statValues or #statValues < numStatColumns then - if not playerTable[player].LeaderStatConnections then - playerTable[player].LeaderStatConnections = {} - end - --Setup a listener to see when this data gets filled in - if not leaderstats then - --We don't even have a leaderstats child, wait for one - table.insert(playerTable[player].LeaderStatConnections, - player.ChildAdded:connect( - function(child) - if child.Name == "leaderstats" then - --Connections will be torn down - recreatePlayerFunction(player) - else - table.insert(playerTable[player].LeaderStatConnections, - child.Changed:connect( - function(prop) - if prop == "Name" and child.Name == "leaderstats" then - --Connections will be torn down - recreatePlayerFunction(player) - end - end)) - end - end)) - else - --We have a leaderstats, but not enough children, recreate if we get them - table.insert(playerTable[player].LeaderStatConnections, - leaderstats.ChildAdded:connect( - function(child) - --TODO only look for IntValue - recreatePlayerFunction(player) - end) - ) - table.insert(playerTable[player].LeaderStatConnections, - leaderstats.AncestryChanged:connect( - function(child) - --We got deleted, try again - recreatePlayerFunction(player) - end) - ) - end - end - if statValues then - if not playerTable[player].StatValues then - playerTable[player].StatValues = {} - end - local pos = 1 - while pos <= numStatColumns and pos <= #statValues do - local currentColumn = pos - local statValue = statValues[pos] - local statChanger = textChangers[pos] - - local updateStat = function(val) - statChanger(val) - if playerTable[player] ~= nil then recomputeTeamScore(playerTable[player].CurrentTeam, currentColumn) end - end - if pos > #playerTable[player].StatValues then - table.insert(playerTable[player].StatValues, statValue) - end - - if type(statValue) ~= "number" and statValue["Changed"] then - table.insert(playerTable[player].Connections, - statValue.Changed:connect(updateStat) - ) - end - - table.insert(playerTable[player].Connections, - statValue.AncestryChanged:connect( - function() - recreatePlayerFunction(player) - end) - ) - updateStat(statValue.Value) - pos = pos + 1 - end - end - end - - if supportFriends and player ~= game.Players.LocalPlayer and player.userId > 0 and game.Players.LocalPlayer.userId > 0 then - local button = Instance.new("TextButton") - button.Name = playerObject.Name .. "Button" - button.Text = "" - button.Active = false - button.Size = playerObject.Size - button.Position = playerObject.Position - button.BackgroundColor3 = playerObject.BackgroundColor3 - - local secondButton = Instance.new("TextButton") - secondButton.Name = playerObject.Name .. "RealButton" - secondButton.Text = "" - secondButton.BackgroundTransparency = 1 - secondButton.BackgroundColor3 = playerObject.BackgroundColor3 - local theNameLabel = playerObject:findFirstChild("NameLabel",true) - secondButton.Parent.BackgroundTransparency = 1 - secondButton.Parent.Visible = true - secondButton.ZIndex = 2 - secondButton.Size = UDim2.new(1,0,1,0) - - local previousTransparency = nil - table.insert(playerTable[player].Connections, - secondButton.MouseEnter:connect( - function(x,y) - if playerContextMenu and playerContextMenu.Visible then - return - end -- don't update if we currently see it - - updatePlayerContextMenu(player,x,y) - if not playerContextMenuHasItems() then return end -- don't show if we have nothing to show - - if previousTransparency == nil then - previousTransparency = secondButton.BackgroundTransparency - end - secondButton.Parent.BackgroundTransparency = 0 - end)) - table.insert(playerTable[player].Connections, - secondButton.MouseLeave:connect( - function() - if previousTransparency ~= nil then - previousTransparency = nil - end - delay(0.01,function() - if playerContextMenu and not inContextMenu then - playerContextMenu.Visible = false - end - end) - secondButton.Parent.BackgroundTransparency = 1 - end)) - - local mouseDownX, mouseDownY - table.insert(playerTable[player].Connections, - secondButton.MouseButton1Down:connect(function(x,y) - mouseDownX = x - mouseDownY = y - end)) - table.insert(playerTable[player].Connections, - secondButton.MouseButton1Click:connect(function() - showPlayerMenu(player, mouseDownX, secondButton.AbsolutePosition.Y + secondButton.AbsoluteSize.Y ) - end)) - playerObject.BackgroundTransparency = 1 - playerObject.Size = UDim2.new(1,0,1,0) - playerObject.Position = UDim2.new(0,0,0,0) - playerObject.Parent = button - - playerTable[player]["MainObject" .. suffix] = button - - playerObject = button - else - playerTable[player]["MainObject" .. suffix] = playerObject - - if player == game.Players.LocalPlayer and supportFriends then - table.insert(playerTable[player].Connections, - player.FriendStatusChanged:connect( - function(otherPlayer, friendStatus) - if friendRequestBlacklist[otherPlayer] then - updatePlayerFriendStatus(playerTable[otherPlayer]["NameObject" .. suffix], Enum.FriendStatus.NotFriend) - elseif playerTable[otherPlayer] then - updatePlayerFriendStatus(playerTable[otherPlayer]["NameObject" .. suffix], friendStatus) - end - end) - ) - end - end - table.insert(playerTable[player].Connections, - player.Changed:connect( - function(prop) - if prop == "MembershipType" then - updatePlayerName(playerTable[player]["NameObject" .. suffix], player.MembershipType, currentColor) - elseif prop == "Name" then - playerTable[player]["ChangeName" .. suffix](player.Name) - elseif prop == "Neutral" or prop == "TeamColor" then - assignToTeam(player) - end - end) - ) - return playerObject - end - - local function doSort(tableToSort, objectName, order, startPos, sortType, ascending) - local orderedPlayerTable = {} - getLocalPlayer = false - for i, player in ipairs(tableToSort) do - if playerTable[player] then - if playerTable[player][objectName] ~= nil then - if player ~= game.Players.LocalPlayer then - table.insert(orderedPlayerTable,playerTable[player][objectName]) - else - getLocalPlayer = true - end - end - end - end - - if sortType == nil then -- default back to alphabetical sort - table.sort(orderedPlayerTable,function(a,b) - return string.lower(a:FindFirstChild("FullNameLabel",true).Text) < string.lower(b:FindFirstChild("FullNameLabel",true).Text) - end) - else -- we are sorting by a value - table.sort(orderedPlayerTable,function(a,b) - if ascending then - currentSortName = "" - return tonumber(a:FindFirstChild(sortType,true).Text) > tonumber(b:FindFirstChild(sortType,true).Text) - else - currentSortName = sortType - return tonumber(a:FindFirstChild(sortType,true).Text) < tonumber(b:FindFirstChild(sortType,true).Text) - end - end) - end - if getLocalPlayer and playerTable[game.Players.LocalPlayer] and playerTable[game.Players.LocalPlayer][objectName] then - table.insert(orderedPlayerTable,1,playerTable[game.Players.LocalPlayer][objectName]) - end - for i = 1, #orderedPlayerTable do - order[orderedPlayerTable[i]] = startPos - startPos = startPos + 1 - end - - return startPos - end - - local function orderScrollList(scrollOrder, objectName, scrollFrame, sortType, ascending) - local pos = 0 - local order = {} - local isTeam, isScore = getBoardTypeInfo() - for i, obj in ipairs(scrollOrder) do - order[obj] = 0 - end - - if isTeam then - local teams = getTeams() - for i, team in ipairs(teams) do - if teamTable[team][objectName] then - order[teamTable[team][objectName]] = pos - pos = pos + 1 - end - pos = doSort(teamTable[team].Players, objectName, order, pos, sortType, ascending) - end - - if #teamTable["Neutral"].Players > 0 then - teamTable["Neutral"][objectName].Parent = scrollFrame - order[teamTable["Neutral"][objectName]] = pos - pos = pos + 1 - doSort(teamTable["Neutral"].Players, objectName, order, pos, sortType, ascending) - else - teamTable["Neutral"][objectName].Parent = nil - end - else - local players = getPlayers() - doSort(players, objectName, order, pos, sortType, ascending) - end - - table.sort(scrollOrder, - function(a,b) - return order[a] < order[b] - end) - end - - local function createPlayerListBasics(frame, isBig) - local headerFrame = Instance.new("Frame") - headerFrame.Name = "Header" - headerFrame.BackgroundTransparency = 1 - headerFrame.Size = UDim2.new(1,-13,0,26) - headerFrame.Position = UDim2.new(0,0,0,0) - headerFrame.Parent = frame - - local lowerPaneFrame = Instance.new("Frame") - lowerPaneFrame.Name = "ScrollingArea" - lowerPaneFrame.BackgroundTransparency = 1 - lowerPaneFrame.Size = UDim2.new(1,-3,1,-26) - if not isBig then lowerPaneFrame.Size = UDim2.new(1,-3,1,-30) end - lowerPaneFrame.Position = UDim2.new(0,0,0,26) - lowerPaneFrame.Parent = frame - - local scrollOrder = {} - local scrollFrame, scrollUp, scrollDown, recalculateScroll, scrollBar = RbxGui.CreateScrollingFrame(scrollOrder) - - scrollBar.Size = UDim2.new(0, 17, 1, -36) - if isBig then scrollBar.Size = UDim2.new(0, 17, 1, -61) end - scrollBar.Parent = lowerPaneFrame - - scrollFrame.Parent = lowerPaneFrame - scrollUp.Parent = lowerPaneFrame - scrollDown.Parent = lowerPaneFrame - - if isBig then - scrollFrame.Position = UDim2.new(0,0,0,0) - scrollUp.Position = UDim2.new(1,-41,0,5) - scrollDown.Position = UDim2.new(1,-41,1,-35) - scrollBar.Position = UDim2.new(1, -41, 0, 24) - - scrollFrame.Size = UDim2.new(1,-48,1,-16) - headerFrame.Size = UDim2.new(1,-20,0,26) - - else - scrollBar.Position = UDim2.new(1, -15, 0, 14) - scrollBar.Size = UDim2.new(0,17,1,-36) - scrollFrame.Position = UDim2.new(0,1,0,0) - scrollUp.Position = UDim2.new(1,-15,0,-5) - scrollDown.Position = UDim2.new(1,-15,1,-20) - - lowerPaneFrame.Position = UDim2.new(0,0,0,30) - - local toggleScrollBar = function(visible) - if visible then - scrollFrame.Size = UDim2.new(1,-16,1,0) - headerFrame.Size = UDim2.new(1,-16,0,smallWindowHeaderYSize) - else - scrollFrame.Size = UDim2.new(1,0,1,0) - headerFrame.Size = UDim2.new(1,0,0,smallWindowHeaderYSize) - end - scrollUp.Visible = visible - scrollDown.Visible = visible - scrollBar.Visible = visible - end - scrollUp.Changed:connect(function(prop) - if prop == "Active" then - toggleScrollBar(scrollUp.Active or scrollDown.Active) - end - end) - - scrollDown.Changed:connect(function(prop) - if prop == "Active" then - toggleScrollBar(scrollUp.Active or scrollDown.Active) - end - end) - - toggleScrollBar(scrollUp.Active or scrollDown.Active) - end - return headerFrame, scrollFrame, recalculateScroll, scrollOrder - end - - createBoardsFunction = function (boardType, numStatColumns) - local updatePlayerCount = function() - return #getPlayers() - end - - local smallFrame = Instance.new("Frame") - smallFrame.Name = "SmallPlayerlist" - smallFrame.Position = smallWindowPosition - smallFrame.Active = false - smallFrame.Size = smallWindowSize - smallFrame.BackgroundColor3 = Color3.new(0,0,0) - smallFrame.BackgroundTransparency = 0.7 - smallFrame.BorderSizePixel = 0 - - local bigFrame = Instance.new("Frame") - bigFrame.Name = "BigPlayerlist" - bigFrame.Size = bigWindowSize - bigFrame.Position = bigWindowPosition - bigFrame.BackgroundColor3 = Color3.new(0,0,0) - bigFrame.BackgroundTransparency = 0.7 - bigFrame.BorderSizePixel = 0 - bigFrame.Visible = false - - local bigFrameWrapper = Instance.new("Frame") - bigFrameWrapper.Name = "Expander" - bigFrameWrapper.Size = UDim2.new(1,21,1,16) - bigFrameWrapper.Position = UDim2.new(0, 0, 0,0) - bigFrameWrapper.BackgroundTransparency = 1 - bigFrameWrapper.Parent = bigFrame - - local smallHeaderFrame, scrollFrameSmall, recalculateScrollSmall, scrollOrderSmall = createPlayerListBasics(smallFrame, false) - local bigHeaderFrame, scrollFrameBig, recalculateScrollBig, scrollOrderBig = createPlayerListBasics(bigFrameWrapper, true) - - local playerListButton = Instance.new("ImageButton") - playerListButton.Name = "GoBigButton" - playerListButton.BackgroundTransparency = 1 - playerListButton.Image = "rbxasset://textures/ui/playerlist_small_maximize.png" - playerListButton.Size = UDim2.new(0.0, 35, 0, 29) - playerListButton.Position = UDim2.new(0, 0, 0, 0) - playerListButton.MouseButton1Click:connect( - function() - toggleBigWindow() - end) - playerListButton.Parent = smallHeaderFrame - - playerListButton = Instance.new("ImageButton") - playerListButton.Name = "CloseButton" - playerListButton.BackgroundTransparency = 1 - playerListButton.Image = "rbxasset://textures/ui/playerlist_small_hide.png" - playerListButton.Size = UDim2.new(0.0, 38, 0, 29) - playerListButton.Position = UDim2.new(0, 35, 0, 0) - playerListButton.MouseButton1Click:connect( - function() - transitionWindowsFunction("None") - end) - playerListButton.Parent = smallHeaderFrame - - playerListButton = Instance.new("ImageButton") - playerListButton.Name = "CloseButton" - playerListButton.Image = "rbxasset://textures/ui/playerlist_big_hide.png" - playerListButton.BackgroundTransparency = 1 - playerListButton.Size = UDim2.new(0.0, 29, 0, 29) - playerListButton.Position = UDim2.new(1, -30, 0.5, -13) - playerListButton.MouseButton1Click:connect( - function() - toggleBigWindow() - end) - playerListButton.Parent = bigHeaderFrame - - local placeName = Instance.new("TextButton") - placeName.Name = "PlaceName" - placeName.Text = " Players (" .. tostring(updatePlayerCount()) .. ")" - placeName.AutoButtonColor = false - placeName.FontSize = Enum.FontSize.Size24 - placeName.TextXAlignment = Enum.TextXAlignment.Left - placeName.Font = Enum.Font.ArialBold - placeName.BorderSizePixel = 0 - placeName.BackgroundColor3 = Color3.new(0,0,0) - placeName.BackgroundTransparency = 1 - placeName.TextColor3 = Color3.new(1,1,1) - placeName.Size = UDim2.new(0.4, 0, 1, 0) - placeName.Position = UDim2.new(0, 0, 0.0, 0) - placeName = RbxGui.AutoTruncateTextObject(placeName) - placeName.Parent = bigHeaderFrame - - placeName.MouseEnter:connect(function() - placeName.BackgroundTransparency = 0.2 - end) - - placeName.MouseLeave:connect(function() - placeName.BackgroundTransparency = 1 - end) - - placeName.MouseButton1Click:connect(function() - sortPlayerListsFunction() - end) - - currentBoardType = boardType - currentStatCount = numStatColumns - local isTeam, isScore = getBoardTypeInfo() - local players = getPlayers() - - if isScore then - local statColumns = getStatColumns(players) - numStatColumns = #statColumns - if numStatColumns > 3 then - numStatColumns = 3 - end - createStatHeaders(statColumns, numStatColumns, false).Parent = smallHeaderFrame - createStatHeaders(statColumns, currentStatCount, true).Parent = bigHeaderFrame - end - - --Clean up all old stuff - resetPlayerTable() - updatePlayerCount() - - for i, player in ipairs(players) do - local playerObject = buildPlayerObject(player, numStatColumns, "Small") - table.insert(scrollOrderSmall, playerObject) - playerObject.Parent = scrollFrameSmall - - playerObject = buildPlayerObject(player, currentStatCount, "Big") - table.insert(scrollOrderBig, playerObject) - playerObject.Parent = scrollFrameBig - end - - --Clean up old stuff - resetTeamTable() - - local teamStatObjects = {} - if isTeam then - local teams = getTeams() - local i = #teams - while i >= 1 do - --We go backwards so the "first" team color gets the team - local team = teams[i] - teamColorTable[team.TeamColor.Name] = team - i = i - 1 - end - - --Adding/Removing a Team causes a full invalidation of the board - for i, team in ipairs(teams) do - local teamObject = buildTeamObject(team, numStatColumns, "Small") - table.insert(scrollOrderSmall, teamObject) - teamObject.Parent = scrollFrameSmall - - teamObject = buildTeamObject(team, currentStatCount, "Big") - table.insert(scrollOrderBig, teamObject) - teamObject.Parent = scrollFrameBig - end - - teamTable["Neutral"] = {} - teamTable["Neutral"].Players = {} - - local neutralTeamObject = createTeamName("Neutral", BrickColor.palette(8)) - teamTable["Neutral"].NameObjectSmall = neutralTeamObject - teamTable["Neutral"].StatObjectSmall = nil - teamTable["Neutral"].MainObjectSmall = neutralTeamObject - table.insert(scrollOrderSmall, neutralTeamObject) - - neutralTeamObject = createTeamName("Neutral", BrickColor.palette(8)) - teamTable["Neutral"].NameObjectBig = neutralTeamObject - teamTable["Neutral"].StatObjectBig = nil - teamTable["Neutral"].MainObjectBig = neutralTeamObject - table.insert(scrollOrderBig, neutralTeamObject) - - local neutralPlayers = {} - for i, player in ipairs(players) do - assignToTeam(player) - end - end - - removePlayerFunction = function(player) - if playerTable[player] then - clearTableEntry(player, playerTable[player]) - - placeName.Text = " Players (" .. tostring(updatePlayerCount()) .. ")" - - ArrayRemove(scrollOrderSmall, playerTable[player].MainObjectSmall) - ArrayRemove(scrollOrderBig, playerTable[player].MainObjectBig) - - playerTable[player] = nil - recalculateSmallPlayerListSize(smallFrame) - end - end - recreatePlayerFunction = function(player) - placeName.Text = " Players (" .. tostring(updatePlayerCount()) .. ")" - - removePlayerFunction(player) - - local playerObject = buildPlayerObject(player, numStatColumns, "Small") - table.insert(scrollOrderSmall, playerObject) - robloxLock(playerObject) - playerObject.Parent = scrollFrameSmall - - playerObject = buildPlayerObject(player, currentStatCount, "Big") - table.insert(scrollOrderBig, playerObject) - robloxLock(playerObject) - playerObject.Parent = scrollFrameBig - - local isTeam, isScore = getBoardTypeInfo() - if isTeam then - assignToTeam(player) - end - - sortPlayerListsFunction() - recalculateSmallPlayerListSize(smallFrame) - end - - if screenResizeCon then screenResizeCon:disconnect() end - screenResizeCon = screen.Changed:connect( - function(prop) - if prop == "AbsoluteSize" then - wait() - recalculateSmallPlayerListSize(smallFrame) - end - end) - - sortPlayerListsFunction = function(sortType, ascending) - orderScrollList(scrollOrderSmall, "MainObjectSmall", scrollFrameSmall, sortType, ascending) - recalculateScrollSmall() - createAlternatingRows(scrollOrderSmall) - - orderScrollList(scrollOrderBig, "MainObjectBig", scrollFrameBig, sortType, ascending) - recalculateScrollBig() - createAlternatingRows(scrollOrderBig) - end - - sortPlayerListsFunction() - - robloxLock(smallFrame) - robloxLock(bigFrame) - return smallFrame, bigFrame - end - - --Teams changing invalidates the whole board - local function teamsChanged() - if debounceTeamsChanged then - return - end - - debounceTeamsChanged = true - wait() - rebuildBoard(script.Parent, determineBoardType()) - debounceTeamsChanged = false - end - - - local checkIfBoardChanged = function() - local newBoardType, numStats = determineBoardType() - if newBoardType ~= currentBoardType or numStats ~= currentStatCount then - rebuildBoard(script.Parent, newBoardType, numStats) - end - end - - local function buildPlayerList() - waitForChild(game, "Players") - waitForProperty(game.Players, "LocalPlayer") - - local teams = game:GetService("Teams") - if teams then - local teamConnections = {} - - teams.ChildAdded:connect( - function(child) - if child:IsA("Team") then - teamsChanged() - teamConnections[child] = child.Changed:connect( - function(prop) - if prop == "TeamColor" or prop == "Name" then - --Rebuild when things change - teamsChanged() - end - end) - end - end) - teams.ChildRemoved:connect( - function(child) - if child:IsA("Team") then - if teamConnections[child] then - teamConnections[child]:disconnect() - teamConnections[child] = nil - end - teamsChanged() - end - end) - end - - game.Players.ChildAdded:connect( - function(player) - if player:IsA("Player") then - addPlayerFunction(player) - end - end) - - game.Players.ChildRemoved:connect( - function(player) - if player:IsA("Player") then - if removePlayerFunction then - removePlayerFunction(player) - end - end - end) - - rebuildBoard(script.Parent, determineBoardType()) - - delay(0, - function() - while true do - wait(5) - checkIfBoardChanged() - end - end) - end - - buildPlayerList() -end - -if not personalServerPlace then -- one more backup check - local theBool = game.Workspace:FindFirstChild("PSVariable") - if theBool and theBool:IsA("BoolValue") then - personalServerPlace = true - end -end - -if personalServerPlace then - addPersonalServerContext() - setupBuildToolManagement() -else - local psVarCon = nil - psVarCon = game.Workspace.ChildAdded:connect(function(child) - if child:IsA("BoolValue") and child.Name == "PSVariable" then - psVarCon:disconnect() - personalServerPlace = true - addPersonalServerContext() - setupBuildToolManagement() - end - end) -end - true - - - \ No newline at end of file diff --git a/clients/2011M/content/fonts/Arial-18pt.fontdef b/clients/2011M/content/fonts/Arial-18pt.fontdef new file mode 100644 index 0000000..dad36a6 --- /dev/null +++ b/clients/2011M/content/fonts/Arial-18pt.fontdef @@ -0,0 +1,101 @@ +fonts/Arial-18pt +{ + type image + source fonts/Arial-18pt.png + + glyph u0032 0.1074219 0.3984375 0.1210938 0.453125 + glyph ! 0.1074219 0 0.1210938 0.0546875 + glyph " 0.2070313 0 0.2285156 0.0546875 + glyph # 0.3066406 0 0.3339844 0.0546875 + glyph $ 0.40625 0 0.4335938 0.0546875 + glyph % 0.5058594 0 0.5546875 0.0546875 + glyph & 0.6054688 0 0.6367188 0.0546875 + glyph ' 0.7050781 0 0.71875 0.0546875 + glyph ( 0.8046875 0 0.8183594 0.0546875 + glyph ) 0.9042969 0 0.9179688 0.0546875 + glyph * 0.0078125 0.09960938 0.02539063 0.1542969 + glyph + 0.1074219 0.09960938 0.1367188 0.1542969 + glyph , 0.2070313 0.09960938 0.2207031 0.1542969 + glyph - 0.3066406 0.09960938 0.3261719 0.1542969 + glyph . 0.40625 0.09960938 0.4199219 0.1542969 + glyph / 0.5058594 0.09960938 0.5234375 0.1542969 + glyph 0 0.6054688 0.09960938 0.6328125 0.1542969 + glyph 1 0.7050781 0.09960938 0.7324219 0.1542969 + glyph 2 0.8046875 0.09960938 0.8320313 0.1542969 + glyph 3 0.9042969 0.09960938 0.9316406 0.1542969 + glyph 4 0.0078125 0.1992188 0.03515625 0.2539063 + glyph 5 0.1074219 0.1992188 0.1347656 0.2539063 + glyph 6 0.2070313 0.1992188 0.234375 0.2539063 + glyph 7 0.3066406 0.1992188 0.3339844 0.2539063 + glyph 8 0.40625 0.1992188 0.4335938 0.2539063 + glyph 9 0.5058594 0.1992188 0.5332031 0.2539063 + glyph : 0.6054688 0.1992188 0.6191406 0.2539063 + glyph ; 0.7050781 0.1992188 0.71875 0.2539063 + glyph < 0.8046875 0.1992188 0.8339844 0.2539063 + glyph = 0.9042969 0.1992188 0.9335938 0.2539063 + glyph > 0.0078125 0.2988281 0.03710938 0.3535156 + glyph ? 0.1074219 0.2988281 0.1347656 0.3535156 + glyph @ 0.2070313 0.2988281 0.2460938 0.3535156 + glyph A 0.3066406 0.2988281 0.3378906 0.3535156 + glyph B 0.40625 0.2988281 0.4394531 0.3535156 + glyph C 0.5058594 0.2988281 0.5410156 0.3535156 + glyph D 0.6054688 0.2988281 0.640625 0.3535156 + glyph E 0.7050781 0.2988281 0.7363281 0.3535156 + glyph F 0.8046875 0.2988281 0.8339844 0.3535156 + glyph G 0.9042969 0.2988281 0.9414063 0.3535156 + glyph H 0.0078125 0.3984375 0.04296875 0.453125 + glyph I 0.1074219 0.3984375 0.1210938 0.453125 + glyph J 0.2070313 0.3984375 0.2324219 0.453125 + glyph K 0.3066406 0.3984375 0.3398438 0.453125 + glyph L 0.40625 0.3984375 0.4335938 0.453125 + glyph M 0.5058594 0.3984375 0.5488281 0.453125 + glyph N 0.6054688 0.3984375 0.640625 0.453125 + glyph O 0.7050781 0.3984375 0.7421875 0.453125 + glyph P 0.8046875 0.3984375 0.8359375 0.453125 + glyph Q 0.9042969 0.3984375 0.9414063 0.453125 + glyph R 0.0078125 0.4980469 0.04101563 0.5527344 + glyph S 0.1074219 0.4980469 0.1386719 0.5527344 + glyph T 0.2070313 0.4980469 0.2363281 0.5527344 + glyph U 0.3066406 0.4980469 0.3417969 0.5527344 + glyph V 0.40625 0.4980469 0.4375 0.5527344 + glyph W 0.5058594 0.4980469 0.5507813 0.5527344 + glyph X 0.6054688 0.4980469 0.6367188 0.5527344 + glyph Y 0.7050781 0.4980469 0.7363281 0.5527344 + glyph Z 0.8046875 0.4980469 0.8359375 0.5527344 + glyph [ 0.9042969 0.4980469 0.9179688 0.5527344 + glyph \ 0.0078125 0.5976563 0.02539063 0.6523438 + glyph ] 0.1074219 0.5976563 0.1210938 0.6523438 + glyph ^ 0.2070313 0.5976563 0.2363281 0.6523438 + glyph _ 0.3066406 0.5976563 0.3320313 0.6523438 + glyph ` 0.40625 0.5976563 0.4179688 0.6523438 + glyph a 0.5058594 0.5976563 0.5332031 0.6523438 + glyph b 0.6054688 0.5976563 0.6347656 0.6523438 + glyph c 0.7050781 0.5976563 0.7324219 0.6523438 + glyph d 0.8046875 0.5976563 0.8339844 0.6523438 + glyph e 0.9042969 0.5976563 0.9316406 0.6523438 + glyph f 0.0078125 0.6972656 0.0234375 0.7519531 + glyph g 0.1074219 0.6972656 0.1367188 0.7519531 + glyph h 0.2070313 0.6972656 0.234375 0.7519531 + glyph i 0.3066406 0.6972656 0.3183594 0.7519531 + glyph j 0.40625 0.6972656 0.4179688 0.7519531 + glyph k 0.5058594 0.6972656 0.53125 0.7519531 + glyph l 0.6054688 0.6972656 0.6171875 0.7519531 + glyph m 0.7050781 0.6972656 0.7480469 0.7519531 + glyph n 0.8046875 0.6972656 0.8320313 0.7519531 + glyph o 0.9042969 0.6972656 0.9335938 0.7519531 + glyph p 0.0078125 0.796875 0.03710938 0.8515625 + glyph q 0.1074219 0.796875 0.1367188 0.8515625 + glyph r 0.2070313 0.796875 0.2246094 0.8515625 + glyph s 0.3066406 0.796875 0.3320313 0.8515625 + glyph t 0.40625 0.796875 0.421875 0.8515625 + glyph u 0.5058594 0.796875 0.5332031 0.8515625 + glyph v 0.6054688 0.796875 0.6308594 0.8515625 + glyph w 0.7050781 0.796875 0.7421875 0.8515625 + glyph x 0.8046875 0.796875 0.8300781 0.8515625 + glyph y 0.9042969 0.796875 0.9296875 0.8515625 + glyph z 0.0078125 0.8964844 0.03125 0.9511719 + glyph { 0.1074219 0.8964844 0.125 0.9511719 + glyph | 0.2070313 0.8964844 0.21875 0.9511719 + glyph } 0.3066406 0.8964844 0.3242188 0.9511719 + glyph ~ 0.40625 0.8964844 0.4355469 0.9511719 +} diff --git a/clients/2011M/content/fonts/Arial-18pt.png b/clients/2011M/content/fonts/Arial-18pt.png new file mode 100644 index 0000000..91d60ec Binary files /dev/null and b/clients/2011M/content/fonts/Arial-18pt.png differ diff --git a/clients/2011M/content/fonts/Arial-48pt.fontdef b/clients/2011M/content/fonts/Arial-48pt.fontdef new file mode 100644 index 0000000..3526206 --- /dev/null +++ b/clients/2011M/content/fonts/Arial-48pt.fontdef @@ -0,0 +1,101 @@ +fonts/Arial-48pt +{ + type image + source fonts/Arial-48pt.png + + glyph u0032 0.1103516 0.3984375 0.1269531 0.4716797 + glyph ! 0.1103516 0 0.1269531 0.07324219 + glyph " 0.2099609 0 0.2373047 0.07324219 + glyph # 0.3095703 0 0.3457031 0.07324219 + glyph $ 0.4091797 0 0.4453125 0.07324219 + glyph % 0.5087891 0 0.5732422 0.07324219 + glyph & 0.6083984 0 0.6494141 0.07324219 + glyph ' 0.7080078 0 0.7255859 0.07324219 + glyph ( 0.8076172 0 0.8242188 0.07324219 + glyph ) 0.9072266 0 0.9238281 0.07324219 + glyph * 0.01074219 0.09960938 0.03320313 0.1728516 + glyph + 0.1103516 0.09960938 0.1494141 0.1728516 + glyph , 0.2099609 0.09960938 0.2275391 0.1728516 + glyph - 0.3095703 0.09960938 0.3349609 0.1728516 + glyph . 0.4091797 0.09960938 0.4267578 0.1728516 + glyph / 0.5087891 0.09960938 0.5302734 0.1728516 + glyph 0 0.6083984 0.09960938 0.6445313 0.1728516 + glyph 1 0.7080078 0.09960938 0.7441406 0.1728516 + glyph 2 0.8076172 0.09960938 0.84375 0.1728516 + glyph 3 0.9072266 0.09960938 0.9433594 0.1728516 + glyph 4 0.01074219 0.1992188 0.046875 0.2724609 + glyph 5 0.1103516 0.1992188 0.1464844 0.2724609 + glyph 6 0.2099609 0.1992188 0.2460938 0.2724609 + glyph 7 0.3095703 0.1992188 0.3457031 0.2724609 + glyph 8 0.4091797 0.1992188 0.4453125 0.2724609 + glyph 9 0.5087891 0.1992188 0.5449219 0.2724609 + glyph : 0.6083984 0.1992188 0.6259766 0.2724609 + glyph ; 0.7080078 0.1992188 0.7255859 0.2724609 + glyph < 0.8076172 0.1992188 0.8466797 0.2724609 + glyph = 0.9072266 0.1992188 0.9462891 0.2724609 + glyph > 0.01074219 0.2988281 0.04980469 0.3720703 + glyph ? 0.1103516 0.2988281 0.1464844 0.3720703 + glyph @ 0.2099609 0.2988281 0.2617188 0.3720703 + glyph A 0.3095703 0.2988281 0.3515625 0.3720703 + glyph B 0.4091797 0.2988281 0.453125 0.3720703 + glyph C 0.5087891 0.2988281 0.5556641 0.3720703 + glyph D 0.6083984 0.2988281 0.6533203 0.3720703 + glyph E 0.7080078 0.2988281 0.7470703 0.3720703 + glyph F 0.8076172 0.2988281 0.8447266 0.3720703 + glyph G 0.9072266 0.2988281 0.9560547 0.3720703 + glyph H 0.01074219 0.3984375 0.05761719 0.4716797 + glyph I 0.1103516 0.3984375 0.1269531 0.4716797 + glyph J 0.2099609 0.3984375 0.2431641 0.4716797 + glyph K 0.3095703 0.3984375 0.3525391 0.4716797 + glyph L 0.4091797 0.3984375 0.4453125 0.4716797 + glyph M 0.5087891 0.3984375 0.5644531 0.4716797 + glyph N 0.6083984 0.3984375 0.6552734 0.4716797 + glyph O 0.7080078 0.3984375 0.7568359 0.4716797 + glyph P 0.8076172 0.3984375 0.8496094 0.4716797 + glyph Q 0.9072266 0.3984375 0.9560547 0.4716797 + glyph R 0.01074219 0.4980469 0.0546875 0.5712891 + glyph S 0.1103516 0.4980469 0.1523438 0.5712891 + glyph T 0.2099609 0.4980469 0.2470703 0.5712891 + glyph U 0.3095703 0.4980469 0.3564453 0.5712891 + glyph V 0.4091797 0.4980469 0.4482422 0.5712891 + glyph W 0.5087891 0.4980469 0.5683594 0.5712891 + glyph X 0.6083984 0.4980469 0.6474609 0.5712891 + glyph Y 0.7080078 0.4980469 0.75 0.5712891 + glyph Z 0.8076172 0.4980469 0.8466797 0.5712891 + glyph [ 0.9072266 0.4980469 0.9238281 0.5712891 + glyph \ 0.01074219 0.5976563 0.03222656 0.6708984 + glyph ] 0.1103516 0.5976563 0.1269531 0.6708984 + glyph ^ 0.2099609 0.5976563 0.2490234 0.6708984 + glyph _ 0.3095703 0.5976563 0.3417969 0.6708984 + glyph ` 0.4091797 0.5976563 0.4238281 0.6708984 + glyph a 0.5087891 0.5976563 0.5429688 0.6708984 + glyph b 0.6083984 0.5976563 0.6464844 0.6708984 + glyph c 0.7080078 0.5976563 0.7421875 0.6708984 + glyph d 0.8076172 0.5976563 0.8457031 0.6708984 + glyph e 0.9072266 0.5976563 0.9414063 0.6708984 + glyph f 0.01074219 0.6972656 0.03027344 0.7705078 + glyph g 0.1103516 0.6972656 0.1474609 0.7705078 + glyph h 0.2099609 0.6972656 0.2460938 0.7705078 + glyph i 0.3095703 0.6972656 0.3242188 0.7705078 + glyph j 0.4091797 0.6972656 0.4238281 0.7705078 + glyph k 0.5087891 0.6972656 0.5419922 0.7705078 + glyph l 0.6083984 0.6972656 0.6230469 0.7705078 + glyph m 0.7080078 0.6972656 0.7626953 0.7705078 + glyph n 0.8076172 0.6972656 0.84375 0.7705078 + glyph o 0.9072266 0.6972656 0.9443359 0.7705078 + glyph p 0.01074219 0.796875 0.04882813 0.8701172 + glyph q 0.1103516 0.796875 0.1484375 0.8701172 + glyph r 0.2099609 0.796875 0.2314453 0.8701172 + glyph s 0.3095703 0.796875 0.3417969 0.8701172 + glyph t 0.4091797 0.796875 0.4296875 0.8701172 + glyph u 0.5087891 0.796875 0.5449219 0.8701172 + glyph v 0.6083984 0.796875 0.640625 0.8701172 + glyph w 0.7080078 0.796875 0.7568359 0.8701172 + glyph x 0.8076172 0.796875 0.8408203 0.8701172 + glyph y 0.9072266 0.796875 0.9394531 0.8701172 + glyph z 0.01074219 0.8964844 0.04199219 0.9697266 + glyph { 0.1103516 0.8964844 0.1318359 0.9697266 + glyph | 0.2099609 0.8964844 0.2246094 0.9697266 + glyph } 0.3095703 0.8964844 0.3310547 0.9697266 + glyph ~ 0.4091797 0.8964844 0.4482422 0.9697266 +} diff --git a/clients/2011M/content/fonts/Arial-48pt.png b/clients/2011M/content/fonts/Arial-48pt.png new file mode 100644 index 0000000..cf48aa1 Binary files /dev/null and b/clients/2011M/content/fonts/Arial-48pt.png differ diff --git a/clients/2011M/content/fonts/ArialBold-18pt.fontdef b/clients/2011M/content/fonts/ArialBold-18pt.fontdef new file mode 100644 index 0000000..ab3e164 --- /dev/null +++ b/clients/2011M/content/fonts/ArialBold-18pt.fontdef @@ -0,0 +1,101 @@ +fonts/ArialBold-18pt +{ + type image + source fonts/ArialBold-18pt.png + + glyph u0032 0.1074219 0.3984375 0.1230469 0.4550781 + glyph ! 0.1074219 0 0.1230469 0.05664063 + glyph " 0.2070313 0 0.2324219 0.05664063 + glyph # 0.3066406 0 0.3378906 0.05664063 + glyph $ 0.40625 0 0.4375 0.05664063 + glyph % 0.5058594 0 0.5566406 0.05664063 + glyph & 0.6054688 0 0.640625 0.05664063 + glyph ' 0.7050781 0 0.7207031 0.05664063 + glyph ( 0.8046875 0 0.8203125 0.05664063 + glyph ) 0.9042969 0 0.9199219 0.05664063 + glyph * 0.0078125 0.09960938 0.02929688 0.15625 + glyph + 0.1074219 0.09960938 0.1367188 0.15625 + glyph , 0.2070313 0.09960938 0.2226563 0.15625 + glyph - 0.3066406 0.09960938 0.328125 0.15625 + glyph . 0.40625 0.09960938 0.421875 0.15625 + glyph / 0.5058594 0.09960938 0.5273438 0.15625 + glyph 0 0.6054688 0.09960938 0.6367188 0.15625 + glyph 1 0.7050781 0.09960938 0.7363281 0.15625 + glyph 2 0.8046875 0.09960938 0.8359375 0.15625 + glyph 3 0.9042969 0.09960938 0.9355469 0.15625 + glyph 4 0.0078125 0.1992188 0.0390625 0.2558594 + glyph 5 0.1074219 0.1992188 0.1386719 0.2558594 + glyph 6 0.2070313 0.1992188 0.2382813 0.2558594 + glyph 7 0.3066406 0.1992188 0.3378906 0.2558594 + glyph 8 0.40625 0.1992188 0.4375 0.2558594 + glyph 9 0.5058594 0.1992188 0.5371094 0.2558594 + glyph : 0.6054688 0.1992188 0.6210938 0.2558594 + glyph ; 0.7050781 0.1992188 0.7207031 0.2558594 + glyph < 0.8046875 0.1992188 0.8339844 0.2558594 + glyph = 0.9042969 0.1992188 0.9335938 0.2558594 + glyph > 0.0078125 0.2988281 0.03710938 0.3554688 + glyph ? 0.1074219 0.2988281 0.1367188 0.3554688 + glyph @ 0.2070313 0.2988281 0.2460938 0.3554688 + glyph A 0.3066406 0.2988281 0.3417969 0.3554688 + glyph B 0.40625 0.2988281 0.4414063 0.3554688 + glyph C 0.5058594 0.2988281 0.5429688 0.3554688 + glyph D 0.6054688 0.2988281 0.6425781 0.3554688 + glyph E 0.7050781 0.2988281 0.7382813 0.3554688 + glyph F 0.8046875 0.2988281 0.8359375 0.3554688 + glyph G 0.9042969 0.2988281 0.9433594 0.3554688 + glyph H 0.0078125 0.3984375 0.04492188 0.4550781 + glyph I 0.1074219 0.3984375 0.1230469 0.4550781 + glyph J 0.2070313 0.3984375 0.2363281 0.4550781 + glyph K 0.3066406 0.3984375 0.34375 0.4550781 + glyph L 0.40625 0.3984375 0.4375 0.4550781 + glyph M 0.5058594 0.3984375 0.5507813 0.4550781 + glyph N 0.6054688 0.3984375 0.6425781 0.4550781 + glyph O 0.7050781 0.3984375 0.7441406 0.4550781 + glyph P 0.8046875 0.3984375 0.8378906 0.4550781 + glyph Q 0.9042969 0.3984375 0.9433594 0.4550781 + glyph R 0.0078125 0.4980469 0.04296875 0.5546875 + glyph S 0.1074219 0.4980469 0.140625 0.5546875 + glyph T 0.2070313 0.4980469 0.2382813 0.5546875 + glyph U 0.3066406 0.4980469 0.34375 0.5546875 + glyph V 0.40625 0.4980469 0.4375 0.5546875 + glyph W 0.5058594 0.4980469 0.5527344 0.5546875 + glyph X 0.6054688 0.4980469 0.640625 0.5546875 + glyph Y 0.7050781 0.4980469 0.7382813 0.5546875 + glyph Z 0.8046875 0.4980469 0.8378906 0.5546875 + glyph [ 0.9042969 0.4980469 0.9238281 0.5546875 + glyph \ 0.0078125 0.5976563 0.02929688 0.6542969 + glyph ] 0.1074219 0.5976563 0.1269531 0.6542969 + glyph ^ 0.2070313 0.5976563 0.2363281 0.6542969 + glyph _ 0.3066406 0.5976563 0.3320313 0.6542969 + glyph ` 0.40625 0.5976563 0.421875 0.6542969 + glyph a 0.5058594 0.5976563 0.5351563 0.6542969 + glyph b 0.6054688 0.5976563 0.6367188 0.6542969 + glyph c 0.7050781 0.5976563 0.734375 0.6542969 + glyph d 0.8046875 0.5976563 0.8359375 0.6542969 + glyph e 0.9042969 0.5976563 0.9355469 0.6542969 + glyph f 0.0078125 0.6972656 0.02734375 0.7539063 + glyph g 0.1074219 0.6972656 0.1386719 0.7539063 + glyph h 0.2070313 0.6972656 0.2382813 0.7539063 + glyph i 0.3066406 0.6972656 0.3222656 0.7539063 + glyph j 0.40625 0.6972656 0.421875 0.7539063 + glyph k 0.5058594 0.6972656 0.5351563 0.7539063 + glyph l 0.6054688 0.6972656 0.6210938 0.7539063 + glyph m 0.7050781 0.6972656 0.75 0.7539063 + glyph n 0.8046875 0.6972656 0.8359375 0.7539063 + glyph o 0.9042969 0.6972656 0.9355469 0.7539063 + glyph p 0.0078125 0.796875 0.0390625 0.8535156 + glyph q 0.1074219 0.796875 0.1386719 0.8535156 + glyph r 0.2070313 0.796875 0.2285156 0.8535156 + glyph s 0.3066406 0.796875 0.3339844 0.8535156 + glyph t 0.40625 0.796875 0.4257813 0.8535156 + glyph u 0.5058594 0.796875 0.5371094 0.8535156 + glyph v 0.6054688 0.796875 0.6328125 0.8535156 + glyph w 0.7050781 0.796875 0.7460938 0.8535156 + glyph x 0.8046875 0.796875 0.8320313 0.8535156 + glyph y 0.9042969 0.796875 0.9316406 0.8535156 + glyph z 0.0078125 0.8964844 0.03515625 0.953125 + glyph { 0.1074219 0.8964844 0.1269531 0.953125 + glyph | 0.2070313 0.8964844 0.21875 0.953125 + glyph } 0.3066406 0.8964844 0.3261719 0.953125 + glyph ~ 0.40625 0.8964844 0.4355469 0.953125 +} diff --git a/clients/2011M/content/fonts/ArialBold-18pt.png b/clients/2011M/content/fonts/ArialBold-18pt.png new file mode 100644 index 0000000..7d034df Binary files /dev/null and b/clients/2011M/content/fonts/ArialBold-18pt.png differ diff --git a/clients/2011M/content/fonts/ArialBold-48pt.fontdef b/clients/2011M/content/fonts/ArialBold-48pt.fontdef new file mode 100644 index 0000000..169f477 --- /dev/null +++ b/clients/2011M/content/fonts/ArialBold-48pt.fontdef @@ -0,0 +1,101 @@ +fonts/ArialBold-48pt +{ + type image + source fonts/ArialBold-48pt.png + + glyph u0032 0.1103516 0.3984375 0.1308594 0.4726563 + glyph ! 0.1103516 0 0.1298828 0.07421875 + glyph " 0.2099609 0 0.2421875 0.07421875 + glyph # 0.3095703 0 0.3505859 0.07421875 + glyph $ 0.4091797 0 0.4501953 0.07421875 + glyph % 0.5087891 0 0.5742188 0.07421875 + glyph & 0.6083984 0 0.6552734 0.07421875 + glyph ' 0.7080078 0 0.7275391 0.07421875 + glyph ( 0.8076172 0 0.8271484 0.07421875 + glyph ) 0.9072266 0 0.9267578 0.07421875 + glyph * 0.01074219 0.09960938 0.0390625 0.1738281 + glyph + 0.1103516 0.09960938 0.1494141 0.1738281 + glyph , 0.2099609 0.09960938 0.2304688 0.1738281 + glyph - 0.3095703 0.09960938 0.3359375 0.1738281 + glyph . 0.4091797 0.09960938 0.4296875 0.1738281 + glyph / 0.5087891 0.09960938 0.5351563 0.1738281 + glyph 0 0.6083984 0.09960938 0.6494141 0.1738281 + glyph 1 0.7080078 0.09960938 0.7490234 0.1738281 + glyph 2 0.8076172 0.09960938 0.8486328 0.1738281 + glyph 3 0.9072266 0.09960938 0.9482422 0.1738281 + glyph 4 0.01074219 0.1992188 0.05175781 0.2734375 + glyph 5 0.1103516 0.1992188 0.1513672 0.2734375 + glyph 6 0.2099609 0.1992188 0.2509766 0.2734375 + glyph 7 0.3095703 0.1992188 0.3505859 0.2734375 + glyph 8 0.4091797 0.1992188 0.4501953 0.2734375 + glyph 9 0.5087891 0.1992188 0.5498047 0.2734375 + glyph : 0.6083984 0.1992188 0.6289063 0.2734375 + glyph ; 0.7080078 0.1992188 0.7285156 0.2734375 + glyph < 0.8076172 0.1992188 0.8466797 0.2734375 + glyph = 0.9072266 0.1992188 0.9462891 0.2734375 + glyph > 0.01074219 0.2988281 0.04980469 0.3730469 + glyph ? 0.1103516 0.2988281 0.1474609 0.3730469 + glyph @ 0.2099609 0.2988281 0.2617188 0.3730469 + glyph A 0.3095703 0.2988281 0.3544922 0.3730469 + glyph B 0.4091797 0.2988281 0.4560547 0.3730469 + glyph C 0.5087891 0.2988281 0.5576172 0.3730469 + glyph D 0.6083984 0.2988281 0.6572266 0.3730469 + glyph E 0.7080078 0.2988281 0.7519531 0.3730469 + glyph F 0.8076172 0.2988281 0.8466797 0.3730469 + glyph G 0.9072266 0.2988281 0.9570313 0.3730469 + glyph H 0.01074219 0.3984375 0.05859375 0.4726563 + glyph I 0.1103516 0.3984375 0.1308594 0.4726563 + glyph J 0.2099609 0.3984375 0.2480469 0.4726563 + glyph K 0.3095703 0.3984375 0.3574219 0.4726563 + glyph L 0.4091797 0.3984375 0.4482422 0.4726563 + glyph M 0.5087891 0.3984375 0.5683594 0.4726563 + glyph N 0.6083984 0.3984375 0.65625 0.4726563 + glyph O 0.7080078 0.3984375 0.7578125 0.4726563 + glyph P 0.8076172 0.3984375 0.8515625 0.4726563 + glyph Q 0.9072266 0.3984375 0.9570313 0.4726563 + glyph R 0.01074219 0.4980469 0.05761719 0.5722656 + glyph S 0.1103516 0.4980469 0.1533203 0.5722656 + glyph T 0.2099609 0.4980469 0.2519531 0.5722656 + glyph U 0.3095703 0.4980469 0.3574219 0.5722656 + glyph V 0.4091797 0.4980469 0.4511719 0.5722656 + glyph W 0.5087891 0.4980469 0.5712891 0.5722656 + glyph X 0.6083984 0.4980469 0.6533203 0.5722656 + glyph Y 0.7080078 0.4980469 0.7509766 0.5722656 + glyph Z 0.8076172 0.4980469 0.8505859 0.5722656 + glyph [ 0.9072266 0.4980469 0.9306641 0.5722656 + glyph \ 0.01074219 0.5976563 0.03710938 0.671875 + glyph ] 0.1103516 0.5976563 0.1337891 0.671875 + glyph ^ 0.2099609 0.5976563 0.2490234 0.671875 + glyph _ 0.3095703 0.5976563 0.3417969 0.671875 + glyph ` 0.4091797 0.5976563 0.4287109 0.671875 + glyph a 0.5087891 0.5976563 0.546875 0.671875 + glyph b 0.6083984 0.5976563 0.6494141 0.671875 + glyph c 0.7080078 0.5976563 0.7460938 0.671875 + glyph d 0.8076172 0.5976563 0.8486328 0.671875 + glyph e 0.9072266 0.5976563 0.9462891 0.671875 + glyph f 0.01074219 0.6972656 0.03417969 0.7714844 + glyph g 0.1103516 0.6972656 0.1494141 0.7714844 + glyph h 0.2099609 0.6972656 0.2509766 0.7714844 + glyph i 0.3095703 0.6972656 0.3291016 0.7714844 + glyph j 0.4091797 0.6972656 0.4287109 0.7714844 + glyph k 0.5087891 0.6972656 0.546875 0.7714844 + glyph l 0.6083984 0.6972656 0.6279297 0.7714844 + glyph m 0.7080078 0.6972656 0.7675781 0.7714844 + glyph n 0.8076172 0.6972656 0.8486328 0.7714844 + glyph o 0.9072266 0.6972656 0.9462891 0.7714844 + glyph p 0.01074219 0.796875 0.05175781 0.8710938 + glyph q 0.1103516 0.796875 0.1513672 0.8710938 + glyph r 0.2099609 0.796875 0.2373047 0.8710938 + glyph s 0.3095703 0.796875 0.3457031 0.8710938 + glyph t 0.4091797 0.796875 0.4345703 0.8710938 + glyph u 0.5087891 0.796875 0.5498047 0.8710938 + glyph v 0.6083984 0.796875 0.6425781 0.8710938 + glyph w 0.7080078 0.796875 0.7617188 0.8710938 + glyph x 0.8076172 0.796875 0.8417969 0.8710938 + glyph y 0.9072266 0.796875 0.9414063 0.8710938 + glyph z 0.01074219 0.8964844 0.04492188 0.9707031 + glyph { 0.1103516 0.8964844 0.1337891 0.9707031 + glyph | 0.2099609 0.8964844 0.2246094 0.9707031 + glyph } 0.3095703 0.8964844 0.3330078 0.9707031 + glyph ~ 0.4091797 0.8964844 0.4482422 0.9707031 +} diff --git a/clients/2011M/content/fonts/ArialBold-48pt.png b/clients/2011M/content/fonts/ArialBold-48pt.png new file mode 100644 index 0000000..63da42d Binary files /dev/null and b/clients/2011M/content/fonts/ArialBold-48pt.png differ diff --git a/clients/2011M/content/fonts/CompositFullAtlasBaseTexture.mesh b/clients/2011M/content/fonts/CompositFullAtlasBaseTexture.mesh new file mode 100644 index 0000000..b7e6595 Binary files /dev/null and b/clients/2011M/content/fonts/CompositFullAtlasBaseTexture.mesh differ diff --git a/clients/2011M/content/fonts/CompositFullAtlasOverlayTexture.mesh b/clients/2011M/content/fonts/CompositFullAtlasOverlayTexture.mesh new file mode 100644 index 0000000..eda1938 Binary files /dev/null and b/clients/2011M/content/fonts/CompositFullAtlasOverlayTexture.mesh differ diff --git a/clients/2011M/content/fonts/CompositLeftArmBase.mesh b/clients/2011M/content/fonts/CompositLeftArmBase.mesh new file mode 100644 index 0000000..5bcc4ae Binary files /dev/null and b/clients/2011M/content/fonts/CompositLeftArmBase.mesh differ diff --git a/clients/2011M/content/fonts/CompositLeftLegBase.mesh b/clients/2011M/content/fonts/CompositLeftLegBase.mesh new file mode 100644 index 0000000..f4712ce Binary files /dev/null and b/clients/2011M/content/fonts/CompositLeftLegBase.mesh differ diff --git a/clients/2011M/content/fonts/CompositPantsTemplate.mesh b/clients/2011M/content/fonts/CompositPantsTemplate.mesh new file mode 100644 index 0000000..756ee03 Binary files /dev/null and b/clients/2011M/content/fonts/CompositPantsTemplate.mesh differ diff --git a/clients/2011M/content/fonts/CompositRightArmBase.mesh b/clients/2011M/content/fonts/CompositRightArmBase.mesh new file mode 100644 index 0000000..02f2721 Binary files /dev/null and b/clients/2011M/content/fonts/CompositRightArmBase.mesh differ diff --git a/clients/2011M/content/fonts/CompositRightLegBase.mesh b/clients/2011M/content/fonts/CompositRightLegBase.mesh new file mode 100644 index 0000000..b287939 Binary files /dev/null and b/clients/2011M/content/fonts/CompositRightLegBase.mesh differ diff --git a/clients/2011M/content/fonts/CompositShirtTemplate.mesh b/clients/2011M/content/fonts/CompositShirtTemplate.mesh new file mode 100644 index 0000000..75487e1 Binary files /dev/null and b/clients/2011M/content/fonts/CompositShirtTemplate.mesh differ diff --git a/clients/2011M/content/fonts/CompositTShirt.mesh b/clients/2011M/content/fonts/CompositTShirt.mesh new file mode 100644 index 0000000..b39b8ac Binary files /dev/null and b/clients/2011M/content/fonts/CompositTShirt.mesh differ diff --git a/clients/2011M/content/fonts/CompositTorsoBase.mesh b/clients/2011M/content/fonts/CompositTorsoBase.mesh new file mode 100644 index 0000000..0388bde Binary files /dev/null and b/clients/2011M/content/fonts/CompositTorsoBase.mesh differ diff --git a/clients/2011M/content/fonts/Legacy-18pt.fontdef b/clients/2011M/content/fonts/Legacy-18pt.fontdef new file mode 100644 index 0000000..525fa41 --- /dev/null +++ b/clients/2011M/content/fonts/Legacy-18pt.fontdef @@ -0,0 +1,103 @@ +fonts/Legacy-18pt +{ + type image + source fonts/Legacy-18pt.png + + glyph u0032 0.1074219 0.3984375 0.1210938 0.4511719 + glyph ! 0.1074219 0 0.1210938 0.05273438 + glyph " 0.2070313 0 0.2246094 0.05273438 + glyph # 0.3066406 0 0.3339844 0.05273438 + glyph $ 0.40625 0 0.4335938 0.05273438 + glyph % 0.5058594 0 0.5488281 0.05273438 + glyph & 0.6054688 0 0.6386719 0.05273438 + glyph ' 0.7050781 0 0.7148438 0.05273438 + glyph ( 0.8046875 0 0.8222656 0.05273438 + glyph ) 0.9042969 0 0.921875 0.05273438 + glyph * 0.0078125 0.09960938 0.02734375 0.1523438 + glyph + 0.1074219 0.09960938 0.1367188 0.1523438 + glyph , 0.2070313 0.09960938 0.2207031 0.1523438 + glyph - 0.3066406 0.09960938 0.3242188 0.1523438 + glyph . 0.40625 0.09960938 0.4199219 0.1523438 + glyph / 0.5058594 0.09960938 0.5195313 0.1523438 + glyph 0 0.6054688 0.09960938 0.6328125 0.1523438 + glyph 1 0.7050781 0.09960938 0.7324219 0.1523438 + glyph 2 0.8046875 0.09960938 0.8320313 0.1523438 + glyph 3 0.9042969 0.09960938 0.9316406 0.1523438 + glyph 4 0.0078125 0.1992188 0.03515625 0.2519531 + glyph 5 0.1074219 0.1992188 0.1347656 0.2519531 + glyph 6 0.2070313 0.1992188 0.234375 0.2519531 + glyph 7 0.3066406 0.1992188 0.3339844 0.2519531 + glyph 8 0.40625 0.1992188 0.4335938 0.2519531 + glyph 9 0.5058594 0.1992188 0.5332031 0.2519531 + glyph : 0.6054688 0.1992188 0.6191406 0.2519531 + glyph ; 0.7050781 0.1992188 0.71875 0.2519531 + glyph < 0.8046875 0.1992188 0.8339844 0.2519531 + glyph = 0.9042969 0.1992188 0.9335938 0.2519531 + glyph > 0.0078125 0.2988281 0.03710938 0.3515625 + glyph ? 0.1074219 0.2988281 0.1347656 0.3515625 + glyph @ 0.2070313 0.2988281 0.2578125 0.3515625 + glyph A 0.3066406 0.2988281 0.3398438 0.3515625 + glyph B 0.40625 0.2988281 0.4394531 0.3515625 + glyph C 0.5058594 0.2988281 0.5410156 0.3515625 + glyph D 0.6054688 0.2988281 0.640625 0.3515625 + glyph E 0.7050781 0.2988281 0.7382813 0.3515625 + glyph F 0.8046875 0.2988281 0.8359375 0.3515625 + glyph G 0.9042969 0.2988281 0.9433594 0.3515625 + glyph H 0.0078125 0.3984375 0.04296875 0.4511719 + glyph I 0.1074219 0.3984375 0.1210938 0.4511719 + glyph J 0.2070313 0.3984375 0.2324219 0.4511719 + glyph K 0.3066406 0.3984375 0.3398438 0.4511719 + glyph L 0.40625 0.3984375 0.4335938 0.4511719 + glyph M 0.5058594 0.3984375 0.546875 0.4511719 + glyph N 0.6054688 0.3984375 0.640625 0.4511719 + glyph O 0.7050781 0.3984375 0.7441406 0.4511719 + glyph P 0.8046875 0.3984375 0.8378906 0.4511719 + glyph Q 0.9042969 0.3984375 0.9433594 0.4511719 + glyph R 0.0078125 0.4980469 0.04296875 0.5507813 + glyph S 0.1074219 0.4980469 0.140625 0.5507813 + glyph T 0.2070313 0.4980469 0.2382813 0.5507813 + glyph U 0.3066406 0.4980469 0.3417969 0.5507813 + glyph V 0.40625 0.4980469 0.4394531 0.5507813 + glyph W 0.5058594 0.4980469 0.5527344 0.5507813 + glyph X 0.6054688 0.4980469 0.6386719 0.5507813 + glyph Y 0.7050781 0.4980469 0.7382813 0.5507813 + glyph Z 0.8046875 0.4980469 0.8359375 0.5507813 + glyph [ 0.9042969 0.4980469 0.9179688 0.5507813 + glyph \ 0.0078125 0.5976563 0.02148438 0.6503906 + glyph ] 0.1074219 0.5976563 0.1210938 0.6503906 + glyph ^ 0.2070313 0.5976563 0.2304688 0.6503906 + glyph _ 0.3066406 0.5976563 0.3339844 0.6503906 + glyph ` 0.40625 0.5976563 0.4238281 0.6503906 + glyph a 0.5058594 0.5976563 0.5332031 0.6503906 + glyph b 0.6054688 0.5976563 0.6328125 0.6503906 + glyph c 0.7050781 0.5976563 0.7304688 0.6503906 + glyph d 0.8046875 0.5976563 0.8320313 0.6503906 + glyph e 0.9042969 0.5976563 0.9316406 0.6503906 + glyph f 0.0078125 0.6972656 0.02148438 0.75 + glyph g 0.1074219 0.6972656 0.1347656 0.75 + glyph h 0.2070313 0.6972656 0.234375 0.75 + glyph i 0.3066406 0.6972656 0.3183594 0.75 + glyph j 0.40625 0.6972656 0.4179688 0.75 + glyph k 0.5058594 0.6972656 0.53125 0.75 + glyph l 0.6054688 0.6972656 0.6171875 0.75 + glyph m 0.7050781 0.6972656 0.7460938 0.75 + glyph n 0.8046875 0.6972656 0.8320313 0.75 + glyph o 0.9042969 0.6972656 0.9316406 0.75 + glyph p 0.0078125 0.796875 0.03515625 0.8496094 + glyph q 0.1074219 0.796875 0.1347656 0.8496094 + glyph r 0.2070313 0.796875 0.2246094 0.8496094 + glyph s 0.3066406 0.796875 0.3320313 0.8496094 + glyph t 0.40625 0.796875 0.4199219 0.8496094 + glyph u 0.5058594 0.796875 0.5332031 0.8496094 + glyph v 0.6054688 0.796875 0.6308594 0.8496094 + glyph w 0.7050781 0.796875 0.7402344 0.8496094 + glyph x 0.8046875 0.796875 0.8300781 0.8496094 + glyph y 0.9042969 0.796875 0.9296875 0.8496094 + glyph z 0.0078125 0.8964844 0.03320313 0.9492188 + glyph { 0.1074219 0.8964844 0.125 0.9492188 + glyph | 0.2070313 0.8964844 0.2207031 0.9492188 + glyph } 0.3066406 0.8964844 0.3242188 0.9492188 + glyph ~ 0.40625 0.8964844 0.4355469 0.9492188 +} + 0.4296875 0.9511719 +} diff --git a/clients/2011M/content/fonts/Legacy-18pt.png b/clients/2011M/content/fonts/Legacy-18pt.png new file mode 100644 index 0000000..c58b76f Binary files /dev/null and b/clients/2011M/content/fonts/Legacy-18pt.png differ diff --git a/clients/2011M/content/fonts/Legacy-64pt.fontdef b/clients/2011M/content/fonts/Legacy-64pt.fontdef new file mode 100644 index 0000000..c4e390b --- /dev/null +++ b/clients/2011M/content/fonts/Legacy-64pt.fontdef @@ -0,0 +1,101 @@ +fonts/Legacy-64pt +{ + type image + source fonts/Legacy-64pt.png + + glyph u0032 0.1142578 0.3984375 0.1376953 0.4912109 + glyph ! 0.1142578 0 0.1376953 0.09277344 + glyph " 0.2138672 0 0.2441406 0.09277344 + glyph # 0.3134766 0 0.3603516 0.09277344 + glyph $ 0.4130859 0 0.4599609 0.09277344 + glyph % 0.5126953 0 0.5878906 0.09277344 + glyph & 0.6123047 0 0.6689453 0.09277344 + glyph ' 0.7119141 0 0.7275391 0.09277344 + glyph ( 0.8115234 0 0.8398438 0.09277344 + glyph ) 0.9111328 0 0.9394531 0.09277344 + glyph * 0.01464844 0.09960938 0.04785156 0.1923828 + glyph + 0.1142578 0.09960938 0.1640625 0.1923828 + glyph , 0.2138672 0.09960938 0.2373047 0.1923828 + glyph - 0.3134766 0.09960938 0.3417969 0.1923828 + glyph . 0.4130859 0.09960938 0.4365234 0.1923828 + glyph / 0.5126953 0.09960938 0.5361328 0.1923828 + glyph 0 0.6123047 0.09960938 0.6591797 0.1923828 + glyph 1 0.7119141 0.09960938 0.7587891 0.1923828 + glyph 2 0.8115234 0.09960938 0.8583984 0.1923828 + glyph 3 0.9111328 0.09960938 0.9580078 0.1923828 + glyph 4 0.01464844 0.1992188 0.06152344 0.2919922 + glyph 5 0.1142578 0.1992188 0.1611328 0.2919922 + glyph 6 0.2138672 0.1992188 0.2607422 0.2919922 + glyph 7 0.3134766 0.1992188 0.3603516 0.2919922 + glyph 8 0.4130859 0.1992188 0.4599609 0.2919922 + glyph 9 0.5126953 0.1992188 0.5595703 0.2919922 + glyph : 0.6123047 0.1992188 0.6357422 0.2919922 + glyph ; 0.7119141 0.1992188 0.7353516 0.2919922 + glyph < 0.8115234 0.1992188 0.8613281 0.2919922 + glyph = 0.9111328 0.1992188 0.9609375 0.2919922 + glyph > 0.01464844 0.2988281 0.06445313 0.3916016 + glyph ? 0.1142578 0.2988281 0.1611328 0.3916016 + glyph @ 0.2138672 0.2988281 0.2998047 0.3916016 + glyph A 0.3134766 0.2988281 0.3701172 0.3916016 + glyph B 0.4130859 0.2988281 0.4697266 0.3916016 + glyph C 0.5126953 0.2988281 0.5742188 0.3916016 + glyph D 0.6123047 0.2988281 0.6738281 0.3916016 + glyph E 0.7119141 0.2988281 0.7685547 0.3916016 + glyph F 0.8115234 0.2988281 0.8632813 0.3916016 + glyph G 0.9111328 0.2988281 0.9775391 0.3916016 + glyph H 0.01464844 0.3984375 0.07617188 0.4912109 + glyph I 0.1142578 0.3984375 0.1376953 0.4912109 + glyph J 0.2138672 0.3984375 0.2558594 0.4912109 + glyph K 0.3134766 0.3984375 0.3701172 0.4912109 + glyph L 0.4130859 0.3984375 0.4599609 0.4912109 + glyph M 0.5126953 0.3984375 0.5839844 0.4912109 + glyph N 0.6123047 0.3984375 0.6738281 0.4912109 + glyph O 0.7119141 0.3984375 0.7783203 0.4912109 + glyph P 0.8115234 0.3984375 0.8681641 0.4912109 + glyph Q 0.9111328 0.3984375 0.9775391 0.4912109 + glyph R 0.01464844 0.4980469 0.07617188 0.5908203 + glyph S 0.1142578 0.4980469 0.1708984 0.5908203 + glyph T 0.2138672 0.4980469 0.265625 0.5908203 + glyph U 0.3134766 0.4980469 0.375 0.5908203 + glyph V 0.4130859 0.4980469 0.4697266 0.5908203 + glyph W 0.5126953 0.4980469 0.5927734 0.5908203 + glyph X 0.6123047 0.4980469 0.6689453 0.5908203 + glyph Y 0.7119141 0.4980469 0.7685547 0.5908203 + glyph Z 0.8115234 0.4980469 0.8632813 0.5908203 + glyph [ 0.9111328 0.4980469 0.9345703 0.5908203 + glyph \ 0.01464844 0.5976563 0.03808594 0.6904297 + glyph ] 0.1142578 0.5976563 0.1376953 0.6904297 + glyph ^ 0.2138672 0.5976563 0.2539063 0.6904297 + glyph _ 0.3134766 0.5976563 0.3603516 0.6904297 + glyph ` 0.4130859 0.5976563 0.4414063 0.6904297 + glyph a 0.5126953 0.5976563 0.5595703 0.6904297 + glyph b 0.6123047 0.5976563 0.6591797 0.6904297 + glyph c 0.7119141 0.5976563 0.7539063 0.6904297 + glyph d 0.8115234 0.5976563 0.8583984 0.6904297 + glyph e 0.9111328 0.5976563 0.9580078 0.6904297 + glyph f 0.01464844 0.6972656 0.03808594 0.7900391 + glyph g 0.1142578 0.6972656 0.1611328 0.7900391 + glyph h 0.2138672 0.6972656 0.2607422 0.7900391 + glyph i 0.3134766 0.6972656 0.3320313 0.7900391 + glyph j 0.4130859 0.6972656 0.4316406 0.7900391 + glyph k 0.5126953 0.6972656 0.5546875 0.7900391 + glyph l 0.6123047 0.6972656 0.6308594 0.7900391 + glyph m 0.7119141 0.6972656 0.7832031 0.7900391 + glyph n 0.8115234 0.6972656 0.8583984 0.7900391 + glyph o 0.9111328 0.6972656 0.9580078 0.7900391 + glyph p 0.01464844 0.796875 0.06152344 0.8896484 + glyph q 0.1142578 0.796875 0.1611328 0.8896484 + glyph r 0.2138672 0.796875 0.2421875 0.8896484 + glyph s 0.3134766 0.796875 0.3554688 0.8896484 + glyph t 0.4130859 0.796875 0.4365234 0.8896484 + glyph u 0.5126953 0.796875 0.5595703 0.8896484 + glyph v 0.6123047 0.796875 0.6542969 0.8896484 + glyph w 0.7119141 0.796875 0.7734375 0.8896484 + glyph x 0.8115234 0.796875 0.8535156 0.8896484 + glyph y 0.9111328 0.796875 0.953125 0.8896484 + glyph z 0.01464844 0.8964844 0.05664063 0.9892578 + glyph { 0.1142578 0.8964844 0.1425781 0.9892578 + glyph | 0.2138672 0.8964844 0.2353516 0.9892578 + glyph } 0.3134766 0.8964844 0.3417969 0.9892578 + glyph ~ 0.4130859 0.8964844 0.4628906 0.9892578 +} diff --git a/clients/2011M/content/fonts/Legacy-64pt.png b/clients/2011M/content/fonts/Legacy-64pt.png new file mode 100644 index 0000000..bb340e8 Binary files /dev/null and b/clients/2011M/content/fonts/Legacy-64pt.png differ diff --git a/clients/2011M/content/fonts/Rocket.rbxm b/clients/2011M/content/fonts/Rocket.rbxm new file mode 100644 index 0000000..72beea5 --- /dev/null +++ b/clients/2011M/content/fonts/Rocket.rbxm @@ -0,0 +1,102 @@ + + null + nil + + + false + -0.5 + 0.5 + 3 + 0 + -0.5 + 0.5 + 3 + 0 + 23 + + -0.5 + 0.5 + 0 + -1.1920929e-007 + 1.00000012 + 0 + 1.00000012 + -1.1920929e-007 + 0 + 0 + 0 + -1.00000024 + + true + true + 0 + true + true + 0.5 + 0 + 0.300000012 + -0.5 + 0.5 + 3 + 0 + -0.5 + 0.5 + 3 + 0 + false + Rocket + 0 + -0.5 + 0.5 + 3 + 0 + + 0 + 0 + 0 + + -0.5 + 0.5 + 3 + 0 + 0 + + 0 + 0 + 0 + + 1 + + 1 + 1 + 4 + + + + + true + Swoosh + 0 + false + rbxasset://sounds\Rocket whoosh 01.wav + 0.699999988 + + + + + false + Explosion + 0 + true + rbxasset://sounds\collide.wav + 1 + + + + + Script + r = game:service("RunService") shaft = script.Parent position = Vector3.new(0,0,0) function fly() direction = shaft.CFrame.lookVector position = position + direction error = position - shaft.Position shaft.Velocity = 7*error end function blow() swoosh:Stop() explosion = Instance.new("Explosion") explosion.Position = shaft.Position explosion.Parent = game.Workspace connection:disconnect() shaft:remove() end t, s = r.Stepped:wait() swoosh = script.Parent.Swoosh swoosh:Play() position = shaft.Position d = t + 10.0 - s connection = shaft.Touched:connect(blow) while t < d do fly() t = r.Stepped:wait() end script.Parent.Explosion.PlayOnRemove = false swoosh:Stop() shaft:remove() + + + + \ No newline at end of file diff --git a/clients/2011M/content/fonts/SlingshotPellet.rbxm b/clients/2011M/content/fonts/SlingshotPellet.rbxm new file mode 100644 index 0000000..d753b0a --- /dev/null +++ b/clients/2011M/content/fonts/SlingshotPellet.rbxm @@ -0,0 +1,82 @@ + + null + nil + + + false + -0.5 + 0.5 + 0 + 0 + -0.5 + 0.5 + 4 + 0 + 194 + + 0 + 6.4000001 + -8 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 1 + + true + true + 0 + true + true + 0.5 + 0 + 0.300000012 + -0.5 + 0.5 + 0 + 0 + -0.5 + 0.5 + 0 + 0 + false + Pellet + 0 + -0.5 + 0.5 + 0 + 0 + + 0 + 0 + 0 + + -0.5 + 0.5 + 3 + 0 + 0 + + 0 + 0 + 0 + + 0 + + 2 + 2 + 2 + + + + + Script + pellet = script.Parent damage = 8 function onTouched(hit) humanoid = hit.Parent:findFirstChild("Humanoid") if humanoid~=nil then humanoid.Health = humanoid.Health - damage connection:disconnect() else damage = damage / 2 if damage < 0.1 then connection:disconnect() end end end connection = pellet.Touched:connect(onTouched) r = game:service("RunService") t, s = r.Stepped:wait() d = t + 1.0 - s while t < d do t = r.Stepped:wait() end pellet.Parent = nil + + + + \ No newline at end of file diff --git a/clients/2011M/content/fonts/character.rbxm b/clients/2011M/content/fonts/character.rbxm new file mode 100644 index 0000000..7bf4b8a --- /dev/null +++ b/clients/2011M/content/fonts/character.rbxm @@ -0,0 +1,527 @@ + + null + nil + + + 7 + true + + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 1 + + erik.cassel + RBX1 + true + + + + false + -0.5 + 0.5 + 0 + 0 + -0.5 + 0.5 + 4 + 0 + 24 + + 0 + 4.5 + 25.5 + -1 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + -1 + + true + 0 + true + false + 0.5 + 0 + 0.300000012 + -0.5 + 0.5 + 0 + 0 + -0.5 + 0.5 + 0 + 0 + true + Head + 0 + -0.5 + 0.5 + 0 + 0 + + 0 + 0 + 0 + + -0.5 + 0.5 + 0 + 0 + 0 + + 0 + 0 + 0 + + true + 1 + + 2 + 1 + 1 + + + + + + 0 + Mesh + + 1.25 + 1.25 + 1.25 + + + + 1 + 1 + 1 + + true + + + + + 5 + face + 20 + 0 + rbxasset://textures/face.png + true + + + + + + false + -0.5 + 0.5 + 0 + 0 + -0.5 + 0.5 + 4 + 0 + 23 + + 0 + 3 + 25.5 + -1 + 0 + -0 + -0 + 1 + -0 + -0 + 0 + -1 + + true + 0 + true + false + 0.5 + 0 + 0.300000012 + -0.5 + 0.5 + 0 + 0 + 0 + 0 + 2 + 0 + true + Torso + 0 + 0 + 0 + 2 + 0 + + 0 + 0 + 0 + + -0.5 + 0.5 + 3 + 0 + 0 + + 0 + 0 + 0 + + true + 1 + + 2 + 2 + 1 + + + + + 5 + roblox + 20 + 0 + + + + true + + + + + + false + -0.5 + 0.5 + 0 + 0 + -0.5 + 0.5 + 4 + 0 + 24 + + 1.5 + 3 + 25.5 + -1 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + -1 + + false + 0 + true + false + 0.5 + 0 + 0.300000012 + -0.5 + 0.5 + 0 + 0 + -0.5 + 0.5 + 0 + 0 + true + Left Arm + 0 + -0.5 + 0.5 + 0 + 0 + + 0 + 0 + 0 + + -0.5 + 0.5 + 3 + 0 + 0 + + 0 + 0 + 0 + + true + 1 + + 1 + 2 + 1 + + + + + + false + -0.5 + 0.5 + 0 + 0 + -0.5 + 0.5 + 4 + 0 + 24 + + -1.5 + 3 + 25.5 + -1 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + -1 + + false + 0 + true + false + 0.5 + 0 + 0.300000012 + -0.5 + 0.5 + 0 + 0 + -0.5 + 0.5 + 0 + 0 + true + Right Arm + 0 + -0.5 + 0.5 + 0 + 0 + + 0 + 0 + 0 + + -0.5 + 0.5 + 3 + 0 + 0 + + 0 + 0 + 0 + + true + 1 + + 1 + 2 + 1 + + + + + + false + -0.5 + 0.5 + 0 + 0 + -0.5 + 0.5 + 0 + 0 + 119 + + 0.5 + 1 + 25.5 + -1 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + -1 + + false + 0 + true + false + 0.5 + 0 + 0.300000012 + -0.5 + 0.5 + 0 + 0 + -0.5 + 0.5 + 0 + 0 + true + Left Leg + 0 + -0.5 + 0.5 + 0 + 0 + + 0 + 0 + 0 + + -0.5 + 0.5 + 3 + 0 + 0 + + 0 + 0 + 0 + + true + 1 + + 1 + 2 + 1 + + + + + + false + -0.5 + 0.5 + 0 + 0 + -0.5 + 0.5 + 0 + 0 + 119 + + -0.5 + 1 + 25.5 + -1 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + -1 + + false + 0 + true + false + 0.5 + 0 + 0.300000012 + -0.5 + 0.5 + 0 + 0 + -0.5 + 0.5 + 0 + 0 + true + Right Leg + 0 + -0.5 + 0.5 + 0 + 0 + + 0 + 0 + 0 + + -0.5 + 0.5 + 3 + 0 + 0 + + 0 + 0 + 0 + + true + 1 + + 1 + 2 + 1 + + + + + + 100 + false + 100 + Humanoid + false + + 0 + 0 + 0 + + + 0 + 0 + 0 + + 0 + null + + 0 + 0 + 0 + + true + + + + \ No newline at end of file diff --git a/clients/2011M/content/fonts/comics.fnt b/clients/2011M/content/fonts/comics.fnt new file mode 100644 index 0000000..6b71c7e Binary files /dev/null and b/clients/2011M/content/fonts/comics.fnt differ diff --git a/clients/2011M/content/fonts/diogenes.fnt b/clients/2011M/content/fonts/diogenes.fnt new file mode 100644 index 0000000..3e718e2 --- /dev/null +++ b/clients/2011M/content/fonts/diogenes.fnt @@ -0,0 +1,438 @@ + + +&& +f84<9 +a6=4; +a 6> +4qq +47:'!<:; +47:'!<:;<&! +4=:90 +4<1& +4;49 +4;499, +4; & +4&=:90 +4&=:90& +4&& +4&&0& +4&&=:90 +4&&=:90& +4&&><&&0' +4&&"<%0 +7 +7499& +7499&46 +7499&46> +74&!4'1 +74&!0'1 +704&!<4994;1 +79:6>94;1 +79:6>94;1{ & +79:" +79:"?:7 +79:"?:7& +7:;0=041 +7:;0' +7::7 +7::7<0& +7::7& +7'04&! +7'04&!& +7 99&= +7 !!3 6>0' +7 !!=4<' +7 !!=041 +7 !!=:90 +7 !!%<6>0' +6=<;> +6<24'0!!0 +6<'690?0'> +69 +6:6>'<10 +6:6>& +6:6>& 6> +6:6>& 6>01 +6:6>& 6>0' +6:6>& 6><;2 +6:6>& 6>& +6:> +6:;1:8 +6:;1:8& +6::!0' +6'4% +6'<%& +6 8 +6 880'u +6 88<;2 +6 8& +6 8&=:! +6 ;<9<;2 & +6 ;<99<;2 & +6 ;;<9<;2 & +6 ;! +6 ;!9<6> +6 ;!9<6>0' +6 ;!9<6><;2 +6 ;!& +6,70'3 6 +6,70'3 6> +6,70'3 6>01 +6,70'3 6>0' +6,70'3 6>0'& +6,70'3 6><;2 +18; +148 +1488 +1<6>& +1<>0 +1<91: +1<91:u +1<91:& +1<91:&u +1<%&=0 +0?46 94!0u +0?46 94!01u +0?46 94!0& +0?46 94!<;2 +0?46 94!<;2& +0?46 94!<:; +084<9 +3 +3 +3 +30' +3<;2 +3> +342 +3420! +3422 +34220! +3422<;2 +3422 +36><;2 +3094!<: +30994!<: +3<;20'74;2 +3<;20'3 6> +3<;20'3 6>01 +3<;20'3 6>0' +3<;20'3 6>0'& +3<;20'3 6><;2 +3<;20'3 6>& +3<&!3 6> +3<&!3 6>01 +3<&!3 6>0' +3<&!3 6>0'& +3<&!3 6><;2 +3<&!3 6><;2& +3<&!3 6>& +3:6><;2 +3: '6=4; +3  +3 6 +3 6 +3 6> +3 6>0 +3 6>01 +3 6>0; +3 6>0' +3 6>0'& +3 6><; +3 6><;2 +3 6><;2& +3 6>9:41 +3 6>80 +3 6>& +3 6>!4'1 +3 6>!4'101 +3 6>!:; +3 6>,: +3 > +3 >0' +3 ><; +3 ><;2 +3 >> +3 >& +3 '7 '20' +3,: +24;274;2 +24;274;201 +24;274;2& +24;274;2&u +24, +24,&0- +24/:;20'& +2:1148; +2:;41& +2::> +2&%:! +2 <;;0 +=4'16:'0&0- +=4'1:; +=099 +=:0 +=:8: +=::>0' +=:';<0&! +=:';, +=:!&0- +=!!%ozz"""{79:6>94;1{ & += 8% += &&, +?46>4&& +?46><;2:33 +?46>:33 +?46>x:33 +?4% +?0'> +?0'>x:33 +?0" +?<&8 +?<1&<;4&4;7:- +><>0 +><&&8, +><&&8,4&& +>>> +>:6> +>:;1 8 +>:;1 8& +>'4 ! +> 8 +> 80'u +> 880' +> 88<;2 +> 8& +> ;<9<;2 & +908:;%4'!, +90&7: +90/7<4; +90//: +9:&0' +9:#0' +9 &! +9 &!<;2 +84>0: ! +84&!0'7m +84&!0'74 +8:!=43 6>4 +8:!=43 6>4& +8:!=43 6>4/ +8:!=43 6>01 +8:!=43 6>0' +8:!=43 6>0'& +8:!=43 6><; +8:!=43 6><;2 +8:!=43 6><;2& +8:!=43 6>& +8:!=0'3 6> +8:!=0'3 6>01 +8:!=0'3 6>0' +8:!=0'3 6>0'& +8:!=0'3 6><; +8:!=0'3 6><;2 +8:!=0'3 6><;2& +8:!=0'3 6>& +8 33 +8,6:6> +;4/< +;4/<& +;0'1 +;<20'u +;<224 +;<224& +;<220' +;<220'& +;<$$4 +;<$$4& +; 10 +; 1<&8 +; 1<&! +:=&=< +:=&=< +:832 +:'24&<8 +:'24&<8& +:'24&8 +:'24&8& +%e'; +%06>0' +%01: +%01:704' +%0;<& +%=:;0&0- +%= > +%= >01 +%= ><;2 +%= >>01 +%= >><;2 +%= >& +%= >&u +%= $u +%<8% +%<&0&u +%<&<;u +%<&<;2u +%<&:3 +%<&& +%<&&01 +%<&&0' +%<&&0'u +%<&&0'&u +%<&&0&u +%<&&<;u +%<&&<;2u +%<&&:33 +%:'; +%:';: +%:';:2'4%=, +%:';:& +%'e; +%'<6> +%'<6>& +%':&! +% &<0&u +% &&<0& +% &&, +% &&,34'! +% &&,& +% &,u +% &,&u +$ 00' +'4<% +'4<%<;2 +'4%0 +'4%01 +'4%0' +'4%<;2 +'4%<&! +'01! 70 +'0!4'1 +'!7 +&6=9:;2 +&6'0" +&0- +&0-- +&0--- +&0--, +&0-, +&0-,!<08 +&0-,!<80 +&= +&=d! +&=0<&!0' +&=,%0 +&904/0 +&9 ! +&9 !&u +&80- +&8 ! +&;4!6= +&%0'8 +&% ;> +&% '8 +&!3 +&!'<% +&!'<%%0' +&!'<%%0'%:90 +&!'<%%0'& +& 6> +& 6>& +& > +&"4&!<>4 +!=:;2 +!<;, '9 +! +#422<;4 +#42<;4 +#02<;4 +#<7'4!:' +"4;> +"4;>0' +"0!746> +"=<&>0, +"=:'0 +"=:'0=: &0 +"!3 +"""{79:6>94;1{ & +-3<4= +-3<'0 +,: '6:6> diff --git a/clients/2011M/content/fonts/humanoidAnimate.rbxm b/clients/2011M/content/fonts/humanoidAnimate.rbxm new file mode 100644 index 0000000..7a59cb9 --- /dev/null +++ b/clients/2011M/content/fonts/humanoidAnimate.rbxm @@ -0,0 +1,296 @@ + + null + nil + + + false + + Animate + -- Now with exciting TeamColors HACK! + +function waitForChild(parent, childName) + local child = parent:findFirstChild(childName) + if child then return child end + while true do + child = parent.ChildAdded:wait() + if child.Name==childName then return child end + end +end + +-- TEAM COLORS + + +function onTeamChanged(player) + + wait(1) + + local char = player.Character + if char == nil then return end + + if player.Neutral then + -- Replacing the current BodyColor object will force a reset + local old = char:findFirstChild("Body Colors") + if not old then return end + old:clone().Parent = char + old.Parent = nil + else + local head = char:findFirstChild("Head") + local torso = char:findFirstChild("Torso") + local left_arm = char:findFirstChild("Left Arm") + local right_arm = char:findFirstChild("Right Arm") + local left_leg = char:findFirstChild("Left Leg") + local right_leg = char:findFirstChild("Right Leg") + + if head then head.BrickColor = BrickColor.new(24) end + if torso then torso.BrickColor = player.TeamColor end + if left_arm then left_arm.BrickColor = BrickColor.new(26) end + if right_arm then right_arm.BrickColor = BrickColor.new(26) end + if left_leg then left_leg.BrickColor = BrickColor.new(26) end + if right_leg then right_leg.BrickColor = BrickColor.new(26) end + end +end + +function onPlayerPropChanged(property, player) + if property == "Character" then + onTeamChanged(player) + end + if property== "TeamColor" or property == "Neutral" then + onTeamChanged(player) + end +end + + +local cPlayer = game.Players:GetPlayerFromCharacter(script.Parent) +cPlayer.Changed:connect(function(property) onPlayerPropChanged(property, cPlayer) end ) +onTeamChanged(cPlayer) + + +-- ANIMATION + +-- declarations + +local Figure = script.Parent +local Torso = waitForChild(Figure, "Torso") +local RightShoulder = waitForChild(Torso, "Right Shoulder") +local LeftShoulder = waitForChild(Torso, "Left Shoulder") +local RightHip = waitForChild(Torso, "Right Hip") +local LeftHip = waitForChild(Torso, "Left Hip") +local Neck = waitForChild(Torso, "Neck") +local Humanoid = waitForChild(Figure, "Humanoid") +local pose = "Standing" + +local toolAnim = "None" +local toolAnimTime = 0 + +-- functions + +function onRunning(speed) + if speed>0 then + pose = "Running" + else + pose = "Standing" + end +end + +function onDied() + pose = "Dead" +end + +function onJumping() + pose = "Jumping" +end + +function onClimbing() + pose = "Climbing" +end + +function onGettingUp() + pose = "GettingUp" +end + +function onFreeFall() + pose = "FreeFall" +end + +function onFallingDown() + pose = "FallingDown" +end + +function onSeated() + pose = "Seated" +end + +function onPlatformStanding() + pose = "PlatformStanding" +end + +function moveJump() + RightShoulder.MaxVelocity = 0.5 + LeftShoulder.MaxVelocity = 0.5 + RightShoulder:SetDesiredAngle(3.14) + LeftShoulder:SetDesiredAngle(-3.14) + RightHip:SetDesiredAngle(0) + LeftHip:SetDesiredAngle(0) +end + + +-- same as jump for now + +function moveFreeFall() + RightShoulder.MaxVelocity = 0.5 + LeftShoulder.MaxVelocity = 0.5 + RightShoulder:SetDesiredAngle(3.14) + LeftShoulder:SetDesiredAngle(-3.14) + RightHip:SetDesiredAngle(0) + LeftHip:SetDesiredAngle(0) +end + +function moveSit() + RightShoulder.MaxVelocity = 0.15 + LeftShoulder.MaxVelocity = 0.15 + RightShoulder:SetDesiredAngle(3.14 /2) + LeftShoulder:SetDesiredAngle(-3.14 /2) + RightHip:SetDesiredAngle(3.14 /2) + LeftHip:SetDesiredAngle(-3.14 /2) +end + +function getTool() + for _, kid in ipairs(Figure:GetChildren()) do + if kid.className == "Tool" then return kid end + end + return nil +end + +function getToolAnim(tool) + for _, c in ipairs(tool:GetChildren()) do + if c.Name == "toolanim" and c.className == "StringValue" then + return c + end + end + return nil +end + +function animateTool() + + if (toolAnim == "None") then + RightShoulder:SetDesiredAngle(1.57) + return + end + + if (toolAnim == "Slash") then + RightShoulder.MaxVelocity = 0.5 + RightShoulder:SetDesiredAngle(0) + return + end + + if (toolAnim == "Lunge") then + RightShoulder.MaxVelocity = 0.5 + LeftShoulder.MaxVelocity = 0.5 + RightHip.MaxVelocity = 0.5 + LeftHip.MaxVelocity = 0.5 + RightShoulder:SetDesiredAngle(1.57) + LeftShoulder:SetDesiredAngle(1.0) + RightHip:SetDesiredAngle(1.57) + LeftHip:SetDesiredAngle(1.0) + return + end +end + +function move(time) + local amplitude + local frequency + + if (pose == "Jumping") then + moveJump() + return + end + + if (pose == "FreeFall") then + moveFreeFall() + return + end + + if (pose == "Seated") then + moveSit() + return + end + + local climbFudge = 0 + + if (pose == "Running") then + RightShoulder.MaxVelocity = 0.15 + LeftShoulder.MaxVelocity = 0.15 + amplitude = 1 + frequency = 9 + elseif (pose == "Climbing") then + RightShoulder.MaxVelocity = 0.5 + LeftShoulder.MaxVelocity = 0.5 + amplitude = 1 + frequency = 9 + climbFudge = 3.14 + else + amplitude = 0.1 + frequency = 1 + end + + desiredAngle = amplitude * math.sin(time*frequency) + + RightShoulder:SetDesiredAngle(desiredAngle + climbFudge) + LeftShoulder:SetDesiredAngle(desiredAngle - climbFudge) + RightHip:SetDesiredAngle(-desiredAngle) + LeftHip:SetDesiredAngle(-desiredAngle) + + + local tool = getTool() + + if tool then + + animStringValueObject = getToolAnim(tool) + + if animStringValueObject then + toolAnim = animStringValueObject.Value + -- message recieved, delete StringValue + animStringValueObject.Parent = nil + toolAnimTime = time + .3 + end + + if time > toolAnimTime then + toolAnimTime = 0 + toolAnim = "None" + end + + animateTool() + + + else + toolAnim = "None" + toolAnimTime = 0 + end +end + + +-- connect events + +Humanoid.Died:connect(onDied) +Humanoid.Running:connect(onRunning) +Humanoid.Jumping:connect(onJumping) +Humanoid.Climbing:connect(onClimbing) +Humanoid.GettingUp:connect(onGettingUp) +Humanoid.FreeFalling:connect(onFreeFall) +Humanoid.FallingDown:connect(onFallingDown) +Humanoid.Seated:connect(onSeated) +Humanoid.PlatformStanding:connect(onPlatformStanding) + +-- main program + +local runService = game:service("RunService"); + +while Figure.Parent~=nil do + local _, time = wait(0.1) + move(time) +end + + true + + + \ No newline at end of file diff --git a/clients/2011M/content/fonts/humanoidAnimateLocal.rbxm b/clients/2011M/content/fonts/humanoidAnimateLocal.rbxm new file mode 100644 index 0000000..282e2ac --- /dev/null +++ b/clients/2011M/content/fonts/humanoidAnimateLocal.rbxm @@ -0,0 +1,318 @@ + + null + nil + + + false + + Animate + + +function waitForChild(parent, childName) + local child = parent:findFirstChild(childName) + if child then return child end + while true do + child = parent.ChildAdded:wait() + if child.Name==childName then return child end + end +end + +-- ANIMATION + +-- declarations + +local Figure = script.Parent +local Torso = waitForChild(Figure, "Torso") +local RightShoulder = waitForChild(Torso, "Right Shoulder") +local LeftShoulder = waitForChild(Torso, "Left Shoulder") +local RightHip = waitForChild(Torso, "Right Hip") +local LeftHip = waitForChild(Torso, "Left Hip") +local Neck = waitForChild(Torso, "Neck") +local Humanoid = waitForChild(Figure, "Humanoid") +local pose = "Standing" + +local toolAnim = "None" +local toolAnimTime = 0 + +-- functions + +function onRunning(speed) + if speed>0 then + pose = "Running" + else + pose = "Standing" + end +end + +function onDied() + pose = "Dead" +end + +function onJumping() + pose = "Jumping" +end + +function onClimbing() + pose = "Climbing" +end + +function onGettingUp() + pose = "GettingUp" +end + +function onFreeFall() + pose = "FreeFall" +end + +function onFallingDown() + pose = "FallingDown" +end + +function onSeated() + pose = "Seated" +end + +function onPlatformStanding() + pose = "PlatformStanding" +end + +function moveJump() + RightShoulder.MaxVelocity = 0.5 + LeftShoulder.MaxVelocity = 0.5 + RightShoulder:SetDesiredAngle(3.14) + LeftShoulder:SetDesiredAngle(-3.14) + RightHip:SetDesiredAngle(0) + LeftHip:SetDesiredAngle(0) +end + + +-- same as jump for now + +function moveFreeFall() + RightShoulder.MaxVelocity = 0.5 + LeftShoulder.MaxVelocity = 0.5 + RightShoulder:SetDesiredAngle(3.14) + LeftShoulder:SetDesiredAngle(-3.14) + RightHip:SetDesiredAngle(0) + LeftHip:SetDesiredAngle(0) +end + +function moveSit() + RightShoulder.MaxVelocity = 0.15 + LeftShoulder.MaxVelocity = 0.15 + RightShoulder:SetDesiredAngle(3.14 /2) + LeftShoulder:SetDesiredAngle(-3.14 /2) + RightHip:SetDesiredAngle(3.14 /2) + LeftHip:SetDesiredAngle(-3.14 /2) +end + +function getTool() + for _, kid in ipairs(Figure:GetChildren()) do + if kid.className == "Tool" then return kid end + end + return nil +end + +function getToolAnim(tool) + for _, c in ipairs(tool:GetChildren()) do + if c.Name == "toolanim" and c.className == "StringValue" then + return c + end + end + return nil +end + +function animateTool() + + if (toolAnim == "None") then + RightShoulder:SetDesiredAngle(1.57) + return + end + + if (toolAnim == "Slash") then + RightShoulder.MaxVelocity = 0.5 + RightShoulder:SetDesiredAngle(0) + return + end + + if (toolAnim == "Lunge") then + RightShoulder.MaxVelocity = 0.5 + LeftShoulder.MaxVelocity = 0.5 + RightHip.MaxVelocity = 0.5 + LeftHip.MaxVelocity = 0.5 + RightShoulder:SetDesiredAngle(1.57) + LeftShoulder:SetDesiredAngle(1.0) + RightHip:SetDesiredAngle(1.57) + LeftHip:SetDesiredAngle(1.0) + return + end +end + +function move(time) + local amplitude + local frequency + + if (pose == "Jumping") then + moveJump() + return + end + + if (pose == "FreeFall") then + moveFreeFall() + return + end + + if (pose == "Seated") then + moveSit() + return + end + + local climbFudge = 0 + + if (pose == "Running") then + RightShoulder.MaxVelocity = 0.15 + LeftShoulder.MaxVelocity = 0.15 + amplitude = 1 + frequency = 9 + elseif (pose == "Climbing") then + RightShoulder.MaxVelocity = 0.5 + LeftShoulder.MaxVelocity = 0.5 + amplitude = 1 + frequency = 9 + climbFudge = 3.14 + else + amplitude = 0.1 + frequency = 1 + end + + desiredAngle = amplitude * math.sin(time*frequency) + + RightShoulder:SetDesiredAngle(desiredAngle + climbFudge) + LeftShoulder:SetDesiredAngle(desiredAngle - climbFudge) + RightHip:SetDesiredAngle(-desiredAngle) + LeftHip:SetDesiredAngle(-desiredAngle) + + + local tool = getTool() + + if tool then + + animStringValueObject = getToolAnim(tool) + + if animStringValueObject then + toolAnim = animStringValueObject.Value + -- message recieved, delete StringValue + animStringValueObject.Parent = nil + toolAnimTime = time + .3 + end + + if time > toolAnimTime then + toolAnimTime = 0 + toolAnim = "None" + end + + animateTool() + + + else + toolAnim = "None" + toolAnimTime = 0 + end +end + + +-- connect events + +Humanoid.Died:connect(onDied) +Humanoid.Running:connect(onRunning) +Humanoid.Jumping:connect(onJumping) +Humanoid.Climbing:connect(onClimbing) +Humanoid.GettingUp:connect(onGettingUp) +Humanoid.FreeFalling:connect(onFreeFall) +Humanoid.FallingDown:connect(onFallingDown) +Humanoid.Seated:connect(onSeated) +Humanoid.PlatformStanding:connect(onPlatformStanding) + +-- main program + +local runService = game:service("RunService"); + +while Figure.Parent~=nil do + local _, time = wait(0.1) + move(time) +end + + true + + + + + false + + + + RobloxTeam + + -- Now with exciting TeamColors HACK! + + function waitForChild(parent, childName) + local child = parent:findFirstChild(childName) + if child then return child end + while true do + child = parent.ChildAdded:wait() + if child.Name==childName then return child end + end + end + + -- TEAM COLORS + + + function onTeamChanged(player) + + wait(1) + + local char = player.Character + if char == nil then return end + + if player.Neutral then + -- Replacing the current BodyColor object will force a reset + local old = char:findFirstChild("Body Colors") + if not old then return end + old:clone().Parent = char + old.Parent = nil + else + local head = char:findFirstChild("Head") + local torso = char:findFirstChild("Torso") + local left_arm = char:findFirstChild("Left Arm") + local right_arm = char:findFirstChild("Right Arm") + local left_leg = char:findFirstChild("Left Leg") + local right_leg = char:findFirstChild("Right Leg") + + if head then head.BrickColor = BrickColor.new(24) end + if torso then torso.BrickColor = player.TeamColor end + if left_arm then left_arm.BrickColor = BrickColor.new(26) end + if right_arm then right_arm.BrickColor = BrickColor.new(26) end + if left_leg then left_leg.BrickColor = BrickColor.new(26) end + if right_leg then right_leg.BrickColor = BrickColor.new(26) end + end + end + + function onPlayerPropChanged(property, player) + if property == "Character" then + onTeamChanged(player) + end + if property== "TeamColor" or property == "Neutral" then + onTeamChanged(player) + end + end + + + local cPlayer = game.Players:GetPlayerFromCharacter(script.Parent) + cPlayer.Changed:connect(function(property) onPlayerPropChanged(property, cPlayer) end ) + onTeamChanged(cPlayer) + + + true + + + \ No newline at end of file diff --git a/clients/2011M/content/fonts/humanoidExtra.rbxm b/clients/2011M/content/fonts/humanoidExtra.rbxm new file mode 100644 index 0000000..ea08e27 --- /dev/null +++ b/clients/2011M/content/fonts/humanoidExtra.rbxm @@ -0,0 +1,11 @@ + + null + nil + + + false + Script + while script.Parent.Head==nil do wait(0.05) end function newSound(id) local sound = Instance.new("Sound") sound.SoundId = id sound.Parent = script.Parent.Head return sound end sDied = newSound("rbxasset://sounds/uuhhh.wav") sFallingDown = newSound("rbxasset://sounds/splat.wav") sFreeFalling = newSound("rbxasset://sounds/swoosh.wav") sGettingUp = newSound("rbxasset://sounds/hit.wav") sJumping = newSound("rbxasset://sounds/button.wav") sRunning = newSound("rbxasset://sounds/bfsl-minifigfoots1.mp3") sRunning.Looped = true function onDied() sDied:play() end function onState(state, sound) if state then sound:play() else sound:pause() end end function onRunning(speed) if speed>0 then sRunning:play() else sRunning:pause() end end while script.Parent.Humanoid==nil do wait(0.05) end h = script.Parent.Humanoid h.Died:connect(onDied) h.Running:connect(onRunning) h.Jumping:connect(function(state) onState(state, sJumping) end) h.GettingUp:connect(function(state) onState(state, sGettingUp) end) h.FreeFalling:connect(function(state) onState(state, sFreeFalling) end) h.FallingDown:connect(function(state) onState(state, sFallingDown) end) -- regeneration while true do local s = wait(1) local health=h.Health if health>0 and health<h.MaxHealth then health = health + 0.01*s*h.MaxHealth if health*1.05 < h.MaxHealth then h.Health = health else h.Health = h.MaxHealth end end end + + + \ No newline at end of file diff --git a/clients/2011M/content/fonts/humanoidHealth.rbxm b/clients/2011M/content/fonts/humanoidHealth.rbxm new file mode 100644 index 0000000..12cdbbb --- /dev/null +++ b/clients/2011M/content/fonts/humanoidHealth.rbxm @@ -0,0 +1,191 @@ + + null + nil + + + false + + HealthScript v2.0 + local humanoid = script.Parent.Humanoid + +if (humanoid == nil) then + print("ERROR: no humanoid found in 'HealthScript v2.0'") +end + + +function CreateGUI() + local p = game.Players:GetPlayerFromCharacter(humanoid.Parent) + print("Health for Player: " .. p.Name) + script.HealthGUI.Parent = p.PlayerGui +end + +function UpdateGUI(health) + local pgui = game.Players:GetPlayerFromCharacter(humanoid.Parent).PlayerGui + local tray = pgui.HealthGUI.Tray + + tray.HealthBar.Size = UDim2.new(0.2, 0, 0.8 * (health / humanoid.MaxHealth), 0) + tray.HealthBar.Position = UDim2.new(0.4, 0, 0.8 * (1- (health / humanoid.MaxHealth)) , 0) + +end + + +function HealthChanged(health) + UpdateGUI(health) +end + + +CreateGUI() +humanoid.HealthChanged:connect(HealthChanged) +humanoid.Died:connect(function() HealthChanged(0) end) + true + + + + HealthGUI + true + + + + false + 4285215356 + 1 + 4279970357 + 1 + Tray + + 0.949999988 + 0 + 0.380000025 + 0 + + + 0.0450000018 + 0 + 0.340000004 + 0 + + 0 + true + 1 + true + + + + false + 4294967295 + 1 + 4279970357 + 1 + http://www.roblox.com/asset/?id=18441769 + ImageLabel + + 0 + 0 + 0.800000012 + 3 + + + 1 + 0 + 0.25 + 0 + + 1 + true + 1 + true + + + + + false + 4286892054 + 0 + 4278190080 + 0 + HealthBar + + 0.420000017 + 0 + 0 + 0 + + + 0.159999996 + 0 + 0.800000012 + 0 + + 0 + true + 2 + true + + + + + false + 4289733411 + 0 + 4278190080 + 0 + HealthBarBacking + + 0.419999987 + 0 + 0 + 0 + + + 0.159999996 + 0 + 0.800000012 + 0 + + 0 + true + 1 + true + + + + + + + + false + + Health + function waitForChild(parent, childName) + local child = parent:findFirstChild(childName) + if child then return child end + while true do + child = parent.ChildAdded:wait() + if child.Name==childName then return child end + end + end + + -- declarations + + local Figure = script.Parent + local Head = waitForChild(Figure, "Head") + local Humanoid = waitForChild(Figure, "Humanoid") + + -- regeneration + while true do + local s = wait(1) + local health = Humanoid.Health + if health > 0 and health < Humanoid.MaxHealth then + health = health + 0.01 * s * Humanoid.MaxHealth + if health * 1.05 < Humanoid.MaxHealth then + Humanoid.Health = health + else + Humanoid.Health = Humanoid.MaxHealth + end + end + end + + true + + + \ No newline at end of file diff --git a/clients/2011M/content/fonts/humanoidSound.rbxm b/clients/2011M/content/fonts/humanoidSound.rbxm new file mode 100644 index 0000000..0523e7b --- /dev/null +++ b/clients/2011M/content/fonts/humanoidSound.rbxm @@ -0,0 +1,76 @@ + + null + nil + + + false + + Sound + -- util + +function waitForChild(parent, childName) + local child = parent:findFirstChild(childName) + if child then return child end + while true do + child = parent.ChildAdded:wait() + if child.Name==childName then return child end + end +end + +function newSound(id) + local sound = Instance.new("Sound") + sound.SoundId = id + sound.archivable = false + sound.Parent = script.Parent.Head + return sound +end + +-- declarations + +local sDied = newSound("rbxasset://sounds/uuhhh.wav") +local sFallingDown = newSound("rbxasset://sounds/splat.wav") +local sFreeFalling = newSound("rbxasset://sounds/swoosh.wav") +local sGettingUp = newSound("rbxasset://sounds/hit.wav") +local sJumping = newSound("rbxasset://sounds/button.wav") +local sRunning = newSound("rbxasset://sounds/bfsl-minifigfoots1.mp3") +sRunning.Looped = true + +local Figure = script.Parent +local Head = waitForChild(Figure, "Head") +local Humanoid = waitForChild(Figure, "Humanoid") + +-- functions + +function onDied() + sDied:Play() +end + +function onState(state, sound) + if state then + sound:Play() + else + sound:Pause() + end +end + +function onRunning(speed) + if speed>0 then + sRunning:Play() + else + sRunning:Pause() + end +end + +-- connect up + +Humanoid.Died:connect(onDied) +Humanoid.Running:connect(onRunning) +Humanoid.Jumping:connect(function(state) onState(state, sJumping) end) +Humanoid.GettingUp:connect(function(state) onState(state, sGettingUp) end) +Humanoid.FreeFalling:connect(function(state) onState(state, sFreeFalling) end) +Humanoid.FallingDown:connect(function(state) onState(state, sFallingDown) end) + + true + + + \ No newline at end of file diff --git a/clients/2011M/content/fonts/humanoidStatic.rbxm b/clients/2011M/content/fonts/humanoidStatic.rbxm new file mode 100644 index 0000000..1c9fcb7 --- /dev/null +++ b/clients/2011M/content/fonts/humanoidStatic.rbxm @@ -0,0 +1,12 @@ + + null + nil + + + false + Static + local Figure = script.Parent local Torso = Figure:findFirstChild("Torso") Torso:makeJoints() + true + + + \ No newline at end of file diff --git a/clients/2011M/content/fonts/leftarm.mesh b/clients/2011M/content/fonts/leftarm.mesh new file mode 100644 index 0000000..6e8bb63 Binary files /dev/null and b/clients/2011M/content/fonts/leftarm.mesh differ diff --git a/clients/2011M/content/fonts/leftleg.mesh b/clients/2011M/content/fonts/leftleg.mesh new file mode 100644 index 0000000..aba3a29 Binary files /dev/null and b/clients/2011M/content/fonts/leftleg.mesh differ diff --git a/clients/2011M/content/fonts/libraries.rbxm b/clients/2011M/content/fonts/libraries.rbxm new file mode 100644 index 0000000..71630fe --- /dev/null +++ b/clients/2011M/content/fonts/libraries.rbxm @@ -0,0 +1,7208 @@ + + null + nil + + + false + + Sorter + print("Special thanks to Bitl, Carrot, iago, winsupermario1234, Khangaroo, drslicendice, coke, TheLivingBee, Raymonf, and a bunch of play - testers for help making 2011 fully stable and work. 8)") +script.Playerlist:clone().Parent = game.StarterGui +script.Dialogs:clone().Parent = game.StarterGui +script.Health:clone().Parent = game.StarterGui +script.ReenableDialogScript:clone().Parent = game.Lighting +script.TimeoutScript:clone().Parent = game.Lighting +script.ResetCommand:clone().Parent = game.Workspace +script:remove() + true + + + + true + + ReenableDialogScript + wait(5) +local dialog = script.Parent +if dialog:IsA("Dialog") then + dialog.InUse = false +end +script:Remove() + + true + + + + + true + + TimeoutScript + wait(5) +local dialog = script.Parent +if dialog:IsA("Dialog") then + dialog.InUse = false +end +script:Remove() + + true + + + + + false + + ResetCommand + function onChatted(msg, speaker) + + source = string.lower(speaker.Name) + msg = string.lower(msg) + -- Note: This one is NOT caps sensitive + + if msg == "!!!reset" then + speaker.Character.Humanoid.Health = 0 + end +end + +function onPlayerEntered(newPlayer) + newPlayer.Chatted:connect(function(msg) onChatted(msg, newPlayer) end) +end + +game.Players.ChildAdded:connect(onPlayerEntered) + true + + + + + Health + true + + + + false + 4285215356 + 1 + 4279970357 + 1 + tray + + 0.5 + -44 + 1 + -26 + + + 0 + 170 + 0 + 18 + + 2 + 0 + true + 1 + true + + + + false + 4294967295 + 1 + 4279970357 + 1 + rbxasset://../../../shareddata/textures/healthgui/bkg.png + bkg + + 0 + 0 + 0 + 0 + + + 1 + 0 + 1 + 0 + + 0 + true + 1 + true + + + + + false + 4294967295 + 1 + 4279970357 + 1 + rbxasset://../../../shareddata/textures/healthgui/BarRed.png + barRed + + 0.0189999994 + 0 + 0.100000001 + 0 + + + 0 + 0 + 0 + 0 + + 0 + true + 1 + true + + + + + false + 4294967295 + 1.00000012 + 4279970357 + 0 + bar2 + + 0.0189999994 + 0 + 0.100000001 + 0 + + + 0.192000002 + 0 + 0.829999983 + 0 + + 0 + 0 + true + 1 + true + + + + false + + Init + h = game.Players.LocalPlayer.Character.Humanoid +tray = script.Parent.Parent +base = tray.Parent +local lastHealth = 100 +local lastHealth2 = 100 +local maxWidth = 0.96 + +function UpdateGUI(health) + local width = (health / h.MaxHealth) * maxWidth + local height = 0.83 + local lastX = tray.bar.Position.X.Scale + local x = 0.019 + (maxWidth - width) + local y = 0.1 + + tray.bar.Position = UDim2.new(x,0,y, 0) + tray.bar.Size = UDim2.new(width, 0, height, 0) + -- If more than 1/4 health, bar = green. Else, bar = red. + if( (health / h.MaxHealth) > 0.25 ) then + tray.barRed.Size = UDim2.new(0, 0, 0, 0) + else + tray.barRed.Position = tray.bar.Position + tray.barRed.Size = tray.bar.Size + tray.bar.Size = UDim2.new(0, 0, 0, 0) + end + + if ( (lastHealth - health) > (h.MaxHealth / 10) ) then + lastHealth = health + + if h.Health ~= h.MaxHealth then + delay(0,function() + AnimateHurtOverlay() + end) + delay(0,function() + AnimateBars(x, y, lastX, height) + end) + end + else + lastHealth = health + end +end + +function AnimateBars(x, y, lastX, height) + local width = math.abs(x - lastX) + if( x > lastX ) then + x = lastX + end + tray.bar2.Position = UDim2.new(x,0, y, 0) + tray.bar2.Size = UDim2.new(width, 0, height, 0) + tray.bar2.BackgroundTransparency = 0 + local GBchannels = 1 + local j = 0.2 + + local i_total = 30 + for i=1,i_total do + -- Increment Values + if (GBchannels < 0.2) then + j = -j + end + GBchannels = GBchannels + j + if (i > (i_total - 10)) then + tray.bar2.BackgroundTransparency = tray.bar2.BackgroundTransparency + 0.1 + end + tray.bar2.BackgroundColor3 = Color3.new(1, GBchannels, GBchannels) + + wait(0.02) + end +end + +function AnimateHurtOverlay() + -- Start: + -- overlay.Position = UDim2.new(0, 0, 0, -22) + -- overlay.Size = UDim2.new(1, 0, 1.15, 30) + + -- Finish: + -- overlay.Position = UDim2.new(-2, 0, -2, -22) + -- overlay.Size = UDim2.new(4.5, 0, 4.65, 30) + + overlay = base.hurtOverlay + overlay.Visible = true + overlay.Position = UDim2.new(-2, 0, -2, -22) + overlay.Size = UDim2.new(4.5, 0, 4.65, 30) + -- Animate In, fast + local i_total = 2 + local wiggle_total = 0 + local wiggle_i = 0.02 + for i=1,i_total do + overlay.Position = UDim2.new( (-2 + (2 * (i/i_total)) + wiggle_total/2), 0, (-2 + (2 * (i/i_total)) + wiggle_total/2), -22 ) + overlay.Size = UDim2.new( (4.5 - (3.5 * (i/i_total)) + wiggle_total), 0, (4.65 - (3.5 * (i/i_total)) + wiggle_total), 30 ) + wait(0.01) + end + + i_total = 30 + + wait(0.03) + + -- Animate Out, slow + for i=1,i_total do + if( math.abs(wiggle_total) > (wiggle_i * 3) ) then + wiggle_i = -wiggle_i + end + wiggle_total = wiggle_total + wiggle_i + overlay.Position = UDim2.new( (0 - (2 * (i/i_total)) + wiggle_total/2), 0, (0 - (2 * (i/i_total)) + wiggle_total/2), -22 ) + overlay.Size = UDim2.new( (1 + (3.5 * (i/i_total)) + wiggle_total), 0, (1.15 + (3.5 * (i/i_total)) + wiggle_total), 30 ) + wait(0.01) + end + + -- Hide after we're done + overlay.Position = UDim2.new(10, 0, 0, 0) + overlay.Visible = false +end + +h.Changed:connect(function() + UpdateGUI(h.Health) + if ( (lastHealth2 - h.Health) > (h.MaxHealth / 10) ) then + lastHealth2 = h.Health + else + lastHealth2 = h.Health + end end) + true + + + + + + false + 4294967295 + 1 + 4279970357 + 1 + rbxasset://../../../shareddata/textures/healthgui/Bar.png + bar + + 0.0189999994 + 0 + 0.100000001 + 0 + + + 0.959999979 + 0 + 0.829999983 + 0 + + 0 + true + 1 + true + + + + + false + 4294967295 + 1 + 4279970357 + 0 + rbxasset://../../../shareddata/textures/healthgui/label.png + label + + 0.680000007 + 0 + 0.300000012 + 0 + + + 0.25 + 0 + 0.349999994 + 0 + + 0 + true + 1 + true + + + + + + false + 4290164919 + 1 + 4279970357 + 1 + rbxasset://../../../shareddata/textures/healthgui/HurtOverlay.png + hurtOverlay + + 2 + 0 + 0 + -22 + + + 1 + 0 + 1.1500001 + 30 + + 0 + false + 1 + true + + + + + + Dialogs + true + + + + false + 4288914085 + 1 + 4279970357 + 1 + ControlFrame + + 0 + 0 + 0 + 0 + + + 1 + 0 + 1 + 0 + + 0 + 0 + true + 1 + true + + + + false + 4288914085 + 1 + 4279970357 + 1 + BottomLeftControl + + 0 + 0 + 1 + -46 + + + 0 + 130 + 0 + 46 + + 0 + 0 + true + 1 + true + + + + + + false + + Init + --rbxsig%XeVmMtUuu+dXh8pEbcaTkr2m9RJZXY42LaACJ12YYcuPtOUxy4Azi8uMDGU8ZTh7cvZC9BlOWgqmZHKjESSdfOZl0/cgd2JKHPZ2UqiqA1slJa7R5GtCcGXlNPHW8KDYgJGRuwe8h5CSiMDOl6QLTSEegTOG7fzHk/n1AFcRN8I=% +--rbxassetid%39250920% +--fixed by Carrot#0559 + +function waitForProperty(instance, name) + while not instance[name] do + instance.Changed:wait() + end +end + +local beter = game.Lighting + +function waitForDialogChildrenMyLord(beter, name) + while not beter:FindFirstChild(name) do + beter.ChildAdded:wait() + end +end + +local bois = game.Players.LocalPlayer.PlayerGui + +function waitForFaker(bois, name) + while not bois:FindFirstChild(name) do + bois.ChildAdded:wait() + end +end + + +local mainFrame +local choices = {} +local lastChoice +local choiceMap = {} +local currentConversationDialog +local currentConversationPartner +local currentAbortDialogScript + +local tooFarAwayMessage = "You are too far away to chat!" +local tooFarAwaySize = 300 +local characterWanderedOffMessage = "Chat ended because you walked away" +local characterWanderedOffSize = 350 +local conversationTimedOut = "Chat ended because you didn't reply" +local conversationTimedOutSize = 350 + +local player +local screenGui +local chatNotificationGui +local messageDialog +local timeoutScript = game.Lighting.ReenableDialogScript +local reenableDialogScript = game.Lighting.TimeoutScript +local dialogMap = {} +local dialogConnections = {} + +local gui = nil +--waitForDialogChildrenMyLord(game,"CoreGui") +--waitForDialogChildrenMyLord(game.CoreGui,"RobloxGui") +--if game.CoreGui.RobloxGui:FindFirstChild("ControlFrame") then +-- gui = game.CoreGui.RobloxGui.ControlFrame +--else +-- gui = game.CoreGui.RobloxGui +--end + +function currentTone() + if currentConversationDialog then + return currentConversationDialog.Tone + else + return Enum.DialogTone.Neutral + end +end + + +function createChatNotificationGui() + chatNotificationGui = Instance.new("BillboardGui") + chatNotificationGui.Name = "ChatNotificationGui" + chatNotificationGui.ExtentsOffset = Vector3.new(0,1,0) + chatNotificationGui.Size = UDim2.new(4, 0, 5.42857122, 0) + chatNotificationGui.SizeOffset = Vector2.new(0,0) + chatNotificationGui.StudsOffset = Vector3.new(0.4, 4.3, 0) + chatNotificationGui.Enabled = true + chatNotificationGui.Active = true + + local image = Instance.new("ImageLabel") + image.Name = "Image" + image.Active = false + image.BackgroundTransparency = 1 + image.Position = UDim2.new(0,0,0,0) + image.Size = UDim2.new(1.0,0,1.0,0) + image.Image = "" + image.Parent = chatNotificationGui + + + local button = Instance.new("ImageButton") + button.Name = "Button" + button.AutoButtonColor = false + button.Position = UDim2.new(0.0879999995, 0, 0.0529999994, 0) + button.Size = UDim2.new(0.829999983, 0, 0.460000008, 0) + button.Image = "" + button.BackgroundTransparency = 1 + button.Parent = image +end + +function getChatColor(tone) + if tone == Enum.DialogTone.Neutral then + return Enum.ChatColor.Blue + elseif tone == Enum.DialogTone.Friendly then + return Enum.ChatColor.Green + elseif tone == Enum.DialogTone.Enemy then + return Enum.ChatColor.Red + end +end + +function styleChoices(tone) + for i, obj in pairs(choices) do + resetColor(obj, tone) + end + resetColor(lastChoice, tone) +end + +function styleMainFrame(tone) + if tone == Enum.DialogTone.Neutral then + mainFrame.Style = Enum.FrameStyle.ChatBlue + mainFrame.Tail.Image = "rbxasset://textures/chatBubble_botBlue_tailRight.png" + elseif tone == Enum.DialogTone.Friendly then + mainFrame.Style = Enum.FrameStyle.ChatGreen + mainFrame.Tail.Image = "rbxasset://textures/chatBubble_botGreen_tailRight.png" + elseif tone == Enum.DialogTone.Enemy then + mainFrame.Style = Enum.FrameStyle.ChatRed + mainFrame.Tail.Image = "rbxasset://textures/chatBubble_botRed_tailRight.png" + end + + styleChoices(tone) +end +function setChatNotificationTone(gui, purpose, tone) + if tone == Enum.DialogTone.Neutral then + gui.Image.Image = "rbxasset://textures/chatBubble_botBlue_notify_bkg.png" + elseif tone == Enum.DialogTone.Friendly then + gui.Image.Image = "rbxasset://textures/chatBubble_botGreen_notify_bkg.png" + elseif tone == Enum.DialogTone.Enemy then + gui.Image.Image = "rbxasset://textures/chatBubble_botRed_notify_bkg.png" + end + if purpose == Enum.DialogPurpose.Quest then + gui.Image.Button.Image = "rbxasset://textures/chatBubble_bot_notify_bang.png" + elseif purpose == Enum.DialogPurpose.Help then + gui.Image.Button.Image = "rbxasset://textures/chatBubble_bot_notify_question.png" + elseif purpose == Enum.DialogPurpose.Shop then + gui.Image.Button.Image = "rbxasset://textures/chatBubble_bot_notify_money.png" + end +end + +function createMessageDialog() + messageDialog = Instance.new("Frame"); + messageDialog.Name = "DialogScriptMessage" + messageDialog.Style = Enum.FrameStyle.RobloxRound + messageDialog.Visible = false + + local text = Instance.new("TextLabel") + text.Name = "Text" + text.Position = UDim2.new(0,0,0,-1) + text.Size = UDim2.new(1,0,1,0) + text.FontSize = Enum.FontSize.Size14 + text.BackgroundTransparency = 1 + text.TextColor3 = Color3.new(1,1,1) + text.Parent = messageDialog +end + +function showMessage(msg, size) + messageDialog.Text.Text = msg + messageDialog.Size = UDim2.new(0,size,0,40) + messageDialog.Position = UDim2.new(0.5, -size/2, 0.5, -40) + messageDialog.Visible = true + wait(2) + messageDialog.Visible = false +end + +function variableDelay(str) + local length = math.min(string.len(str), 100) + wait(0.75 + ((length/75) * 1.5)) +end + +function resetColor(frame, tone) + if tone == Enum.DialogTone.Neutral then + frame.BackgroundColor3 = Color3.new(0/255, 0/255, 179/255) + frame.Number.TextColor3 = Color3.new(45/255, 142/255, 245/255) + elseif tone == Enum.DialogTone.Friendly then + frame.BackgroundColor3 = Color3.new(0/255, 77/255, 0/255) + frame.Number.TextColor3 = Color3.new(0/255, 190/255, 0/255) + elseif tone == Enum.DialogTone.Enemy then + frame.BackgroundColor3 = Color3.new(140/255, 0/255, 0/255) + frame.Number.TextColor3 = Color3.new(255/255,88/255, 79/255) + end +end + +function highlightColor(frame, tone) + if tone == Enum.DialogTone.Neutral then + frame.BackgroundColor3 = Color3.new(2/255, 108/255, 255/255) + frame.Number.TextColor3 = Color3.new(1, 1, 1) + elseif tone == Enum.DialogTone.Friendly then + frame.BackgroundColor3 = Color3.new(0/255, 128/255, 0/255) + frame.Number.TextColor3 = Color3.new(1, 1, 1) + elseif tone == Enum.DialogTone.Enemy then + frame.BackgroundColor3 = Color3.new(204/255, 0/255, 0/255) + frame.Number.TextColor3 = Color3.new(1, 1, 1) + end +end + +function wanderDialog() + print("Wander") + mainFrame.Visible = false + endDialog() + showMessage(characterWanderedOffMessage, characterWanderedOffSize) +end + +function timeoutDialog() + print("Timeout") + mainFrame.Visible = false + endDialog() + showMessage(conversationTimedOut, conversationTimedOutSize) +end +function normalEndDialog() + print("Done") + endDialog() +end + +function endDialog() + if currentAbortDialogScript then + currentAbortDialogScript:Remove() + currentAbortDialogScript = nil + end + + local dialog = currentConversationDialog + currentConversationDialog = nil + if dialog and dialog.InUse then + local reenableScript = reenableDialogScript:Clone() + reenableScript.archivable = false + reenableScript.Disabled = false + reenableScript.Parent = dialog + end + + for dialog, gui in pairs(dialogMap) do + if dialog and gui then + gui.Enabled = not dialog.InUse + end + end + + currentConversationPartner = nil +end + +function sanitizeMessage(msg) + if string.len(msg) == 0 then + return "..." + else + return msg + end +end + +function selectChoice(choice) + renewKillswitch(currentConversationDialog) + + --First hide the Gui + mainFrame.Visible = false + if choice == lastChoice then + game.Chat:Chat(game.Players.LocalPlayer.Character, "Goodbye!", getChatColor(currentTone())) + + normalEndDialog() + else + local dialogChoice = choiceMap[choice] + + game.Chat:Chat(game.Players.LocalPlayer.Character, sanitizeMessage(dialogChoice.UserDialog), getChatColor(currentTone())) + wait(1) + --currentConversationDialog:SignalDialogChoiceSelected(player, dialogChoice) + game.Chat:Chat(currentConversationPartner, sanitizeMessage(dialogChoice.ResponseDialog), getChatColor(currentTone())) + + variableDelay(dialogChoice.ResponseDialog) + presentDialogChoices(currentConversationPartner, dialogChoice:GetChildren()) + end +end + +function newChoice(numberText) + local frame = Instance.new("TextButton") + frame.BackgroundColor3 = Color3.new(0/255, 0/255, 179/255) + frame.AutoButtonColor = false + frame.BorderSizePixel = 0 + frame.Text = "" + frame.MouseEnter:connect(function() highlightColor(frame, currentTone()) end) + frame.MouseLeave:connect(function() resetColor(frame, currentTone()) end) + frame.MouseButton1Click:connect(function() selectChoice(frame) end) + + local number = Instance.new("TextLabel") + number.Name = "Number" + number.TextColor3 = Color3.new(127/255, 212/255, 255/255) + number.Text = numberText + number.FontSize = Enum.FontSize.Size14 + number.BackgroundTransparency = 1 + number.Position = UDim2.new(0,4,0,2) + number.Size = UDim2.new(0,20,0,24) + number.TextXAlignment = Enum.TextXAlignment.Left + number.TextYAlignment = Enum.TextYAlignment.Top + number.Parent = frame + + local prompt = Instance.new("TextLabel") + prompt.Name = "UserPrompt" + prompt.BackgroundTransparency = 1 + prompt.TextColor3 = Color3.new(1,1,1) + prompt.FontSize = Enum.FontSize.Size14 + prompt.Position = UDim2.new(0,28, 0, 2) + prompt.Size = UDim2.new(1,-32, 1, -4) + prompt.TextXAlignment = Enum.TextXAlignment.Left + prompt.TextYAlignment = Enum.TextYAlignment.Top + prompt.TextWrap = true + prompt.Parent = frame + + return frame +end +function initialize(parent) + choices[1] = newChoice("1)") + choices[2] = newChoice("2)") + choices[3] = newChoice("3)") + choices[4] = newChoice("4)") + + lastChoice = newChoice("5)") + lastChoice.UserPrompt.Text = "Goodbye!" + lastChoice.Size = UDim2.new(1,0,0,28) + + mainFrame = Instance.new("Frame") + mainFrame.Name = "UserDialogArea" + mainFrame.Size = UDim2.new(0, 350, 0, 200) + mainFrame.Style = Enum.FrameStyle.ChatBlue + mainFrame.Visible = false + + local imageLabel = Instance.new("ImageLabel") + imageLabel.Name = "Tail" + imageLabel.Size = UDim2.new(0,62,0,53) + imageLabel.Position = UDim2.new(1,8,0.25) + imageLabel.Image = "rbxasset://textures/chatBubble_botBlue_tailRight.png" + imageLabel.BackgroundTransparency = 1 + imageLabel.Parent = mainFrame + + for n, obj in pairs(choices) do + obj.Parent = mainFrame + end + lastChoice.Parent = mainFrame + + mainFrame.Parent = parent +end + +function presentDialogChoices(talkingPart, dialogChoices) + if not currentConversationDialog then + return + end + + currentConversationPartner = talkingPart + local sortedDialogChoices = {} + for n, obj in pairs(dialogChoices) do + if obj:IsA("DialogChoice") then + table.insert(sortedDialogChoices, obj) + end + end + table.sort(sortedDialogChoices, function(a,b) return a.Name < b.Name end) + + if #sortedDialogChoices == 0 then + normalEndDialog() + return + end + + local pos = 1 + local yPosition = 0 + choiceMap = {} + for n, obj in pairs(choices) do + obj.Visible = false + end + + for n, obj in pairs(sortedDialogChoices) do + if pos <= #choices then + --3 lines is the maximum, set it to that temporarily + choices[pos].Size = UDim2.new(1, 0, 0, 24*3) + choices[pos].UserPrompt.Text = obj.UserDialog + local height = math.ceil(choices[pos].UserPrompt.TextBounds.Y/24)*24 + + choices[pos].Position = UDim2.new(0, 0, 0, yPosition) + choices[pos].Size = UDim2.new(1, 0, 0, height) + choices[pos].Visible = true + + choiceMap[choices[pos]] = obj + + yPosition = yPosition + height + pos = pos + 1 + end + end + + lastChoice.Position = UDim2.new(0,0,0,yPosition) + lastChoice.Number.Text = pos .. ")" + + mainFrame.Size = UDim2.new(0, 350, 0, yPosition+24+32) + mainFrame.Position = UDim2.new(0,20,0.0, -mainFrame.Size.Y.Offset-20) + styleMainFrame(currentTone()) + mainFrame.Visible = true +end + +function doDialog(dialog) + while not Instance.Lock(dialog, player) do + wait() + end + + if dialog.InUse then + Instance.Unlock(dialog) + return + else + dialog.InUse = true + Instance.Unlock(dialog) + end + + currentConversationDialog = dialog + game.Chat:Chat(dialog.Parent, dialog.InitialPrompt, getChatColor(dialog.Tone)) + variableDelay(dialog.InitialPrompt) + + presentDialogChoices(dialog.Parent, dialog:GetChildren()) +end + +function renewKillswitch(dialog) + if currentAbortDialogScript then + currentAbortDialogScript:Remove() + currentAbortDialogScript = nil + end + + currentAbortDialogScript = timeoutScript:Clone() + currentAbortDialogScript.archivable = false + currentAbortDialogScript.Disabled = false + currentAbortDialogScript.Parent = dialog +end + +function checkForLeaveArea() + while currentConversationDialog do + if currentConversationDialog.Parent and (player:DistanceFromCharacter(currentConversationDialog.Parent.Position) >= currentConversationDialog.ConversationDistance) then + wanderDialog() + end + wait(1) + end +end + +function startDialog(dialog) + if dialog.Parent and dialog.Parent:IsA("BasePart") then + if player:DistanceFromCharacter(dialog.Parent.Position) >= dialog.ConversationDistance then + showMessage(tooFarAwayMessage, tooFarAwaySize) + return + end + + for dialog, gui in pairs(dialogMap) do + if dialog and gui then + gui.Enabled = false + end + end + + renewKillswitch(dialog) + + delay(1, checkForLeaveArea) + doDialog(dialog) + end +end + +function removeDialog(dialog) + if dialogMap[dialog] then + dialogMap[dialog]:Remove() + dialogMap[dialog] = nil + end + if dialogConnections[dialog] then + dialogConnections[dialog]:disconnect() + dialogConnections[dialog] = nil + end +end + +function addDialog(dialog) + if dialog.Parent then + if dialog.Parent:IsA("BasePart") then + local chatGui = chatNotificationGui:clone() + chatGui.Enabled = not dialog.InUse + chatGui.Adornee = dialog.Parent + chatGui.Parent = game.Players.LocalPlayer.PlayerGui + chatGui.Image.Button.MouseButton1Click:connect(function() startDialog(dialog) end) + setChatNotificationTone(chatGui, dialog.Purpose, dialog.Tone) + + dialogMap[dialog] = chatGui + + dialogConnections[dialog] = dialog.Changed:connect(function(prop) + if prop == "Parent" and dialog.Parent then + --This handles the reparenting case, seperate from removal case + removeDialog(dialog) + addDialog(dialog) + elseif prop == "InUse" then + chatGui.Enabled = not currentConversationDialog and not dialog.InUse + if dialog == currentConversationDialog then + timeoutDialog() + end + elseif prop == "Tone" or prop == "Purpose" then + setChatNotificationTone(chatGui, dialog.Purpose, dialog.Tone) + end + end) + else -- still need to listen to parent changes even if current parent is not a BasePart + dialogConnections[dialog] = dialog.Changed:connect(function(prop) + if prop == "Parent" and dialog.Parent then + --This handles the reparenting case, seperate from removal case + removeDialog(dialog) + addDialog(dialog) + end + end) + end + end +end + + +--[[function fetchScripts() + local model = game:GetService("InsertService"):LoadAsset(39226062) + if type(model) == "string" then -- load failed, lets try again + wait(0.1) + model = game:GetService("InsertService"):LoadAsset(39226062) + end + if type(model) == "string" then -- not going to work, lets bail + return + end + + waitForDialogChildrenMyLord(model,"TimeoutScript") + timeoutScript = model.TimeoutScript + waitForDialogChildrenMyLord(model,"ReenableDialogScript") + reenableDialogScript = model.ReenableDialogScript +end +]]-- + +function onLoad() + waitForProperty(game.Players, "LocalPlayer") + player = game.Players.LocalPlayer + waitForProperty(player, "Character") + + --print("Fetching Scripts") + --fetchScripts() + + --print("Creating Guis") + createChatNotificationGui() + + waitForFaker(bois,"Dialogs") + --print("Creating MessageDialog") + createMessageDialog() + messageDialog.Parent = game.Players.LocalPlayer.PlayerGui.Dialogs + + + --print("Initializing Frame") + local frame = Instance.new("Frame") + frame.Name = "DialogFrame" + frame.Position = UDim2.new(0,0,0,0) + frame.Size = UDim2.new(0,0,0,0) + frame.BackgroundTransparency = 1 + frame.Parent = game.Players.LocalPlayer.PlayerGui.Dialogs.ControlFrame.BottomLeftControl + initialize(frame) + + --print("Adding Dialogs") + game.CollectionService.ItemAdded:connect(function(obj) if obj:IsA("Dialog") then addDialog(obj) end end) + game.CollectionService.ItemRemoved:connect(function(obj) if obj:IsA("Dialog") then removeDialog(obj) end end) + for i, obj in pairs(game.CollectionService:GetCollection("Dialog")) do + if obj:IsA("Dialog") then + addDialog(obj) + end + end +end + +onLoad() + true + + + + + + Playerlist + true + + + + false + + Init + --fixed by Carrot#0559 +--for non corescript use +local t = {} + +local function ScopedConnect(parentInstance, instance, event, signalFunc, syncFunc, removeFunc) + local eventConnection = nil + + --Connection on parentInstance is scoped by parentInstance (when destroyed, it goes away) + local tryConnect = function() + if game:IsAncestorOf(parentInstance) then + --Entering the world, make sure we are connected/synced + if not eventConnection then + eventConnection = instance[event]:connect(signalFunc) + if syncFunc then syncFunc() end + end + else + --Probably leaving the world, so disconnect for now + if eventConnection then + eventConnection:disconnect() + if removeFunc then removeFunc() end + end + end + end + + --Hook it up to ancestryChanged signal + local connection = parentInstance.AncestryChanged:connect(tryConnect) + + --Now connect us if we're already in the world + tryConnect() + + return connection +end + +local function getScreenGuiAncestor(instance) + local localInstance = instance + while localInstance and not localInstance:IsA("ScreenGui") do + localInstance = localInstance.Parent + end + return localInstance +end + +local function CreateButtons(frame, buttons, yPos, ySize) + local buttonNum = 1 + local buttonObjs = {} + for i, obj in ipairs(buttons) do + local button = Instance.new("TextButton") + button.Name = "Button" .. buttonNum + button.Font = Enum.Font.Arial + button.FontSize = Enum.FontSize.Size18 + button.AutoButtonColor = true + button.Modal = true + if obj["Style"] then + button.Style = obj.Style + else + button.Style = Enum.ButtonStyle.RobloxButton + end + if obj["ZIndex"] then + button.ZIndex = obj.ZIndex + end + button.Text = obj.Text + button.TextColor3 = Color3.new(1,1,1) + button.MouseButton1Click:connect(obj.Function) + button.Parent = frame + buttonObjs[buttonNum] = button + + buttonNum = buttonNum + 1 + end + local numButtons = buttonNum-1 + + if numButtons == 1 then + frame.Button1.Position = UDim2.new(0.35, 0, yPos.Scale, yPos.Offset) + frame.Button1.Size = UDim2.new(.4,0,ySize.Scale, ySize.Offset) + elseif numButtons == 2 then + frame.Button1.Position = UDim2.new(0.1, 0, yPos.Scale, yPos.Offset) + frame.Button1.Size = UDim2.new(.8/3,0, ySize.Scale, ySize.Offset) + + frame.Button2.Position = UDim2.new(0.55, 0, yPos.Scale, yPos.Offset) + frame.Button2.Size = UDim2.new(.35,0, ySize.Scale, ySize.Offset) + elseif numButtons >= 3 then + local spacing = .1 / numButtons + local buttonSize = .9 / numButtons + + buttonNum = 1 + while buttonNum <= numButtons do + buttonObjs[buttonNum].Position = UDim2.new(spacing*buttonNum + (buttonNum-1) * buttonSize, 0, yPos.Scale, yPos.Offset) + buttonObjs[buttonNum].Size = UDim2.new(buttonSize, 0, ySize.Scale, ySize.Offset) + buttonNum = buttonNum + 1 + end + end +end + +local function setSliderPos(newAbsPosX,slider,sliderPosition,bar,steps) + + local newStep = steps - 1 --otherwise we really get one more step than we want + local relativePosX = math.min(1, math.max(0, (newAbsPosX - bar.AbsolutePosition.X) / bar.AbsoluteSize.X )) + local wholeNum, remainder = math.modf(relativePosX * newStep) + if remainder > 0.5 then + wholeNum = wholeNum + 1 + end + relativePosX = wholeNum/newStep + + local result = math.ceil(relativePosX * newStep) + if sliderPosition.Value ~= (result + 1) then --only update if we moved a step + sliderPosition.Value = result + 1 + slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset) + end + +end + +local function cancelSlide(areaSoak) + areaSoak.Visible = false + if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end +end + +t.CreateStyledMessageDialog = function(title, message, style, buttons) + local frame = Instance.new("Frame") + frame.Size = UDim2.new(0.5, 0, 0, 165) + frame.Position = UDim2.new(0.25, 0, 0.5, -72.5) + frame.Name = "MessageDialog" + frame.Active = true + frame.Style = Enum.FrameStyle.RobloxRound + + local styleImage = Instance.new("ImageLabel") + styleImage.Name = "StyleImage" + styleImage.BackgroundTransparency = 1 + styleImage.Position = UDim2.new(0,5,0,15) + if style == "error" or style == "Error" then + styleImage.Size = UDim2.new(0, 71, 0, 71) + styleImage.Image = "http://www.roblox.com/asset/?id=42565285" + elseif style == "notify" or style == "Notify" then + styleImage.Size = UDim2.new(0, 71, 0, 71) + styleImage.Image = "http://www.roblox.com/asset/?id=42604978" + elseif style == "confirm" or style == "Confirm" then + styleImage.Size = UDim2.new(0, 74, 0, 76) + styleImage.Image = "http://www.roblox.com/asset/?id=42557901" + else + return t.CreateMessageDialog(title,message,buttons) + end + styleImage.Parent = frame + + local titleLabel = Instance.new("TextLabel") + titleLabel.Name = "Title" + titleLabel.Text = title + titleLabel.TextStrokeTransparency = 0 + titleLabel.BackgroundTransparency = 1 + titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255) + titleLabel.Position = UDim2.new(0, 80, 0, 0) + titleLabel.Size = UDim2.new(1, -80, 0, 40) + titleLabel.Font = Enum.Font.ArialBold + titleLabel.FontSize = Enum.FontSize.Size36 + titleLabel.TextXAlignment = Enum.TextXAlignment.Center + titleLabel.TextYAlignment = Enum.TextYAlignment.Center + titleLabel.Parent = frame + + local messageLabel = Instance.new("TextLabel") + messageLabel.Name = "Message" + messageLabel.Text = message + messageLabel.TextStrokeTransparency = 0 + messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255) + messageLabel.Position = UDim2.new(0.025, 80, 0, 45) + messageLabel.Size = UDim2.new(0.95, -80, 0, 55) + messageLabel.BackgroundTransparency = 1 + messageLabel.Font = Enum.Font.Arial + messageLabel.FontSize = Enum.FontSize.Size18 + messageLabel.TextWrap = true + messageLabel.TextXAlignment = Enum.TextXAlignment.Left + messageLabel.TextYAlignment = Enum.TextYAlignment.Top + messageLabel.Parent = frame + + CreateButtons(frame, buttons, UDim.new(0, 105), UDim.new(0, 40) ) + + return frame +end + +t.CreateMessageDialog = function(title, message, buttons) + local frame = Instance.new("Frame") + frame.Size = UDim2.new(0.5, 0, 0.5, 0) + frame.Position = UDim2.new(0.25, 0, 0.25, 0) + frame.Name = "MessageDialog" + frame.Active = true + frame.Style = Enum.FrameStyle.RobloxRound + + local titleLabel = Instance.new("TextLabel") + titleLabel.Name = "Title" + titleLabel.Text = title + titleLabel.BackgroundTransparency = 1 + titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255) + titleLabel.Position = UDim2.new(0, 0, 0, 0) + titleLabel.Size = UDim2.new(1, 0, 0.15, 0) + titleLabel.Font = Enum.Font.ArialBold + titleLabel.FontSize = Enum.FontSize.Size36 + titleLabel.TextXAlignment = Enum.TextXAlignment.Center + titleLabel.TextYAlignment = Enum.TextYAlignment.Center + titleLabel.Parent = frame + + local messageLabel = Instance.new("TextLabel") + messageLabel.Name = "Message" + messageLabel.Text = message + messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255) + messageLabel.Position = UDim2.new(0.025, 0, 0.175, 0) + messageLabel.Size = UDim2.new(0.95, 0, .55, 0) + messageLabel.BackgroundTransparency = 1 + messageLabel.Font = Enum.Font.Arial + messageLabel.FontSize = Enum.FontSize.Size18 + messageLabel.TextWrap = true + messageLabel.TextXAlignment = Enum.TextXAlignment.Left + messageLabel.TextYAlignment = Enum.TextYAlignment.Top + messageLabel.Parent = frame + + CreateButtons(frame, buttons, UDim.new(0.8,0), UDim.new(0.15, 0)) + + return frame +end + +t.CreateDropDownMenu = function(items, onSelect, forRoblox, whiteSkin, baseZ) + local baseZIndex = 0 + if (type(baseZ) == "number") then + baseZIndex = baseZ + end + local width = UDim.new(0, 100) + local height = UDim.new(0, 32) + + local xPos = 0.055 + local frame = Instance.new("Frame") + local textColor = Color3.new(1,1,1) + if (whiteSkin) then + textColor = Color3.new(0.5, 0.5, 0.5) + end + frame.Name = "DropDownMenu" + frame.BackgroundTransparency = 1 + frame.Size = UDim2.new(width, height) + + local dropDownMenu = Instance.new("TextButton") + dropDownMenu.Name = "DropDownMenuButton" + dropDownMenu.TextWrap = true + dropDownMenu.TextColor3 = textColor + dropDownMenu.Text = "Choose One" + dropDownMenu.Font = Enum.Font.ArialBold + dropDownMenu.FontSize = Enum.FontSize.Size18 + dropDownMenu.TextXAlignment = Enum.TextXAlignment.Left + dropDownMenu.TextYAlignment = Enum.TextYAlignment.Center + dropDownMenu.BackgroundTransparency = 1 + dropDownMenu.AutoButtonColor = true + if (whiteSkin) then + dropDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton + else + dropDownMenu.Style = Enum.ButtonStyle.RobloxButton + end + dropDownMenu.Size = UDim2.new(1,0,1,0) + dropDownMenu.Parent = frame + dropDownMenu.ZIndex = 2 + baseZIndex + + local dropDownIcon = Instance.new("ImageLabel") + dropDownIcon.Name = "Icon" + dropDownIcon.Active = false + if (whiteSkin) then + dropDownIcon.Image = "rbxasset://textures/ui/dropdown_arrow.png" + dropDownIcon.Size = UDim2.new(0,16,0,12) + dropDownIcon.Position = UDim2.new(1,-17,0.5, -6) + else + dropDownIcon.Image = "http://www.roblox.com/asset/?id=45732894" + dropDownIcon.Size = UDim2.new(0,11,0,6) + dropDownIcon.Position = UDim2.new(1,-11,0.5, -2) + end + dropDownIcon.BackgroundTransparency = 1 + dropDownIcon.Parent = dropDownMenu + dropDownIcon.ZIndex = 2 + baseZIndex + + local itemCount = #items + local dropDownItemCount = #items + local useScrollButtons = false + if dropDownItemCount > 6 then + useScrollButtons = true + dropDownItemCount = 6 + end + + local droppedDownMenu = Instance.new("TextButton") + droppedDownMenu.Name = "List" + droppedDownMenu.Text = "" + droppedDownMenu.BackgroundTransparency = 1 + --droppedDownMenu.AutoButtonColor = true + if (whiteSkin) then + droppedDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton + else + droppedDownMenu.Style = Enum.ButtonStyle.RobloxButton + end + droppedDownMenu.Visible = false + droppedDownMenu.Active = true --Blocks clicks + droppedDownMenu.Position = UDim2.new(0,0,0,0) + droppedDownMenu.Size = UDim2.new(1,0, (1 + dropDownItemCount)*.8, 0) + droppedDownMenu.Parent = frame + droppedDownMenu.ZIndex = 2 + baseZIndex + + local choiceButton = Instance.new("TextButton") + choiceButton.Name = "ChoiceButton" + choiceButton.BackgroundTransparency = 1 + choiceButton.BorderSizePixel = 0 + choiceButton.Text = "ReplaceMe" + choiceButton.TextColor3 = textColor + choiceButton.TextXAlignment = Enum.TextXAlignment.Left + choiceButton.TextYAlignment = Enum.TextYAlignment.Center + choiceButton.BackgroundColor3 = Color3.new(1, 1, 1) + choiceButton.Font = Enum.Font.Arial + choiceButton.FontSize = Enum.FontSize.Size18 + if useScrollButtons then + choiceButton.Size = UDim2.new(1,-13, .8/((dropDownItemCount + 1)*.8),0) + else + choiceButton.Size = UDim2.new(1, 0, .8/((dropDownItemCount + 1)*.8),0) + end + choiceButton.TextWrap = true + choiceButton.ZIndex = 2 + baseZIndex + + local areaSoak = Instance.new("TextButton") + areaSoak.Name = "AreaSoak" + areaSoak.Text = "" + areaSoak.BackgroundTransparency = 1 + areaSoak.Active = true + areaSoak.Size = UDim2.new(1,0,1,0) + areaSoak.Visible = false + areaSoak.ZIndex = 3 + baseZIndex + + local dropDownSelected = false + + local scrollUpButton + local scrollDownButton + local scrollMouseCount = 0 + + local setZIndex = function(baseZIndex) + droppedDownMenu.ZIndex = baseZIndex +1 + if scrollUpButton then + scrollUpButton.ZIndex = baseZIndex + 3 + end + if scrollDownButton then + scrollDownButton.ZIndex = baseZIndex + 3 + end + + local children = droppedDownMenu:GetChildren() + if children then + for i, child in ipairs(children) do + if child.Name == "ChoiceButton" then + child.ZIndex = baseZIndex + 2 + elseif child.Name == "ClickCaptureButton" then + child.ZIndex = baseZIndex + end + end + end + end + + local scrollBarPosition = 1 + local updateScroll = function() + if scrollUpButton then + scrollUpButton.Active = scrollBarPosition > 1 + end + if scrollDownButton then + scrollDownButton.Active = scrollBarPosition + dropDownItemCount <= itemCount + end + + local children = droppedDownMenu:GetChildren() + if not children then return end + + local childNum = 1 + for i, obj in ipairs(children) do + if obj.Name == "ChoiceButton" then + if childNum < scrollBarPosition or childNum >= scrollBarPosition + dropDownItemCount then + obj.Visible = false + else + obj.Position = UDim2.new(0,0,((childNum-scrollBarPosition+1)*.8)/((dropDownItemCount+1)*.8),0) + obj.Visible = true + end + obj.TextColor3 = textColor + obj.BackgroundTransparency = 1 + + childNum = childNum + 1 + end + end + end + local toggleVisibility = function() + dropDownSelected = not dropDownSelected + + areaSoak.Visible = not areaSoak.Visible + dropDownMenu.Visible = not dropDownSelected + droppedDownMenu.Visible = dropDownSelected + if dropDownSelected then + setZIndex(4 + baseZIndex) + else + setZIndex(2 + baseZIndex) + end + if useScrollButtons then + updateScroll() + end + end + droppedDownMenu.MouseButton1Click:connect(toggleVisibility) + + local updateSelection = function(text) + local foundItem = false + local children = droppedDownMenu:GetChildren() + local childNum = 1 + if children then + for i, obj in ipairs(children) do + if obj.Name == "ChoiceButton" then + if obj.Text == text then + obj.Font = Enum.Font.ArialBold + foundItem = true + scrollBarPosition = childNum + if (whiteSkin) then + obj.TextColor3 = Color3.new(90/255,142/255,233/255) + end + else + obj.Font = Enum.Font.Arial + if (whiteSkin) then + obj.TextColor3 = textColor + end + end + childNum = childNum + 1 + end + end + end + if not text then + dropDownMenu.Text = "Choose One" + scrollBarPosition = 1 + else + if not foundItem then + error("Invalid Selection Update -- " .. text) + end + + if scrollBarPosition + dropDownItemCount > itemCount + 1 then + scrollBarPosition = itemCount - dropDownItemCount + 1 + end + + dropDownMenu.Text = text + end + end + + local function scrollDown() + if scrollBarPosition + dropDownItemCount <= itemCount then + scrollBarPosition = scrollBarPosition + 1 + updateScroll() + return true + end + return false + end + local function scrollUp() + if scrollBarPosition > 1 then + scrollBarPosition = scrollBarPosition - 1 + updateScroll() + return true + end + return false + end + + if useScrollButtons then + --Make some scroll buttons + scrollUpButton = Instance.new("ImageButton") + scrollUpButton.Name = "ScrollUpButton" + scrollUpButton.BackgroundTransparency = 1 + scrollUpButton.Image = "rbxasset://textures/ui/scrollbuttonUp.png" + scrollUpButton.Size = UDim2.new(0,17,0,17) + scrollUpButton.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),0) + scrollUpButton.MouseButton1Click:connect( + function() + scrollMouseCount = scrollMouseCount + 1 + end) + scrollUpButton.MouseLeave:connect( + function() + scrollMouseCount = scrollMouseCount + 1 + end) + scrollUpButton.MouseButton1Down:connect( + function() + scrollMouseCount = scrollMouseCount + 1 + + scrollUp() + local val = scrollMouseCount + wait(0.5) + while val == scrollMouseCount do + if scrollUp() == false then + break + end + wait(0.1) + end + end) + + scrollUpButton.Parent = droppedDownMenu + + scrollDownButton = Instance.new("ImageButton") + scrollDownButton.Name = "ScrollDownButton" + scrollDownButton.BackgroundTransparency = 1 + scrollDownButton.Image = "rbxasset://textures/ui/scrollbuttonDown.png" + scrollDownButton.Size = UDim2.new(0,17,0,17) + scrollDownButton.Position = UDim2.new(1,-11,1,-11) + scrollDownButton.Parent = droppedDownMenu + scrollDownButton.MouseButton1Click:connect( + function() + scrollMouseCount = scrollMouseCount + 1 + end) + scrollDownButton.MouseLeave:connect( + function() + scrollMouseCount = scrollMouseCount + 1 + end) + scrollDownButton.MouseButton1Down:connect( + function() + scrollMouseCount = scrollMouseCount + 1 + + scrollDown() + local val = scrollMouseCount + wait(0.5) + while val == scrollMouseCount do + if scrollDown() == false then + break + end + wait(0.1) + end + end) + + local scrollbar = Instance.new("ImageLabel") + scrollbar.Name = "ScrollBar" + scrollbar.Image = "rbxasset://textures/ui/scrollbar.png" + scrollbar.BackgroundTransparency = 1 + scrollbar.Size = UDim2.new(0, 18, (dropDownItemCount*.8)/((dropDownItemCount+1)*.8), -(17) - 11 - 4) + scrollbar.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),17+2) + scrollbar.Parent = droppedDownMenu + end + + for i,item in ipairs(items) do + -- needed to maintain local scope for items in event listeners below + local button = choiceButton:clone() + if forRoblox then + button.RobloxLocked = true + end + button.Text = item + button.Parent = droppedDownMenu + if (whiteSkin) then + button.TextColor3 = textColor + end + + button.MouseButton1Click:connect(function() + --Remove Highlight + if (not whiteSkin) then + button.TextColor3 = Color3.new(1,1,1) + end + button.BackgroundTransparency = 1 + + updateSelection(item) + onSelect(item) + + toggleVisibility() + end) + button.MouseEnter:connect(function() + --Add Highlight + if (not whiteSkin) then + button.TextColor3 = Color3.new(0,0,0) + end + button.BackgroundTransparency = 0 + end) + + button.MouseLeave:connect(function() + --Remove Highlight + if (not whiteSkin) then + button.TextColor3 = Color3.new(1,1,1) + end + button.BackgroundTransparency = 1 + end) + end + + --This does the initial layout of the buttons + updateScroll() + + frame.AncestryChanged:connect(function(child,parent) + if parent == nil then + areaSoak.Parent = nil + else + areaSoak.Parent = getScreenGuiAncestor(frame) + end + end) + + dropDownMenu.MouseButton1Click:connect(toggleVisibility) + areaSoak.MouseButton1Click:connect(toggleVisibility) + return frame, updateSelection +end + +t.CreatePropertyDropDownMenu = function(instance, property, enum) + + local items = enum:GetEnumItems() + local names = {} + local nameToItem = {} + for i,obj in ipairs(items) do + names[i] = obj.Name + nameToItem[obj.Name] = obj + end + + local frame + local updateSelection + frame, updateSelection = t.CreateDropDownMenu(names, function(text) instance[property] = nameToItem[text] end) + + ScopedConnect(frame, instance, "Changed", + function(prop) + if prop == property then + updateSelection(instance[property].Name) + end + end, + function() + updateSelection(instance[property].Name) + end) + + return frame +end + +t.GetFontHeight = function(font, fontSize) + if font == nil or fontSize == nil then + error("Font and FontSize must be non-nil") + end + + if font == Enum.Font.Legacy then + if fontSize == Enum.FontSize.Size8 then + return 12 + elseif fontSize == Enum.FontSize.Size9 then + return 14 + elseif fontSize == Enum.FontSize.Size10 then + return 15 + elseif fontSize == Enum.FontSize.Size11 then + return 17 + elseif fontSize == Enum.FontSize.Size12 then + return 18 + elseif fontSize == Enum.FontSize.Size14 then + return 21 + elseif fontSize == Enum.FontSize.Size18 then + return 27 + elseif fontSize == Enum.FontSize.Size24 then + return 36 + elseif fontSize == Enum.FontSize.Size36 then + return 54 + elseif fontSize == Enum.FontSize.Size48 then + return 72 + else + error("Unknown FontSize") + end + elseif font == Enum.Font.Arial or font == Enum.Font.ArialBold then + if fontSize == Enum.FontSize.Size8 then + return 8 + elseif fontSize == Enum.FontSize.Size9 then + return 9 + elseif fontSize == Enum.FontSize.Size10 then + return 10 + elseif fontSize == Enum.FontSize.Size11 then + return 11 + elseif fontSize == Enum.FontSize.Size12 then + return 12 + elseif fontSize == Enum.FontSize.Size14 then + return 14 + elseif fontSize == Enum.FontSize.Size18 then + return 18 + elseif fontSize == Enum.FontSize.Size24 then + return 24 + elseif fontSize == Enum.FontSize.Size36 then + return 36 + elseif fontSize == Enum.FontSize.Size48 then + return 48 + else + error("Unknown FontSize") + end + else + error("Unknown Font " .. font) + end +end + +local function layoutGuiObjectsHelper(frame, guiObjects, settingsTable) + local totalPixels = frame.AbsoluteSize.Y + local pixelsRemaining = frame.AbsoluteSize.Y + for i, child in ipairs(guiObjects) do + if child:IsA("TextLabel") or child:IsA("TextButton") then + local isLabel = child:IsA("TextLabel") + if isLabel then + pixelsRemaining = pixelsRemaining - settingsTable["TextLabelPositionPadY"] + else + pixelsRemaining = pixelsRemaining - settingsTable["TextButtonPositionPadY"] + end + child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining) + child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, pixelsRemaining) + + if child.TextFits and child.TextBounds.Y < pixelsRemaining then + child.Visible = true + if isLabel then + child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable["TextLabelSizePadY"]) + else + child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable["TextButtonSizePadY"]) + end + + while not child.TextFits do + child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.AbsoluteSize.Y + 1) + end + pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y + + if isLabel then + pixelsRemaining = pixelsRemaining - settingsTable["TextLabelPositionPadY"] + else + pixelsRemaining = pixelsRemaining - settingsTable["TextButtonPositionPadY"] + end + else + child.Visible = false + pixelsRemaining = -1 + end + + else + --GuiObject + child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining) + pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y + child.Visible = (pixelsRemaining >= 0) + end + end +end + +t.LayoutGuiObjects = function(frame, guiObjects, settingsTable) + if not frame:IsA("GuiObject") then + error("Frame must be a GuiObject") + end + for i, child in ipairs(guiObjects) do + if not child:IsA("GuiObject") then + error("All elements that are layed out must be of type GuiObject") + end + end + + if not settingsTable then + settingsTable = {} + end + + if not settingsTable["TextLabelSizePadY"] then + settingsTable["TextLabelSizePadY"] = 0 + end + if not settingsTable["TextLabelPositionPadY"] then + settingsTable["TextLabelPositionPadY"] = 0 + end + if not settingsTable["TextButtonSizePadY"] then + settingsTable["TextButtonSizePadY"] = 12 + end + if not settingsTable["TextButtonPositionPadY"] then + settingsTable["TextButtonPositionPadY"] = 2 + end + + --Wrapper frame takes care of styled objects + local wrapperFrame = Instance.new("Frame") + wrapperFrame.Name = "WrapperFrame" + wrapperFrame.BackgroundTransparency = 1 + wrapperFrame.Size = UDim2.new(1,0,1,0) + wrapperFrame.Parent = frame + + for i, child in ipairs(guiObjects) do + child.Parent = wrapperFrame + end + + local recalculate = function() + wait() + layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable) + end + + frame.Changed:connect( + function(prop) + if prop == "AbsoluteSize" then + --Wait a heartbeat for it to sync in + recalculate(nil) + end + end) + frame.AncestryChanged:connect(recalculate) + + layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable) +end + + +t.CreateSlider = function(steps,width,position) + local sliderGui = Instance.new("Frame") + sliderGui.Size = UDim2.new(1,0,1,0) + sliderGui.BackgroundTransparency = 1 + sliderGui.Name = "SliderGui" + + local sliderSteps = Instance.new("IntValue") + sliderSteps.Name = "SliderSteps" + sliderSteps.Value = steps + sliderSteps.Parent = sliderGui + + local areaSoak = Instance.new("TextButton") + areaSoak.Name = "AreaSoak" + areaSoak.Text = "" + areaSoak.BackgroundTransparency = 1 + areaSoak.Active = false + areaSoak.Size = UDim2.new(1,0,1,0) + areaSoak.Visible = false + areaSoak.ZIndex = 4 + + sliderGui.AncestryChanged:connect(function(child,parent) + if parent == nil then + areaSoak.Parent = nil + else + areaSoak.Parent = getScreenGuiAncestor(sliderGui) + end + end) + + local sliderPosition = Instance.new("IntValue") + sliderPosition.Name = "SliderPosition" + sliderPosition.Value = 0 + sliderPosition.Parent = sliderGui + + local id = math.random(1,100) + + local bar = Instance.new("TextButton") + bar.Text = "" + bar.AutoButtonColor = false + bar.Name = "Bar" + bar.BackgroundColor3 = Color3.new(0,0,0) + if type(width) == "number" then + bar.Size = UDim2.new(0,width,0,5) + else + bar.Size = UDim2.new(0,200,0,5) + end + bar.BorderColor3 = Color3.new(95/255,95/255,95/255) + bar.ZIndex = 2 + bar.Parent = sliderGui + + if position["X"] and position["X"]["Scale"] and position["X"]["Offset"] and position["Y"] and position["Y"]["Scale"] and position["Y"]["Offset"] then + bar.Position = position + end + + local slider = Instance.new("ImageButton") + slider.Name = "Slider" + slider.BackgroundTransparency = 1 + slider.Image = "rbxasset://textures/ui/Slider.png" + slider.Position = UDim2.new(0,0,0.5,-10) + slider.Size = UDim2.new(0,20,0,20) + slider.ZIndex = 3 + slider.Parent = bar + + local areaSoakMouseMoveCon = nil + + areaSoak.MouseLeave:connect(function() + if areaSoak.Visible then + cancelSlide(areaSoak) + end + end) + areaSoak.MouseButton1Up:connect(function() + if areaSoak.Visible then + cancelSlide(areaSoak) + end + end) + + slider.MouseButton1Down:connect(function() + areaSoak.Visible = true + if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end + areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y) + setSliderPos(x,slider,sliderPosition,bar,steps) + end) + end) + + slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end) + + sliderPosition.Changed:connect(function(prop) + sliderPosition.Value = math.min(steps, math.max(1,sliderPosition.Value)) + local relativePosX = (sliderPosition.Value - 1) / (steps - 1) + slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset) + end) + + bar.MouseButton1Down:connect(function(x,y) + setSliderPos(x,slider,sliderPosition,bar,steps) + end) + + return sliderGui, sliderPosition, sliderSteps + +end + + + +t.CreateSliderNew = function(steps,width,position) + local sliderGui = Instance.new("Frame") + sliderGui.Size = UDim2.new(1,0,1,0) + sliderGui.BackgroundTransparency = 1 + sliderGui.Name = "SliderGui" + + local sliderSteps = Instance.new("IntValue") + sliderSteps.Name = "SliderSteps" + sliderSteps.Value = steps + sliderSteps.Parent = sliderGui + + local areaSoak = Instance.new("TextButton") + areaSoak.Name = "AreaSoak" + areaSoak.Text = "" + areaSoak.BackgroundTransparency = 1 + areaSoak.Active = false + areaSoak.Size = UDim2.new(1,0,1,0) + areaSoak.Visible = false + areaSoak.ZIndex = 6 + + sliderGui.AncestryChanged:connect(function(child,parent) + if parent == nil then + areaSoak.Parent = nil + else + areaSoak.Parent = getScreenGuiAncestor(sliderGui) + end + end) + + local sliderPosition = Instance.new("IntValue") + sliderPosition.Name = "SliderPosition" + sliderPosition.Value = 0 + sliderPosition.Parent = sliderGui + + local id = math.random(1,100) + + local sliderBarImgHeight = 7 + local sliderBarCapImgWidth = 4 + + local bar = Instance.new("ImageButton") + bar.BackgroundTransparency = 1 + bar.Image = "rbxasset://textures/ui/Slider-BKG-Center.png" + bar.Name = "Bar" + local displayWidth = 200 + if type(width) == "number" then + bar.Size = UDim2.new(0,width - (sliderBarCapImgWidth * 2),0,sliderBarImgHeight) + displayWidth = width - (sliderBarCapImgWidth * 2) + else + bar.Size = UDim2.new(0,200,0,sliderBarImgHeight) + end + bar.ZIndex = 3 + bar.Parent = sliderGui + if position["X"] and position["X"]["Scale"] and position["X"]["Offset"] and position["Y"] and position["Y"]["Scale"] and position["Y"]["Offset"] then + bar.Position = position + end + + local barLeft = bar:clone() + barLeft.Name = "BarLeft" + barLeft.Image = "rbxasset://textures/ui/Slider-BKG-Left-Cap.png" + barLeft.Size = UDim2.new(0, sliderBarCapImgWidth, 0, sliderBarImgHeight) + barLeft.Position = UDim2.new(position.X.Scale, position.X.Offset - sliderBarCapImgWidth, position.Y.Scale, position.Y.Offset) + barLeft.Parent = sliderGui + barLeft.ZIndex = 3 + + local barRight = barLeft:clone() + barRight.Name = "BarRight" + barRight.Image = "rbxasset://textures/ui/Slider-BKG-Right-Cap.png" + barRight.Position = UDim2.new(position.X.Scale, position.X.Offset + displayWidth, position.Y.Scale, position.Y.Offset) + barRight.Parent = sliderGui + + local fillLeft = barLeft:clone() + fillLeft.Name = "FillLeft" + fillLeft.Image = "rbxasset://textures/ui/Slider-Fill-Left-Cap.png" + fillLeft.Parent = sliderGui + fillLeft.ZIndex = 4 + + local fill = fillLeft:clone() + fill.Name = "Fill" + fill.Image = "rbxasset://textures/ui/Slider-Fill-Center.png" + fill.Parent = bar + fill.ZIndex = 4 + fill.Position = UDim2.new(0, 0, 0, 0) + fill.Size = UDim2.new(0.5, 0, 1, 0) + + +-- bar.Visible = false + + local slider = Instance.new("ImageButton") + slider.Name = "Slider" + slider.BackgroundTransparency = 1 + slider.Image = "rbxasset://textures/ui/slider_new_tab.png" + slider.Position = UDim2.new(0,0,0.5,-14) + slider.Size = UDim2.new(0,28,0,28) + slider.ZIndex = 5 + slider.Parent = bar + + local areaSoakMouseMoveCon = nil + + areaSoak.MouseLeave:connect(function() + if areaSoak.Visible then + cancelSlide(areaSoak) + end + end) + areaSoak.MouseButton1Up:connect(function() + if areaSoak.Visible then + cancelSlide(areaSoak) + end + end) + + slider.MouseButton1Down:connect(function() + areaSoak.Visible = true + if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end + areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y) + setSliderPos(x,slider,sliderPosition,bar,steps) + end) + end) + + slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end) + + sliderPosition.Changed:connect(function(prop) + sliderPosition.Value = math.min(steps, math.max(1,sliderPosition.Value)) + local relativePosX = (sliderPosition.Value - 1) / (steps - 1) + slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset) + fill.Size = UDim2.new(relativePosX, 0, 1, 0) + end) + + bar.MouseButton1Down:connect(function(x,y) + setSliderPos(x,slider,sliderPosition,bar,steps) + end) + + return sliderGui, sliderPosition, sliderSteps + +end + + + + + +t.CreateTrueScrollingFrame = function() + local lowY = nil + local highY = nil + + local dragCon = nil + local upCon = nil + + local internalChange = false + + local descendantsChangeConMap = {} + + local scrollingFrame = Instance.new("Frame") + scrollingFrame.Name = "ScrollingFrame" + scrollingFrame.Active = true + scrollingFrame.Size = UDim2.new(1,0,1,0) + scrollingFrame.ClipsDescendants = true + + local controlFrame = Instance.new("Frame") + controlFrame.Name = "ControlFrame" + controlFrame.BackgroundTransparency = 1 + controlFrame.Size = UDim2.new(0,18,1,0) + controlFrame.Position = UDim2.new(1,-20,0,0) + controlFrame.Parent = scrollingFrame + + local scrollBottom = Instance.new("BoolValue") + scrollBottom.Value = false + scrollBottom.Name = "ScrollBottom" + scrollBottom.Parent = controlFrame + + local scrollUp = Instance.new("BoolValue") + scrollUp.Value = false + scrollUp.Name = "scrollUp" + scrollUp.Parent = controlFrame + + local scrollUpButton = Instance.new("TextButton") + scrollUpButton.Name = "ScrollUpButton" + scrollUpButton.Text = "" + scrollUpButton.AutoButtonColor = false + scrollUpButton.BackgroundColor3 = Color3.new(0,0,0) + scrollUpButton.BorderColor3 = Color3.new(1,1,1) + scrollUpButton.BackgroundTransparency = 0.5 + scrollUpButton.Size = UDim2.new(0,18,0,18) + scrollUpButton.ZIndex = 2 + scrollUpButton.Parent = controlFrame + for i = 1, 6 do + local triFrame = Instance.new("Frame") + triFrame.BorderColor3 = Color3.new(1,1,1) + triFrame.Name = "tri" .. tostring(i) + triFrame.ZIndex = 3 + triFrame.BackgroundTransparency = 0.5 + triFrame.Size = UDim2.new(0,12 - ((i -1) * 2),0,0) + triFrame.Position = UDim2.new(0,3 + (i -1),0.5,2 - (i -1)) + triFrame.Parent = scrollUpButton + end + scrollUpButton.MouseEnter:connect(function() + scrollUpButton.BackgroundTransparency = 0.1 + local upChildren = scrollUpButton:GetChildren() + for i = 1, #upChildren do + upChildren[i].BackgroundTransparency = 0.1 + end + end) + scrollUpButton.MouseLeave:connect(function() + scrollUpButton.BackgroundTransparency = 0.5 + local upChildren = scrollUpButton:GetChildren() + for i = 1, #upChildren do + upChildren[i].BackgroundTransparency = 0.5 + end + end) + + local scrollDownButton = scrollUpButton:clone() + scrollDownButton.Name = "ScrollDownButton" + scrollDownButton.Position = UDim2.new(0,0,1,-18) + local downChildren = scrollDownButton:GetChildren() + for i = 1, #downChildren do + downChildren[i].Position = UDim2.new(0,3 + (i -1),0.5,-2 + (i - 1)) + end + scrollDownButton.MouseEnter:connect(function() + scrollDownButton.BackgroundTransparency = 0.1 + local downChildren = scrollDownButton:GetChildren() + for i = 1, #downChildren do + downChildren[i].BackgroundTransparency = 0.1 + end + end) + scrollDownButton.MouseLeave:connect(function() + scrollDownButton.BackgroundTransparency = 0.5 + local downChildren = scrollDownButton:GetChildren() + for i = 1, #downChildren do + downChildren[i].BackgroundTransparency = 0.5 + end + end) + scrollDownButton.Parent = controlFrame + + local scrollTrack = Instance.new("Frame") + scrollTrack.Name = "ScrollTrack" + scrollTrack.BackgroundTransparency = 1 + scrollTrack.Size = UDim2.new(0,18,1,-38) + scrollTrack.Position = UDim2.new(0,0,0,19) + scrollTrack.Parent = controlFrame + + local scrollbar = Instance.new("TextButton") + scrollbar.BackgroundColor3 = Color3.new(0,0,0) + scrollbar.BorderColor3 = Color3.new(1,1,1) + scrollbar.BackgroundTransparency = 0.5 + scrollbar.AutoButtonColor = false + scrollbar.Text = "" + scrollbar.Active = true + scrollbar.Name = "ScrollBar" + scrollbar.ZIndex = 2 + scrollbar.BackgroundTransparency = 0.5 + scrollbar.Size = UDim2.new(0, 18, 0.1, 0) + scrollbar.Position = UDim2.new(0,0,0,0) + scrollbar.Parent = scrollTrack + + local scrollNub = Instance.new("Frame") + scrollNub.Name = "ScrollNub" + scrollNub.BorderColor3 = Color3.new(1,1,1) + scrollNub.Size = UDim2.new(0,10,0,0) + scrollNub.Position = UDim2.new(0.5,-5,0.5,0) + scrollNub.ZIndex = 2 + scrollNub.BackgroundTransparency = 0.5 + scrollNub.Parent = scrollbar + + local newNub = scrollNub:clone() + newNub.Position = UDim2.new(0.5,-5,0.5,-2) + newNub.Parent = scrollbar + + local lastNub = scrollNub:clone() + lastNub.Position = UDim2.new(0.5,-5,0.5,2) + lastNub.Parent = scrollbar + + scrollbar.MouseEnter:connect(function() + scrollbar.BackgroundTransparency = 0.1 + scrollNub.BackgroundTransparency = 0.1 + newNub.BackgroundTransparency = 0.1 + lastNub.BackgroundTransparency = 0.1 + end) + scrollbar.MouseLeave:connect(function() + scrollbar.BackgroundTransparency = 0.5 + scrollNub.BackgroundTransparency = 0.5 + newNub.BackgroundTransparency = 0.5 + lastNub.BackgroundTransparency = 0.5 + end) + + local mouseDrag = Instance.new("ImageButton") + mouseDrag.Active = false + mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0) + mouseDrag.AutoButtonColor = false + mouseDrag.BackgroundTransparency = 1 + mouseDrag.Name = "mouseDrag" + mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0) + mouseDrag.ZIndex = 10 + + local function positionScrollBar(x,y,offset) + local oldPos = scrollbar.Position + + if y < scrollTrack.AbsolutePosition.y then + scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0) + return (oldPos ~= scrollbar.Position) + end + + local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y + + if y > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then + scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0) + return (oldPos ~= scrollbar.Position) + end + local newScaleYPos = (y - scrollTrack.AbsolutePosition.y - offset)/scrollTrack.AbsoluteSize.y + if newScaleYPos + relativeSize > 1 then + newScaleYPos = 1 - relativeSize + scrollBottom.Value = true + scrollUp.Value = false + elseif newScaleYPos <= 0 then + newScaleYPos = 0 + scrollUp.Value = true + scrollBottom.Value = false + else + scrollUp.Value = false + scrollBottom.Value = false + end + scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,newScaleYPos,0) + + return (oldPos ~= scrollbar.Position) + end + + local function drillDownSetHighLow(instance) + if not instance or not instance:IsA("GuiObject") then return end + if instance == controlFrame then return end + if instance:IsDescendantOf(controlFrame) then return end + if not instance.Visible then return end + + if lowY and lowY > instance.AbsolutePosition.Y then + lowY = instance.AbsolutePosition.Y + elseif not lowY then + lowY = instance.AbsolutePosition.Y + end + if highY and highY < (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) then + highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y + elseif not highY then + highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y + end + local children = instance:GetChildren() + for i = 1, #children do + drillDownSetHighLow(children[i]) + end + end + + local function resetHighLow() + local firstChildren = scrollingFrame:GetChildren() + + for i = 1, #firstChildren do + drillDownSetHighLow(firstChildren[i]) + end + end + + local function recalculate() + internalChange = true + + local percentFrame = 0 + if scrollbar.Position.Y.Scale > 0 then + if scrollbar.Visible then + percentFrame = scrollbar.Position.Y.Scale/((scrollTrack.AbsoluteSize.Y - scrollbar.AbsoluteSize.Y)/scrollTrack.AbsoluteSize.Y) + else + percentFrame = 0 + end + end + if percentFrame > 0.99 then percentFrame = 1 end + + local hiddenYAmount = (scrollingFrame.AbsoluteSize.Y - (highY - lowY)) * percentFrame + + local guiChildren = scrollingFrame:GetChildren() + for i = 1, #guiChildren do + if guiChildren[i] ~= controlFrame then + guiChildren[i].Position = UDim2.new(guiChildren[i].Position.X.Scale,guiChildren[i].Position.X.Offset, + 0, math.ceil(guiChildren[i].AbsolutePosition.Y) - math.ceil(lowY) + hiddenYAmount) + end + end + + lowY = nil + highY = nil + resetHighLow() + internalChange = false + end + + local function setSliderSizeAndPosition() + if not highY or not lowY then return end + + local totalYSpan = math.abs(highY - lowY) + if totalYSpan == 0 then + scrollbar.Visible = false + scrollDownButton.Visible = false + scrollUpButton.Visible = false + + if dragCon then dragCon:disconnect() dragCon = nil end + if upCon then upCon:disconnect() upCon = nil end + return + end + + local percentShown = scrollingFrame.AbsoluteSize.Y/totalYSpan + if percentShown >= 1 then + scrollbar.Visible = false + scrollDownButton.Visible = false + scrollUpButton.Visible = false + recalculate() + else + scrollbar.Visible = true + scrollDownButton.Visible = true + scrollUpButton.Visible = true + + scrollbar.Size = UDim2.new(scrollbar.Size.X.Scale,scrollbar.Size.X.Offset,percentShown,0) + end + + local percentPosition = (scrollingFrame.AbsolutePosition.Y - lowY)/totalYSpan + scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,percentPosition,-scrollbar.AbsoluteSize.X/2) + + if scrollbar.AbsolutePosition.y < scrollTrack.AbsolutePosition.y then + scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0) + end + + if (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.Y) > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then + local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y + scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0) + end + end + + local buttonScrollAmountPixels = 7 + local reentrancyGuardScrollUp = false + local function doScrollUp() + if reentrancyGuardScrollUp then return end + + reentrancyGuardScrollUp = true + if positionScrollBar(0,scrollbar.AbsolutePosition.Y - buttonScrollAmountPixels,0) then + recalculate() + end + reentrancyGuardScrollUp = false + end + + local reentrancyGuardScrollDown = false + local function doScrollDown() + if reentrancyGuardScrollDown then return end + + reentrancyGuardScrollDown = true + if positionScrollBar(0,scrollbar.AbsolutePosition.Y + buttonScrollAmountPixels,0) then + recalculate() + end + reentrancyGuardScrollDown = false + end + + local function scrollUp(mouseYPos) + if scrollUpButton.Active then + scrollStamp = tick() + local current = scrollStamp + local upCon + upCon = mouseDrag.MouseButton1Up:connect(function() + scrollStamp = tick() + mouseDrag.Parent = nil + upCon:disconnect() + end) + mouseDrag.Parent = getScreenGuiAncestor(scrollbar) + doScrollUp() + wait(0.2) + local t = tick() + local w = 0.1 + while scrollStamp == current do + doScrollUp() + if mouseYPos and mouseYPos > scrollbar.AbsolutePosition.y then + break + end + if not scrollUpButton.Active then break end + if tick()-t > 5 then + w = 0 + elseif tick()-t > 2 then + w = 0.06 + end + wait(w) + end + end + end + + local function scrollDown(mouseYPos) + if scrollDownButton.Active then + scrollStamp = tick() + local current = scrollStamp + local downCon + downCon = mouseDrag.MouseButton1Up:connect(function() + scrollStamp = tick() + mouseDrag.Parent = nil + downCon:disconnect() + end) + mouseDrag.Parent = getScreenGuiAncestor(scrollbar) + doScrollDown() + wait(0.2) + local t = tick() + local w = 0.1 + while scrollStamp == current do + doScrollDown() + if mouseYPos and mouseYPos < (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.x) then + break + end + if not scrollDownButton.Active then break end + if tick()-t > 5 then + w = 0 + elseif tick()-t > 2 then + w = 0.06 + end + wait(w) + end + end + end + + scrollbar.MouseButton1Down:connect(function(x,y) + if scrollbar.Active then + scrollStamp = tick() + local mouseOffset = y - scrollbar.AbsolutePosition.y + if dragCon then dragCon:disconnect() dragCon = nil end + if upCon then upCon:disconnect() upCon = nil end + local prevY = y + local reentrancyGuardMouseScroll = false + dragCon = mouseDrag.MouseMoved:connect(function(x,y) + if reentrancyGuardMouseScroll then return end + + reentrancyGuardMouseScroll = true + if positionScrollBar(x,y,mouseOffset) then + recalculate() + end + reentrancyGuardMouseScroll = false + + end) + upCon = mouseDrag.MouseButton1Up:connect(function() + scrollStamp = tick() + mouseDrag.Parent = nil + dragCon:disconnect(); dragCon = nil + upCon:disconnect(); drag = nil + end) + mouseDrag.Parent = getScreenGuiAncestor(scrollbar) + end + end) + + local scrollMouseCount = 0 + + scrollUpButton.MouseButton1Down:connect(function() + scrollUp() + end) + scrollUpButton.MouseButton1Up:connect(function() + scrollStamp = tick() + end) + + scrollDownButton.MouseButton1Up:connect(function() + scrollStamp = tick() + end) + scrollDownButton.MouseButton1Down:connect(function() + scrollDown() + end) + + scrollbar.MouseButton1Up:connect(function() + scrollStamp = tick() + end) + + local function heightCheck(instance) + if highY and (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) > highY then + highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y + elseif not highY then + highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y + end + setSliderSizeAndPosition() + end + + local function highLowRecheck() + local oldLowY = lowY + local oldHighY = highY + lowY = nil + highY = nil + resetHighLow() + + if (lowY ~= oldLowY) or (highY ~= oldHighY) then + setSliderSizeAndPosition() + end + end + + local function descendantChanged(this, prop) + if internalChange then return end + if not this.Visible then return end + + if prop == "Size" or prop == "Position" then + wait() + highLowRecheck() + end + end + + scrollingFrame.DescendantAdded:connect(function(instance) + if not instance:IsA("GuiObject") then return end + + if instance.Visible then + wait() -- wait a heartbeat for sizes to reconfig + highLowRecheck() + end + + descendantsChangeConMap[instance] = instance.Changed:connect(function(prop) descendantChanged(instance, prop) end) + end) + + scrollingFrame.DescendantRemoving:connect(function(instance) + if not instance:IsA("GuiObject") then return end + if descendantsChangeConMap[instance] then + descendantsChangeConMap[instance]:disconnect() + descendantsChangeConMap[instance] = nil + end + wait() -- wait a heartbeat for sizes to reconfig + highLowRecheck() + end) + + scrollingFrame.Changed:connect(function(prop) + if prop == "AbsoluteSize" then + if not highY or not lowY then return end + + highLowRecheck() + setSliderSizeAndPosition() + end + end) + + return scrollingFrame, controlFrame +end + +t.CreateScrollingFrame = function(orderList,scrollStyle) + local frame = Instance.new("Frame") + frame.Name = "ScrollingFrame" + frame.BackgroundTransparency = 1 + frame.Size = UDim2.new(1,0,1,0) + + local scrollUpButton = Instance.new("ImageButton") + scrollUpButton.Name = "ScrollUpButton" + scrollUpButton.BackgroundTransparency = 1 + scrollUpButton.Image = "rbxasset://textures/ui/scrollbuttonUp.png" + scrollUpButton.Size = UDim2.new(0,17,0,17) + + + local scrollDownButton = Instance.new("ImageButton") + scrollDownButton.Name = "ScrollDownButton" + scrollDownButton.BackgroundTransparency = 1 + scrollDownButton.Image = "rbxasset://textures/ui/scrollbuttonDown.png" + scrollDownButton.Size = UDim2.new(0,17,0,17) + + local scrollbar = Instance.new("ImageButton") + scrollbar.Name = "ScrollBar" + scrollbar.Image = "rbxasset://textures/ui/scrollbar.png" + scrollbar.BackgroundTransparency = 1 + scrollbar.Size = UDim2.new(0, 18, 0, 150) + + local scrollStamp = 0 + + local scrollDrag = Instance.new("ImageButton") + scrollDrag.Image = "http://www.roblox.com/asset/?id=61367186" + scrollDrag.Size = UDim2.new(1, 0, 0, 16) + scrollDrag.BackgroundTransparency = 1 + scrollDrag.Name = "ScrollDrag" + scrollDrag.Active = true + scrollDrag.Parent = scrollbar + + local mouseDrag = Instance.new("ImageButton") + mouseDrag.Active = false + mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0) + mouseDrag.AutoButtonColor = false + mouseDrag.BackgroundTransparency = 1 + mouseDrag.Name = "mouseDrag" + mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0) + mouseDrag.ZIndex = 10 + + local style = "simple" + if scrollStyle and tostring(scrollStyle) then + style = scrollStyle + end + + local scrollPosition = 1 + local rowSize = 0 + local howManyDisplayed = 0 + + local layoutGridScrollBar = function() + howManyDisplayed = 0 + local guiObjects = {} + if orderList then + for i, child in ipairs(orderList) do + if child.Parent == frame then + table.insert(guiObjects, child) + end + end + else + local children = frame:GetChildren() + if children then + for i, child in ipairs(children) do + if child:IsA("GuiObject") then + table.insert(guiObjects, child) + end + end + end + end + if #guiObjects == 0 then + scrollUpButton.Active = false + scrollDownButton.Active = false + scrollDrag.Active = false + scrollPosition = 1 + return + end + + if scrollPosition > #guiObjects then + scrollPosition = #guiObjects + end + + if scrollPosition < 1 then scrollPosition = 1 end + + local totalPixelsY = frame.AbsoluteSize.Y + local pixelsRemainingY = frame.AbsoluteSize.Y + + local totalPixelsX = frame.AbsoluteSize.X + + local xCounter = 0 + local rowSizeCounter = 0 + local setRowSize = true + + local pixelsBelowScrollbar = 0 + local pos = #guiObjects + + local currentRowY = 0 + + pos = scrollPosition + --count up from current scroll position to fill out grid + while pos <= #guiObjects and pixelsBelowScrollbar < totalPixelsY do + xCounter = xCounter + guiObjects[pos].AbsoluteSize.X + --previous pos was the end of a row + if xCounter >= totalPixelsX then + pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY + currentRowY = 0 + xCounter = guiObjects[pos].AbsoluteSize.X + end + if guiObjects[pos].AbsoluteSize.Y > currentRowY then + currentRowY = guiObjects[pos].AbsoluteSize.Y + end + pos = pos + 1 + end + --Count wherever current row left off + pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY + currentRowY = 0 + + pos = scrollPosition - 1 + xCounter = 0 + + --objects with varying X,Y dimensions can rarely cause minor errors + --rechecking every new scrollPosition is necessary to avoid 100% of errors + + --count backwards from current scrollPosition to see if we can add more rows + while pixelsBelowScrollbar + currentRowY < totalPixelsY and pos >= 1 do + xCounter = xCounter + guiObjects[pos].AbsoluteSize.X + rowSizeCounter = rowSizeCounter + 1 + if xCounter >= totalPixelsX then + rowSize = rowSizeCounter - 1 + rowSizeCounter = 0 + xCounter = guiObjects[pos].AbsoluteSize.X + if pixelsBelowScrollbar + currentRowY <= totalPixelsY then + --It fits, so back up our scroll position + pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY + if scrollPosition <= rowSize then + scrollPosition = 1 + break + else + scrollPosition = scrollPosition - rowSize + end + currentRowY = 0 + else + break + end + end + + if guiObjects[pos].AbsoluteSize.Y > currentRowY then + currentRowY = guiObjects[pos].AbsoluteSize.Y + end + + pos = pos - 1 + end + + --Do check last time if pos = 0 + if (pos == 0) and (pixelsBelowScrollbar + currentRowY <= totalPixelsY) then + scrollPosition = 1 + end + + xCounter = 0 + --pos = scrollPosition + rowSizeCounter = 0 + setRowSize = true + local lastChildSize = 0 + + local xOffset,yOffset = 0 + if guiObjects[1] then + yOffset = math.ceil(math.floor(math.fmod(totalPixelsY,guiObjects[1].AbsoluteSize.X))/2) + xOffset = math.ceil(math.floor(math.fmod(totalPixelsX,guiObjects[1].AbsoluteSize.Y))/2) + end + + for i, child in ipairs(guiObjects) do + if i < scrollPosition then + --print("Hiding " .. child.Name) + child.Visible = false + else + if pixelsRemainingY < 0 then + --print("Out of Space " .. child.Name) + child.Visible = false + else + --print("Laying out " .. child.Name) + --GuiObject + if setRowSize then rowSizeCounter = rowSizeCounter + 1 end + if xCounter + child.AbsoluteSize.X >= totalPixelsX then + if setRowSize then + rowSize = rowSizeCounter - 1 + setRowSize = false + end + xCounter = 0 + pixelsRemainingY = pixelsRemainingY - child.AbsoluteSize.Y + end + child.Position = UDim2.new(child.Position.X.Scale,xCounter + xOffset, 0, totalPixelsY - pixelsRemainingY + yOffset) + xCounter = xCounter + child.AbsoluteSize.X + child.Visible = ((pixelsRemainingY - child.AbsoluteSize.Y) >= 0) + if child.Visible then + howManyDisplayed = howManyDisplayed + 1 + end + lastChildSize = child.AbsoluteSize + end + end + end + + scrollUpButton.Active = (scrollPosition > 1) + if lastChildSize == 0 then + scrollDownButton.Active = false + else + scrollDownButton.Active = ((pixelsRemainingY - lastChildSize.Y) < 0) + end + scrollDrag.Active = #guiObjects > howManyDisplayed + scrollDrag.Visible = scrollDrag.Active + end + + + + local layoutSimpleScrollBar = function() + local guiObjects = {} + howManyDisplayed = 0 + + if orderList then + for i, child in ipairs(orderList) do + if child.Parent == frame then + table.insert(guiObjects, child) + end + end + else + local children = frame:GetChildren() + if children then + for i, child in ipairs(children) do + if child:IsA("GuiObject") then + table.insert(guiObjects, child) + end + end + end + end + if #guiObjects == 0 then + scrollUpButton.Active = false + scrollDownButton.Active = false + scrollDrag.Active = false + scrollPosition = 1 + return + end + + if scrollPosition > #guiObjects then + scrollPosition = #guiObjects + end + + local totalPixels = frame.AbsoluteSize.Y + local pixelsRemaining = frame.AbsoluteSize.Y + + local pixelsBelowScrollbar = 0 + local pos = #guiObjects + while pixelsBelowScrollbar < totalPixels and pos >= 1 do + if pos >= scrollPosition then + pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y + else + if pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y <= totalPixels then + --It fits, so back up our scroll position + pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y + if scrollPosition <= 1 then + scrollPosition = 1 + break + else + --local ("Backing up ScrollPosition from -- " ..scrollPosition) + scrollPosition = scrollPosition - 1 + end + else + break + end + end + pos = pos - 1 + end + + pos = scrollPosition + for i, child in ipairs(guiObjects) do + if i < scrollPosition then + --print("Hiding " .. child.Name) + child.Visible = false + else + if pixelsRemaining < 0 then + --print("Out of Space " .. child.Name) + child.Visible = false + else + --print("Laying out " .. child.Name) + --GuiObject + child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining) + pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y + if (pixelsRemaining >= 0) then + child.Visible = true + howManyDisplayed = howManyDisplayed + 1 + else + child.Visible = false + end + end + end + end + scrollUpButton.Active = (scrollPosition > 1) + scrollDownButton.Active = (pixelsRemaining < 0) + scrollDrag.Active = #guiObjects > howManyDisplayed + scrollDrag.Visible = scrollDrag.Active + end + + + local moveDragger = function() + local guiObjects = 0 + local children = frame:GetChildren() + if children then + for i, child in ipairs(children) do + if child:IsA("GuiObject") then + guiObjects = guiObjects + 1 + end + end + end + + if not scrollDrag.Parent then return end + + local dragSizeY = scrollDrag.Parent.AbsoluteSize.y * (1/(guiObjects - howManyDisplayed + 1)) + if dragSizeY < 16 then dragSizeY = 16 end + scrollDrag.Size = UDim2.new(scrollDrag.Size.X.Scale,scrollDrag.Size.X.Offset,scrollDrag.Size.Y.Scale,dragSizeY) + + local relativeYPos = (scrollPosition - 1)/(guiObjects - (howManyDisplayed)) + if relativeYPos > 1 then relativeYPos = 1 + elseif relativeYPos < 0 then relativeYPos = 0 end + local absYPos = 0 + + if relativeYPos ~= 0 then + absYPos = (relativeYPos * scrollbar.AbsoluteSize.y) - (relativeYPos * scrollDrag.AbsoluteSize.y) + end + + scrollDrag.Position = UDim2.new(scrollDrag.Position.X.Scale,scrollDrag.Position.X.Offset,scrollDrag.Position.Y.Scale,absYPos) + end + + local reentrancyGuard = false + local recalculate = function() + if reentrancyGuard then + return + end + reentrancyGuard = true + wait() + local success, err = nil + if style == "grid" then + success, err = pcall(function() layoutGridScrollBar() end) + elseif style == "simple" then + success, err = pcall(function() layoutSimpleScrollBar() end) + end + if not success then print(err) end + moveDragger() + reentrancyGuard = false + end + + local doScrollUp = function() + scrollPosition = (scrollPosition) - rowSize + if scrollPosition < 1 then scrollPosition = 1 end + recalculate(nil) + end + + local doScrollDown = function() + scrollPosition = (scrollPosition) + rowSize + recalculate(nil) + end + + local scrollUp = function(mouseYPos) + if scrollUpButton.Active then + scrollStamp = tick() + local current = scrollStamp + local upCon + upCon = mouseDrag.MouseButton1Up:connect(function() + scrollStamp = tick() + mouseDrag.Parent = nil + upCon:disconnect() + end) + mouseDrag.Parent = getScreenGuiAncestor(scrollbar) + doScrollUp() + wait(0.2) + local t = tick() + local w = 0.1 + while scrollStamp == current do + doScrollUp() + if mouseYPos and mouseYPos > scrollDrag.AbsolutePosition.y then + break + end + if not scrollUpButton.Active then break end + if tick()-t > 5 then + w = 0 + elseif tick()-t > 2 then + w = 0.06 + end + wait(w) + end + end + end + + local scrollDown = function(mouseYPos) + if scrollDownButton.Active then + scrollStamp = tick() + local current = scrollStamp + local downCon + downCon = mouseDrag.MouseButton1Up:connect(function() + scrollStamp = tick() + mouseDrag.Parent = nil + downCon:disconnect() + end) + mouseDrag.Parent = getScreenGuiAncestor(scrollbar) + doScrollDown() + wait(0.2) + local t = tick() + local w = 0.1 + while scrollStamp == current do + doScrollDown() + if mouseYPos and mouseYPos < (scrollDrag.AbsolutePosition.y + scrollDrag.AbsoluteSize.x) then + break + end + if not scrollDownButton.Active then break end + if tick()-t > 5 then + w = 0 + elseif tick()-t > 2 then + w = 0.06 + end + wait(w) + end + end + end + + local y = 0 + scrollDrag.MouseButton1Down:connect(function(x,y) + if scrollDrag.Active then + scrollStamp = tick() + local mouseOffset = y - scrollDrag.AbsolutePosition.y + local dragCon + local upCon + dragCon = mouseDrag.MouseMoved:connect(function(x,y) + local barAbsPos = scrollbar.AbsolutePosition.y + local barAbsSize = scrollbar.AbsoluteSize.y + + local dragAbsSize = scrollDrag.AbsoluteSize.y + local barAbsOne = barAbsPos + barAbsSize - dragAbsSize + y = y - mouseOffset + y = y < barAbsPos and barAbsPos or y > barAbsOne and barAbsOne or y + y = y - barAbsPos + + local guiObjects = 0 + local children = frame:GetChildren() + if children then + for i, child in ipairs(children) do + if child:IsA("GuiObject") then + guiObjects = guiObjects + 1 + end + end + end + + local doublePercent = y/(barAbsSize-dragAbsSize) + local rowDiff = rowSize + local totalScrollCount = guiObjects - (howManyDisplayed - 1) + local newScrollPosition = math.floor((doublePercent * totalScrollCount) + 0.5) + rowDiff + if newScrollPosition < scrollPosition then + rowDiff = -rowDiff + end + + if newScrollPosition < 1 then + newScrollPosition = 1 + end + + scrollPosition = newScrollPosition + recalculate(nil) + end) + upCon = mouseDrag.MouseButton1Up:connect(function() + scrollStamp = tick() + mouseDrag.Parent = nil + dragCon:disconnect(); dragCon = nil + upCon:disconnect(); drag = nil + end) + mouseDrag.Parent = getScreenGuiAncestor(scrollbar) + end + end) + + local scrollMouseCount = 0 + + scrollUpButton.MouseButton1Down:connect( + function() + scrollUp() + end) + scrollUpButton.MouseButton1Up:connect(function() + scrollStamp = tick() + end) + + + scrollDownButton.MouseButton1Up:connect(function() + scrollStamp = tick() + end) + scrollDownButton.MouseButton1Down:connect( + function() + scrollDown() + end) + + scrollbar.MouseButton1Up:connect(function() + scrollStamp = tick() + end) + scrollbar.MouseButton1Down:connect( + function(x,y) + if y > (scrollDrag.AbsoluteSize.y + scrollDrag.AbsolutePosition.y) then + scrollDown(y) + elseif y < (scrollDrag.AbsolutePosition.y) then + scrollUp(y) + end + end) + + + frame.ChildAdded:connect(function() + recalculate(nil) + end) + + frame.ChildRemoved:connect(function() + recalculate(nil) + end) + + frame.Changed:connect( + function(prop) + if prop == "AbsoluteSize" then + --Wait a heartbeat for it to sync in + recalculate(nil) + end + end) + frame.AncestryChanged:connect(function() recalculate(nil) end) + + return frame, scrollUpButton, scrollDownButton, recalculate, scrollbar +end +local function binaryGrow(min, max, fits) + if min > max then + return min + end + local biggestLegal = min + + while min <= max do + local mid = min + math.floor((max - min) / 2) + if fits(mid) and (biggestLegal == nil or biggestLegal < mid) then + biggestLegal = mid + + --Try growing + min = mid + 1 + else + --Doesn't fit, shrink + max = mid - 1 + end + end + return biggestLegal +end + + +local function binaryShrink(min, max, fits) + if min > max then + return min + end + local smallestLegal = max + + while min <= max do + local mid = min + math.floor((max - min) / 2) + if fits(mid) and (smallestLegal == nil or smallestLegal > mid) then + smallestLegal = mid + + --It fits, shrink + max = mid - 1 + else + --Doesn't fit, grow + min = mid + 1 + end + end + return smallestLegal +end + + +local function getGuiOwner(instance) + while instance ~= nil do + if instance:IsA("ScreenGui") or instance:IsA("BillboardGui") then + return instance + end + instance = instance.Parent + end + return nil +end + +t.AutoTruncateTextObject = function(textLabel) + local text = textLabel.Text + + local fullLabel = textLabel:Clone() + fullLabel.Name = "Full" .. textLabel.Name + fullLabel.BorderSizePixel = 0 + fullLabel.BackgroundTransparency = 0 + fullLabel.Text = text + fullLabel.TextXAlignment = Enum.TextXAlignment.Center + fullLabel.Position = UDim2.new(0,-3,0,0) + fullLabel.Size = UDim2.new(0,100,1,0) + fullLabel.Visible = false + fullLabel.Parent = textLabel + + local shortText = nil + local mouseEnterConnection = nil + local mouseLeaveConnection= nil + + local checkForResize = function() + if getGuiOwner(textLabel) == nil then + return + end + textLabel.Text = text + if textLabel.TextFits then + --Tear down the rollover if it is active + if mouseEnterConnection then + mouseEnterConnection:disconnect() + mouseEnterConnection = nil + end + if mouseLeaveConnection then + mouseLeaveConnection:disconnect() + mouseLeaveConnection = nil + end + else + local len = string.len(text) + textLabel.Text = text .. "~" + + --Shrink the text + local textSize = binaryGrow(0, len, + function(pos) + if pos == 0 then + textLabel.Text = "~" + else + textLabel.Text = string.sub(text, 1, pos) .. "~" + end + return textLabel.TextFits + end) + shortText = string.sub(text, 1, textSize) .. "~" + textLabel.Text = shortText + + --Make sure the fullLabel fits + if not fullLabel.TextFits then + --Already too small, grow it really bit to start + fullLabel.Size = UDim2.new(0, 10000, 1, 0) + end + + --Okay, now try to binary shrink it back down + local fullLabelSize = binaryShrink(textLabel.AbsoluteSize.X,fullLabel.AbsoluteSize.X, + function(size) + fullLabel.Size = UDim2.new(0, size, 1, 0) + return fullLabel.TextFits + end) + fullLabel.Size = UDim2.new(0,fullLabelSize+6,1,0) + + --Now setup the rollover effects, if they are currently off + if mouseEnterConnection == nil then + mouseEnterConnection = textLabel.MouseEnter:connect( + function() + fullLabel.ZIndex = textLabel.ZIndex + 1 + fullLabel.Visible = true + --textLabel.Text = "" + end) + end + if mouseLeaveConnection == nil then + mouseLeaveConnection = textLabel.MouseLeave:connect( + function() + fullLabel.Visible = false + --textLabel.Text = shortText + end) + end + end + end + textLabel.AncestryChanged:connect(checkForResize) + textLabel.Changed:connect( + function(prop) + if prop == "AbsoluteSize" then + checkForResize() + end + end) + + checkForResize() + + local function changeText(newText) + text = newText + fullLabel.Text = text + checkForResize() + end + + return textLabel, changeText +end + +local function TransitionTutorialPages(fromPage, toPage, transitionFrame, currentPageValue) + if fromPage then + fromPage.Visible = false + if transitionFrame.Visible == false then + transitionFrame.Size = fromPage.Size + transitionFrame.Position = fromPage.Position + end + else + if transitionFrame.Visible == false then + transitionFrame.Size = UDim2.new(0.0,50,0.0,50) + transitionFrame.Position = UDim2.new(0.5,-25,0.5,-25) + end + end + transitionFrame.Visible = true + currentPageValue.Value = nil + + local newsize, newPosition + if toPage then + --Make it visible so it resizes + toPage.Visible = true + + newSize = toPage.Size + newPosition = toPage.Position + + toPage.Visible = false + else + newSize = UDim2.new(0.0,50,0.0,50) + newPosition = UDim2.new(0.5,-25,0.5,-25) + end + transitionFrame:TweenSizeAndPosition(newSize, newPosition, Enum.EasingDirection.InOut, Enum.EasingStyle.Quad, 0.3, true, + function(state) + if state == Enum.TweenStatus.Completed then + transitionFrame.Visible = false + if toPage then + toPage.Visible = true + currentPageValue.Value = toPage + end + end + end) +end + +t.CreateTutorial = function(name, tutorialKey, createButtons) + local frame = Instance.new("Frame") + frame.Name = "Tutorial-" .. name + frame.BackgroundTransparency = 1 + frame.Size = UDim2.new(0.6, 0, 0.6, 0) + frame.Position = UDim2.new(0.2, 0, 0.2, 0) + + local transitionFrame = Instance.new("Frame") + transitionFrame.Name = "TransitionFrame" + transitionFrame.Style = Enum.FrameStyle.RobloxRound + transitionFrame.Size = UDim2.new(0.6, 0, 0.6, 0) + transitionFrame.Position = UDim2.new(0.2, 0, 0.2, 0) + transitionFrame.Visible = false + transitionFrame.Parent = frame + + local currentPageValue = Instance.new("ObjectValue") + currentPageValue.Name = "CurrentTutorialPage" + currentPageValue.Value = nil + currentPageValue.Parent = frame + + local boolValue = Instance.new("BoolValue") + boolValue.Name = "Buttons" + boolValue.Value = createButtons + boolValue.Parent = frame + + local pages = Instance.new("Frame") + pages.Name = "Pages" + pages.BackgroundTransparency = 1 + pages.Size = UDim2.new(1,0,1,0) + pages.Parent = frame + + local function getVisiblePageAndHideOthers() + local visiblePage = nil + local children = pages:GetChildren() + if children then + for i,child in ipairs(children) do + if child.Visible then + if visiblePage then + child.Visible = false + else + visiblePage = child + end + end + end + end + return visiblePage + end + + local showTutorial = function(alwaysShow) + if alwaysShow or UserSettings().GameSettings:GetTutorialState(tutorialKey) == false then + print("Showing tutorial-",tutorialKey) + local currentTutorialPage = getVisiblePageAndHideOthers() + + local firstPage = pages:FindFirstChild("TutorialPage1") + if firstPage then + TransitionTutorialPages(currentTutorialPage, firstPage, transitionFrame, currentPageValue) + else + error("Could not find TutorialPage1") + end + end + end + + local dismissTutorial = function() + local currentTutorialPage = getVisiblePageAndHideOthers() + + if currentTutorialPage then + TransitionTutorialPages(currentTutorialPage, nil, transitionFrame, currentPageValue) + end + + UserSettings().GameSettings:SetTutorialState(tutorialKey, true) + end + + local gotoPage = function(pageNum) + local page = pages:FindFirstChild("TutorialPage" .. pageNum) + local currentTutorialPage = getVisiblePageAndHideOthers() + TransitionTutorialPages(currentTutorialPage, page, transitionFrame, currentPageValue) + end + + return frame, showTutorial, dismissTutorial, gotoPage +end + +local function CreateBasicTutorialPage(name, handleResize, skipTutorial, giveDoneButton) + local frame = Instance.new("Frame") + frame.Name = "TutorialPage" + frame.Style = Enum.FrameStyle.RobloxRound + frame.Size = UDim2.new(0.6, 0, 0.6, 0) + frame.Position = UDim2.new(0.2, 0, 0.2, 0) + frame.Visible = false + + local frameHeader = Instance.new("TextLabel") + frameHeader.Name = "Header" + frameHeader.Text = name + frameHeader.BackgroundTransparency = 1 + frameHeader.FontSize = Enum.FontSize.Size24 + frameHeader.Font = Enum.Font.ArialBold + frameHeader.TextColor3 = Color3.new(1,1,1) + frameHeader.TextXAlignment = Enum.TextXAlignment.Center + frameHeader.TextWrap = true + frameHeader.Size = UDim2.new(1,-55, 0, 22) + frameHeader.Position = UDim2.new(0,0,0,0) + frameHeader.Parent = frame + + local skipButton = Instance.new("ImageButton") + skipButton.Name = "SkipButton" + skipButton.AutoButtonColor = false + skipButton.BackgroundTransparency = 1 + skipButton.Image = "rbxasset://textures/ui/closeButton.png" + skipButton.MouseButton1Click:connect(function() + skipTutorial() + end) + skipButton.MouseEnter:connect(function() + skipButton.Image = "rbxasset://textures/ui/closeButton_dn.png" + end) + skipButton.MouseLeave:connect(function() + skipButton.Image = "rbxasset://textures/ui/closeButton.png" + end) + skipButton.Size = UDim2.new(0, 25, 0, 25) + skipButton.Position = UDim2.new(1, -25, 0, 0) + skipButton.Parent = frame + + + if giveDoneButton then + local doneButton = Instance.new("TextButton") + doneButton.Name = "DoneButton" + doneButton.Style = Enum.ButtonStyle.RobloxButtonDefault + doneButton.Text = "Done" + doneButton.TextColor3 = Color3.new(1,1,1) + doneButton.Font = Enum.Font.ArialBold + doneButton.FontSize = Enum.FontSize.Size18 + doneButton.Size = UDim2.new(0,100,0,50) + doneButton.Position = UDim2.new(0.5,-50,1,-50) + + if skipTutorial then + doneButton.MouseButton1Click:connect(function() skipTutorial() end) + end + + doneButton.Parent = frame + end + + local innerFrame = Instance.new("Frame") + innerFrame.Name = "ContentFrame" + innerFrame.BackgroundTransparency = 1 + innerFrame.Position = UDim2.new(0,0,0,25) + innerFrame.Parent = frame + + local nextButton = Instance.new("TextButton") + nextButton.Name = "NextButton" + nextButton.Text = "Next" + nextButton.TextColor3 = Color3.new(1,1,1) + nextButton.Font = Enum.Font.Arial + nextButton.FontSize = Enum.FontSize.Size18 + nextButton.Style = Enum.ButtonStyle.RobloxButtonDefault + nextButton.Size = UDim2.new(0,80, 0, 32) + nextButton.Position = UDim2.new(0.5, 5, 1, -32) + nextButton.Active = false + nextButton.Visible = false + nextButton.Parent = frame + + local prevButton = Instance.new("TextButton") + prevButton.Name = "PrevButton" + prevButton.Text = "Previous" + prevButton.TextColor3 = Color3.new(1,1,1) + prevButton.Font = Enum.Font.Arial + prevButton.FontSize = Enum.FontSize.Size18 + prevButton.Style = Enum.ButtonStyle.RobloxButton + prevButton.Size = UDim2.new(0,80, 0, 32) + prevButton.Position = UDim2.new(0.5, -85, 1, -32) + prevButton.Active = false + prevButton.Visible = false + prevButton.Parent = frame + + if giveDoneButton then + innerFrame.Size = UDim2.new(1,0,1,-75) + else + innerFrame.Size = UDim2.new(1,0,1,-22) + end + + local parentConnection = nil + + local function basicHandleResize() + if frame.Visible and frame.Parent then + local maxSize = math.min(frame.Parent.AbsoluteSize.X, frame.Parent.AbsoluteSize.Y) + handleResize(200,maxSize) + end + end + + frame.Changed:connect( + function(prop) + if prop == "Parent" then + if parentConnection ~= nil then + parentConnection:disconnect() + parentConnection = nil + end + if frame.Parent and frame.Parent:IsA("GuiObject") then + parentConnection = frame.Parent.Changed:connect( + function(parentProp) + if parentProp == "AbsoluteSize" then + wait() + basicHandleResize() + end + end) + basicHandleResize() + end + end + + if prop == "Visible" then + basicHandleResize() + end + end) + + return frame, innerFrame +end + +t.CreateTextTutorialPage = function(name, text, skipTutorialFunc) + local frame = nil + local contentFrame = nil + + local textLabel = Instance.new("TextLabel") + textLabel.BackgroundTransparency = 1 + textLabel.TextColor3 = Color3.new(1,1,1) + textLabel.Text = text + textLabel.TextWrap = true + textLabel.TextXAlignment = Enum.TextXAlignment.Left + textLabel.TextYAlignment = Enum.TextYAlignment.Center + textLabel.Font = Enum.Font.Arial + textLabel.FontSize = Enum.FontSize.Size14 + textLabel.Size = UDim2.new(1,0,1,0) + + local function handleResize(minSize, maxSize) + size = binaryShrink(minSize, maxSize, + function(size) + frame.Size = UDim2.new(0, size, 0, size) + return textLabel.TextFits + end) + frame.Size = UDim2.new(0, size, 0, size) + frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2) + end + + frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc) + textLabel.Parent = contentFrame + + return frame +end + +t.CreateImageTutorialPage = function(name, imageAsset, x, y, skipTutorialFunc, giveDoneButton) + local frame = nil + local contentFrame = nil + + local imageLabel = Instance.new("ImageLabel") + imageLabel.BackgroundTransparency = 1 + imageLabel.Image = imageAsset + imageLabel.Size = UDim2.new(0,x,0,y) + imageLabel.Position = UDim2.new(0.5,-x/2,0.5,-y/2) + + local function handleResize(minSize, maxSize) + size = binaryShrink(minSize, maxSize, + function(size) + return size >= x and size >= y + end) + if size >= x and size >= y then + imageLabel.Size = UDim2.new(0,x, 0,y) + imageLabel.Position = UDim2.new(0.5,-x/2, 0.5, -y/2) + else + if x > y then + --X is limiter, so + imageLabel.Size = UDim2.new(1,0,y/x,0) + imageLabel.Position = UDim2.new(0,0, 0.5 - (y/x)/2, 0) + else + --Y is limiter + imageLabel.Size = UDim2.new(x/y,0,1, 0) + imageLabel.Position = UDim2.new(0.5-(x/y)/2, 0, 0, 0) + end + end + size = size + 50 + frame.Size = UDim2.new(0, size, 0, size) + frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2) + end + + frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc, giveDoneButton) + imageLabel.Parent = contentFrame + + return frame +end + +t.AddTutorialPage = function(tutorial, tutorialPage) + local transitionFrame = tutorial.TransitionFrame + local currentPageValue = tutorial.CurrentTutorialPage + + if not tutorial.Buttons.Value then + tutorialPage.NextButton.Parent = nil + tutorialPage.PrevButton.Parent = nil + end + + local children = tutorial.Pages:GetChildren() + if children and #children > 0 then + tutorialPage.Name = "TutorialPage" .. (#children+1) + local previousPage = children[#children] + if not previousPage:IsA("GuiObject") then + error("All elements under Pages must be GuiObjects") + end + + if tutorial.Buttons.Value then + if previousPage.NextButton.Active then + error("NextButton already Active on previousPage, please only add pages with RbxGui.AddTutorialPage function") + end + previousPage.NextButton.MouseButton1Click:connect( + function() + TransitionTutorialPages(previousPage, tutorialPage, transitionFrame, currentPageValue) + end) + previousPage.NextButton.Active = true + previousPage.NextButton.Visible = true + + if tutorialPage.PrevButton.Active then + error("PrevButton already Active on tutorialPage, please only add pages with RbxGui.AddTutorialPage function") + end + tutorialPage.PrevButton.MouseButton1Click:connect( + function() + TransitionTutorialPages(tutorialPage, previousPage, transitionFrame, currentPageValue) + end) + tutorialPage.PrevButton.Active = true + tutorialPage.PrevButton.Visible = true + end + + tutorialPage.Parent = tutorial.Pages + else + --First child + tutorialPage.Name = "TutorialPage1" + tutorialPage.Parent = tutorial.Pages + end +end + +t.CreateSetPanel = function(userIdsForSets, objectSelected, dialogClosed, size, position, showAdminCategories, useAssetVersionId) + + if not userIdsForSets then + error("CreateSetPanel: userIdsForSets (first arg) is nil, should be a table of number ids") + end + if type(userIdsForSets) ~= "table" and type(userIdsForSets) ~= "userdata" then + error("CreateSetPanel: userIdsForSets (first arg) is of type " ..type(userIdsForSets) .. ", should be of type table or userdata") + end + if not objectSelected then + error("CreateSetPanel: objectSelected (second arg) is nil, should be a callback function!") + end + if type(objectSelected) ~= "function" then + error("CreateSetPanel: objectSelected (second arg) is of type " .. type(objectSelected) .. ", should be of type function!") + end + if dialogClosed and type(dialogClosed) ~= "function" then + error("CreateSetPanel: dialogClosed (third arg) is of type " .. type(dialogClosed) .. ", should be of type function!") + end + + if showAdminCategories == nil then -- by default, don't show beta sets + showAdminCategories = false + end + + local arrayPosition = 1 + local insertButtons = {} + local insertButtonCons = {} + local contents = nil + local setGui = nil + + -- used for water selections + local waterForceDirection = "NegX" + local waterForce = "None" + local waterGui, waterTypeChangedEvent = nil + + local Data = {} + Data.CurrentCategory = nil + Data.Category = {} + local SetCache = {} + + local userCategoryButtons = nil + + local buttonWidth = 64 + local buttonHeight = buttonWidth + + local SmallThumbnailUrl = nil + local LargeThumbnailUrl = nil + local BaseUrl = game:GetService("ContentProvider").BaseUrl:lower() + + if useAssetVersionId then + LargeThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&assetversionid=" + SmallThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&assetversionid=" + else + LargeThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&aid=" + SmallThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&aid=" + end + + local function drillDownSetZIndex(parent, index) + local children = parent:GetChildren() + for i = 1, #children do + if children[i]:IsA("GuiObject") then + children[i].ZIndex = index + end + drillDownSetZIndex(children[i], index) + end + end + + -- for terrain stamping + local currTerrainDropDownFrame = nil + local terrainShapes = {"Block","Vertical Ramp","Corner Wedge","Inverse Corner Wedge","Horizontal Ramp","Auto-Wedge"} + local terrainShapeMap = {} + for i = 1, #terrainShapes do + terrainShapeMap[terrainShapes[i]] = i - 1 + end + terrainShapeMap[terrainShapes[#terrainShapes]] = 6 + + local function createWaterGui() + local waterForceDirections = {"NegX","X","NegY","Y","NegZ","Z"} + local waterForces = {"None", "Small", "Medium", "Strong", "Max"} + + local waterFrame = Instance.new("Frame") + waterFrame.Name = "WaterFrame" + waterFrame.Style = Enum.FrameStyle.RobloxSquare + waterFrame.Size = UDim2.new(0,150,0,110) + waterFrame.Visible = false + + local waterForceLabel = Instance.new("TextLabel") + waterForceLabel.Name = "WaterForceLabel" + waterForceLabel.BackgroundTransparency = 1 + waterForceLabel.Size = UDim2.new(1,0,0,12) + waterForceLabel.Font = Enum.Font.ArialBold + waterForceLabel.FontSize = Enum.FontSize.Size12 + waterForceLabel.TextColor3 = Color3.new(1,1,1) + waterForceLabel.TextXAlignment = Enum.TextXAlignment.Left + waterForceLabel.Text = "Water Force" + waterForceLabel.Parent = waterFrame + + local waterForceDirLabel = waterForceLabel:Clone() + waterForceDirLabel.Name = "WaterForceDirectionLabel" + waterForceDirLabel.Text = "Water Force Direction" + waterForceDirLabel.Position = UDim2.new(0,0,0,50) + waterForceDirLabel.Parent = waterFrame + + local waterTypeChangedEvent = Instance.new("BindableEvent",waterFrame) + waterTypeChangedEvent.Name = "WaterTypeChangedEvent" + + local waterForceDirectionSelectedFunc = function(newForceDirection) + waterForceDirection = newForceDirection + waterTypeChangedEvent:Fire({waterForce, waterForceDirection}) + end + local waterForceSelectedFunc = function(newForce) + waterForce = newForce + waterTypeChangedEvent:Fire({waterForce, waterForceDirection}) + end + + local waterForceDirectionDropDown, forceWaterDirectionSelection = t.CreateDropDownMenu(waterForceDirections, waterForceDirectionSelectedFunc) + waterForceDirectionDropDown.Size = UDim2.new(1,0,0,25) + waterForceDirectionDropDown.Position = UDim2.new(0,0,1,3) + forceWaterDirectionSelection("NegX") + waterForceDirectionDropDown.Parent = waterForceDirLabel + + local waterForceDropDown, forceWaterForceSelection = t.CreateDropDownMenu(waterForces, waterForceSelectedFunc) + forceWaterForceSelection("None") + waterForceDropDown.Size = UDim2.new(1,0,0,25) + waterForceDropDown.Position = UDim2.new(0,0,1,3) + waterForceDropDown.Parent = waterForceLabel + + return waterFrame, waterTypeChangedEvent + end + + -- Helper Function that contructs gui elements + local function createSetGui() + + local setGui = Instance.new("ScreenGui") + setGui.Name = "SetGui" + + local setPanel = Instance.new("Frame") + setPanel.Name = "SetPanel" + setPanel.Active = true + setPanel.BackgroundTransparency = 1 + if position then + setPanel.Position = position + else + setPanel.Position = UDim2.new(0.2, 29, 0.1, 24) + end + if size then + setPanel.Size = size + else + setPanel.Size = UDim2.new(0.6, -58, 0.64, 0) + end + setPanel.Style = Enum.FrameStyle.RobloxRound + setPanel.ZIndex = 6 + setPanel.Parent = setGui + + -- Children of SetPanel + local itemPreview = Instance.new("Frame") + itemPreview.Name = "ItemPreview" + itemPreview.BackgroundTransparency = 1 + itemPreview.Position = UDim2.new(0.8,5,0.085,0) + itemPreview.Size = UDim2.new(0.21,0,0.9,0) + itemPreview.ZIndex = 6 + itemPreview.Parent = setPanel + + -- Children of ItemPreview + local textPanel = Instance.new("Frame") + textPanel.Name = "TextPanel" + textPanel.BackgroundTransparency = 1 + textPanel.Position = UDim2.new(0,0,0.45,0) + textPanel.Size = UDim2.new(1,0,0.55,0) + textPanel.ZIndex = 6 + textPanel.Parent = itemPreview + + -- Children of TextPanel + local rolloverText = Instance.new("TextLabel") + rolloverText.Name = "RolloverText" + rolloverText.BackgroundTransparency = 1 + rolloverText.Size = UDim2.new(1,0,0,48) + rolloverText.ZIndex = 6 + rolloverText.Font = Enum.Font.ArialBold + rolloverText.FontSize = Enum.FontSize.Size24 + rolloverText.Text = "" + rolloverText.TextColor3 = Color3.new(1,1,1) + rolloverText.TextWrap = true + rolloverText.TextXAlignment = Enum.TextXAlignment.Left + rolloverText.TextYAlignment = Enum.TextYAlignment.Top + rolloverText.Parent = textPanel + + local largePreview = Instance.new("ImageLabel") + largePreview.Name = "LargePreview" + largePreview.BackgroundTransparency = 1 + largePreview.Image = "" + largePreview.Size = UDim2.new(1,0,0,170) + largePreview.ZIndex = 6 + largePreview.Parent = itemPreview + + local sets = Instance.new("Frame") + sets.Name = "Sets" + sets.BackgroundTransparency = 1 + sets.Position = UDim2.new(0,0,0,5) + sets.Size = UDim2.new(0.23,0,1,-5) + sets.ZIndex = 6 + sets.Parent = setPanel + + -- Children of Sets + local line = Instance.new("Frame") + line.Name = "Line" + line.BackgroundColor3 = Color3.new(1,1,1) + line.BackgroundTransparency = 0.7 + line.BorderSizePixel = 0 + line.Position = UDim2.new(1,-3,0.06,0) + line.Size = UDim2.new(0,3,0.9,0) + line.ZIndex = 6 + line.Parent = sets + + local setsLists, controlFrame = t.CreateTrueScrollingFrame() + setsLists.Size = UDim2.new(1,-6,0.94,0) + setsLists.Position = UDim2.new(0,0,0.06,0) + setsLists.BackgroundTransparency = 1 + setsLists.Name = "SetsLists" + setsLists.ZIndex = 6 + setsLists.Parent = sets + drillDownSetZIndex(controlFrame, 7) + + local setsHeader = Instance.new("TextLabel") + setsHeader.Name = "SetsHeader" + setsHeader.BackgroundTransparency = 1 + setsHeader.Size = UDim2.new(0,47,0,24) + setsHeader.ZIndex = 6 + setsHeader.Font = Enum.Font.ArialBold + setsHeader.FontSize = Enum.FontSize.Size24 + setsHeader.Text = "Sets" + setsHeader.TextColor3 = Color3.new(1,1,1) + setsHeader.TextXAlignment = Enum.TextXAlignment.Left + setsHeader.TextYAlignment = Enum.TextYAlignment.Top + setsHeader.Parent = sets + + local cancelButton = Instance.new("TextButton") + cancelButton.Name = "CancelButton" + cancelButton.Position = UDim2.new(1,-32,0,-2) + cancelButton.Size = UDim2.new(0,34,0,34) + cancelButton.Style = Enum.ButtonStyle.RobloxButtonDefault + cancelButton.ZIndex = 6 + cancelButton.Text = "" + cancelButton.Modal = true + cancelButton.Parent = setPanel + + -- Children of Cancel Button + local cancelImage = Instance.new("ImageLabel") + cancelImage.Name = "CancelImage" + cancelImage.BackgroundTransparency = 1 + cancelImage.Image = "http://www.roblox.com/asset/?id=54135717" + cancelImage.Position = UDim2.new(0,-2,0,-2) + cancelImage.Size = UDim2.new(0,16,0,16) + cancelImage.ZIndex = 6 + cancelImage.Parent = cancelButton + + return setGui + end + + local function createSetButton(text) + local setButton = Instance.new("TextButton") + + if text then setButton.Text = text + else setButton.Text = "" end + + setButton.AutoButtonColor = false + setButton.BackgroundTransparency = 1 + setButton.BackgroundColor3 = Color3.new(1,1,1) + setButton.BorderSizePixel = 0 + setButton.Size = UDim2.new(1,-5,0,18) + setButton.ZIndex = 6 + setButton.Visible = false + setButton.Font = Enum.Font.Arial + setButton.FontSize = Enum.FontSize.Size18 + setButton.TextColor3 = Color3.new(1,1,1) + setButton.TextXAlignment = Enum.TextXAlignment.Left + + return setButton + end + + local function buildSetButton(name, setId, setImageId, i, count) + local button = createSetButton(name) + button.Text = name + button.Name = "SetButton" + button.Visible = true + + local setValue = Instance.new("IntValue") + setValue.Name = "SetId" + setValue.Value = setId + setValue.Parent = button + + local setName = Instance.new("StringValue") + setName.Name = "SetName" + setName.Value = name + setName.Parent = button + + return button + end + + local function processCategory(sets) + local setButtons = {} + local numSkipped = 0 + for i = 1, #sets do + if not showAdminCategories and sets[i].Name == "Beta" then + numSkipped = numSkipped + 1 + else + setButtons[i - numSkipped] = buildSetButton(sets[i].Name, sets[i].CategoryId, sets[i].ImageAssetId, i - numSkipped, #sets) + end + end + return setButtons + end + + local function handleResize() + wait() -- neccessary to insure heartbeat happened + + local itemPreview = setGui.SetPanel.ItemPreview + + itemPreview.LargePreview.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.X) + itemPreview.LargePreview.Position = UDim2.new(0.5,-itemPreview.LargePreview.AbsoluteSize.X/2,0,0) + itemPreview.TextPanel.Position = UDim2.new(0,0,0,itemPreview.LargePreview.AbsoluteSize.Y) + itemPreview.TextPanel.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.Y - itemPreview.LargePreview.AbsoluteSize.Y) + end + + local function makeInsertAssetButton() + local insertAssetButtonExample = Instance.new("Frame") + insertAssetButtonExample.Name = "InsertAssetButtonExample" + insertAssetButtonExample.Position = UDim2.new(0,128,0,64) + insertAssetButtonExample.Size = UDim2.new(0,64,0,64) + insertAssetButtonExample.BackgroundTransparency = 1 + insertAssetButtonExample.ZIndex = 6 + insertAssetButtonExample.Visible = false + + local assetId = Instance.new("IntValue") + assetId.Name = "AssetId" + assetId.Value = 0 + assetId.Parent = insertAssetButtonExample + + local assetName = Instance.new("StringValue") + assetName.Name = "AssetName" + assetName.Value = "" + assetName.Parent = insertAssetButtonExample + + local button = Instance.new("TextButton") + button.Name = "Button" + button.Text = "" + button.Style = Enum.ButtonStyle.RobloxButton + button.Position = UDim2.new(0.025,0,0.025,0) + button.Size = UDim2.new(0.95,0,0.95,0) + button.ZIndex = 6 + button.Parent = insertAssetButtonExample + + local buttonImage = Instance.new("ImageLabel") + buttonImage.Name = "ButtonImage" + buttonImage.Image = "" + buttonImage.Position = UDim2.new(0,-7,0,-7) + buttonImage.Size = UDim2.new(1,14,1,14) + buttonImage.BackgroundTransparency = 1 + buttonImage.ZIndex = 7 + buttonImage.Parent = button + + local configIcon = buttonImage:clone() + configIcon.Name = "ConfigIcon" + configIcon.Visible = false + configIcon.Position = UDim2.new(1,-23,1,-24) + configIcon.Size = UDim2.new(0,16,0,16) + configIcon.Image = "" + configIcon.ZIndex = 6 + configIcon.Parent = insertAssetButtonExample + + return insertAssetButtonExample + end + + local function showLargePreview(insertButton) + if insertButton:FindFirstChild("AssetId") then + delay(0,function() + game:GetService("ContentProvider"):Preload(LargeThumbnailUrl .. tostring(insertButton.AssetId.Value)) + setGui.SetPanel.ItemPreview.LargePreview.Image = LargeThumbnailUrl .. tostring(insertButton.AssetId.Value) + end) + end + if insertButton:FindFirstChild("AssetName") then + setGui.SetPanel.ItemPreview.TextPanel.RolloverText.Text = insertButton.AssetName.Value + end + end + + local function selectTerrainShape(shape) + if currTerrainDropDownFrame then + objectSelected(tostring(currTerrainDropDownFrame.AssetName.Value), tonumber(currTerrainDropDownFrame.AssetId.Value), shape) + end + end + + local function createTerrainTypeButton(name, parent) + local dropDownTextButton = Instance.new("TextButton") + dropDownTextButton.Name = name .. "Button" + dropDownTextButton.Font = Enum.Font.ArialBold + dropDownTextButton.FontSize = Enum.FontSize.Size14 + dropDownTextButton.BorderSizePixel = 0 + dropDownTextButton.TextColor3 = Color3.new(1,1,1) + dropDownTextButton.Text = name + dropDownTextButton.TextXAlignment = Enum.TextXAlignment.Left + dropDownTextButton.BackgroundTransparency = 1 + dropDownTextButton.ZIndex = parent.ZIndex + 1 + dropDownTextButton.Size = UDim2.new(0,parent.Size.X.Offset - 2,0,16) + dropDownTextButton.Position = UDim2.new(0,1,0,0) + + dropDownTextButton.MouseEnter:connect(function() + dropDownTextButton.BackgroundTransparency = 0 + dropDownTextButton.TextColor3 = Color3.new(0,0,0) + end) + + dropDownTextButton.MouseLeave:connect(function() + dropDownTextButton.BackgroundTransparency = 1 + dropDownTextButton.TextColor3 = Color3.new(1,1,1) + end) + + dropDownTextButton.MouseButton1Click:connect(function() + dropDownTextButton.BackgroundTransparency = 1 + dropDownTextButton.TextColor3 = Color3.new(1,1,1) + if dropDownTextButton.Parent and dropDownTextButton.Parent:IsA("GuiObject") then + dropDownTextButton.Parent.Visible = false + end + selectTerrainShape(terrainShapeMap[dropDownTextButton.Text]) + end) + + return dropDownTextButton + end + + local function createTerrainDropDownMenu(zIndex) + local dropDown = Instance.new("Frame") + dropDown.Name = "TerrainDropDown" + dropDown.BackgroundColor3 = Color3.new(0,0,0) + dropDown.BorderColor3 = Color3.new(1,0,0) + dropDown.Size = UDim2.new(0,200,0,0) + dropDown.Visible = false + dropDown.ZIndex = zIndex + dropDown.Parent = setGui + + for i = 1, #terrainShapes do + local shapeButton = createTerrainTypeButton(terrainShapes[i],dropDown) + shapeButton.Position = UDim2.new(0,1,0,(i - 1) * (shapeButton.Size.Y.Offset)) + shapeButton.Parent = dropDown + dropDown.Size = UDim2.new(0,200,0,dropDown.Size.Y.Offset + (shapeButton.Size.Y.Offset)) + end + + dropDown.MouseLeave:connect(function() + dropDown.Visible = false + end) + end + + + local function createDropDownMenuButton(parent) + local dropDownButton = Instance.new("ImageButton") + dropDownButton.Name = "DropDownButton" + dropDownButton.Image = "http://www.roblox.com/asset/?id=67581509" + dropDownButton.BackgroundTransparency = 1 + dropDownButton.Size = UDim2.new(0,16,0,16) + dropDownButton.Position = UDim2.new(1,-24,0,6) + dropDownButton.ZIndex = parent.ZIndex + 2 + dropDownButton.Parent = parent + + if not setGui:FindFirstChild("TerrainDropDown") then + createTerrainDropDownMenu(8) + end + + dropDownButton.MouseButton1Click:connect(function() + setGui.TerrainDropDown.Visible = true + setGui.TerrainDropDown.Position = UDim2.new(0,parent.AbsolutePosition.X,0,parent.AbsolutePosition.Y) + currTerrainDropDownFrame = parent + end) + end + + local function buildInsertButton() + local insertButton = makeInsertAssetButton() + insertButton.Name = "InsertAssetButton" + insertButton.Visible = true + + if Data.Category[Data.CurrentCategory].SetName == "High Scalability" then + createDropDownMenuButton(insertButton) + end + + local lastEnter = nil + local mouseEnterCon = insertButton.MouseEnter:connect(function() + lastEnter = insertButton + delay(0.1,function() + if lastEnter == insertButton then + showLargePreview(insertButton) + end + end) + end) + return insertButton, mouseEnterCon + end + + local function realignButtonGrid(columns) + local x = 0 + local y = 0 + for i = 1, #insertButtons do + insertButtons[i].Position = UDim2.new(0, buttonWidth * x, 0, buttonHeight * y) + x = x + 1 + if x >= columns then + x = 0 + y = y + 1 + end + end + end + + local function setInsertButtonImageBehavior(insertFrame, visible, name, assetId) + if visible then + insertFrame.AssetName.Value = name + insertFrame.AssetId.Value = assetId + local newImageUrl = SmallThumbnailUrl .. assetId + if newImageUrl ~= insertFrame.Button.ButtonImage.Image then + delay(0,function() + game:GetService("ContentProvider"):Preload(SmallThumbnailUrl .. assetId) + if insertFrame:findFirstChild("Button") then + insertFrame.Button.ButtonImage.Image = SmallThumbnailUrl .. assetId + end + end) + end + table.insert(insertButtonCons, + insertFrame.Button.MouseButton1Click:connect(function() + -- special case for water, show water selection gui + local isWaterSelected = (name == "Water") and (Data.Category[Data.CurrentCategory].SetName == "High Scalability") + waterGui.Visible = isWaterSelected + if isWaterSelected then + objectSelected(name, tonumber(assetId), nil) + else + objectSelected(name, tonumber(assetId)) + end + end) + ) + insertFrame.Visible = true + else + insertFrame.Visible = false + end + end + + local function loadSectionOfItems(setGui, rows, columns) + local pageSize = rows * columns + + if arrayPosition > #contents then return end + + local origArrayPos = arrayPosition + + local yCopy = 0 + for i = 1, pageSize + 1 do + if arrayPosition >= #contents + 1 then + break + end + + local buttonCon + insertButtons[arrayPosition], buttonCon = buildInsertButton() + table.insert(insertButtonCons,buttonCon) + insertButtons[arrayPosition].Parent = setGui.SetPanel.ItemsFrame + arrayPosition = arrayPosition + 1 + end + realignButtonGrid(columns) + + local indexCopy = origArrayPos + for index = origArrayPos, arrayPosition do + if insertButtons[index] then + if contents[index] then + + -- we don't want water to have a drop down button + if contents[index].Name == "Water" then + if Data.Category[Data.CurrentCategory].SetName == "High Scalability" then + insertButtons[index]:FindFirstChild("DropDownButton",true):Destroy() + end + end + + local assetId + if useAssetVersionId then + assetId = contents[index].AssetVersionId + else + assetId = contents[index].AssetId + end + setInsertButtonImageBehavior(insertButtons[index], true, contents[index].Name, assetId) + else + break + end + else + break + end + indexCopy = index + end + end + + local function setSetIndex() + Data.Category[Data.CurrentCategory].Index = 0 + + rows = 7 + columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth) + + contents = Data.Category[Data.CurrentCategory].Contents + if contents then + -- remove our buttons and their connections + for i = 1, #insertButtons do + insertButtons[i]:remove() + end + for i = 1, #insertButtonCons do + if insertButtonCons[i] then insertButtonCons[i]:disconnect() end + end + insertButtonCons = {} + insertButtons = {} + + arrayPosition = 1 + loadSectionOfItems(setGui, rows, columns) + end + end + + local function selectSet(button, setName, setId, setIndex) + if button and Data.Category[Data.CurrentCategory] ~= nil then + if button ~= Data.Category[Data.CurrentCategory].Button then + Data.Category[Data.CurrentCategory].Button = button + + if SetCache[setId] == nil then + SetCache[setId] = game:GetService("InsertService"):GetCollection(setId) + end + Data.Category[Data.CurrentCategory].Contents = SetCache[setId] + + Data.Category[Data.CurrentCategory].SetName = setName + Data.Category[Data.CurrentCategory].SetId = setId + end + setSetIndex() + end + end + + local function selectCategoryPage(buttons, page) + if buttons ~= Data.CurrentCategory then + if Data.CurrentCategory then + for key, button in pairs(Data.CurrentCategory) do + button.Visible = false + end + end + + Data.CurrentCategory = buttons + if Data.Category[Data.CurrentCategory] == nil then + Data.Category[Data.CurrentCategory] = {} + if #buttons > 0 then + selectSet(buttons[1], buttons[1].SetName.Value, buttons[1].SetId.Value, 0) + end + else + Data.Category[Data.CurrentCategory].Button = nil + selectSet(Data.Category[Data.CurrentCategory].ButtonFrame, Data.Category[Data.CurrentCategory].SetName, Data.Category[Data.CurrentCategory].SetId, Data.Category[Data.CurrentCategory].Index) + end + end + end + + local function selectCategory(category) + selectCategoryPage(category, 0) + end + + local function resetAllSetButtonSelection() + local setButtons = setGui.SetPanel.Sets.SetsLists:GetChildren() + for i = 1, #setButtons do + if setButtons[i]:IsA("TextButton") then + setButtons[i].Selected = false + setButtons[i].BackgroundTransparency = 1 + setButtons[i].TextColor3 = Color3.new(1,1,1) + setButtons[i].BackgroundColor3 = Color3.new(1,1,1) + end + end + end + + local function populateSetsFrame() + local currRow = 0 + for i = 1, #userCategoryButtons do + local button = userCategoryButtons[i] + button.Visible = true + button.Position = UDim2.new(0,5,0,currRow * button.Size.Y.Offset) + button.Parent = setGui.SetPanel.Sets.SetsLists + + if i == 1 then -- we will have this selected by default, so show it + button.Selected = true + button.BackgroundColor3 = Color3.new(0,204/255,0) + button.TextColor3 = Color3.new(0,0,0) + button.BackgroundTransparency = 0 + end + + button.MouseEnter:connect(function() + if not button.Selected then + button.BackgroundTransparency = 0 + button.TextColor3 = Color3.new(0,0,0) + end + end) + button.MouseLeave:connect(function() + if not button.Selected then + button.BackgroundTransparency = 1 + button.TextColor3 = Color3.new(1,1,1) + end + end) + button.MouseButton1Click:connect(function() + resetAllSetButtonSelection() + button.Selected = not button.Selected + button.BackgroundColor3 = Color3.new(0,204/255,0) + button.TextColor3 = Color3.new(0,0,0) + button.BackgroundTransparency = 0 + selectSet(button, button.Text, userCategoryButtons[i].SetId.Value, 0) + end) + + currRow = currRow + 1 + end + + local buttons = setGui.SetPanel.Sets.SetsLists:GetChildren() + + -- set first category as loaded for default + if buttons then + for i = 1, #buttons do + if buttons[i]:IsA("TextButton") then + selectSet(buttons[i], buttons[i].Text, userCategoryButtons[i].SetId.Value, 0) + selectCategory(userCategoryButtons) + break + end + end + end + end + + setGui = createSetGui() + waterGui, waterTypeChangedEvent = createWaterGui() + waterGui.Position = UDim2.new(0,55,0,0) + waterGui.Parent = setGui + setGui.Changed:connect(function(prop) -- this resizes the preview image to always be the right size + if prop == "AbsoluteSize" then + handleResize() + setSetIndex() + end + end) + + local scrollFrame, controlFrame = t.CreateTrueScrollingFrame() + scrollFrame.Size = UDim2.new(0.54,0,0.85,0) + scrollFrame.Position = UDim2.new(0.24,0,0.085,0) + scrollFrame.Name = "ItemsFrame" + scrollFrame.ZIndex = 6 + scrollFrame.Parent = setGui.SetPanel + scrollFrame.BackgroundTransparency = 1 + + drillDownSetZIndex(controlFrame,7) + + controlFrame.Parent = setGui.SetPanel + controlFrame.Position = UDim2.new(0.76, 5, 0, 0) + + local debounce = false + controlFrame.ScrollBottom.Changed:connect(function(prop) + if controlFrame.ScrollBottom.Value == true then + if debounce then return end + debounce = true + loadSectionOfItems(setGui, rows, columns) + debounce = false + end + end) + + local userData = {} + for id = 1, #userIdsForSets do + local newUserData = game:GetService("InsertService"):GetUserSets(userIdsForSets[id]) + if newUserData and #newUserData > 2 then + -- start at #3 to skip over My Decals and My Models for each account + for category = 3, #newUserData do + if newUserData[category].Name == "High Scalability" then -- we want high scalability parts to show first + table.insert(userData,1,newUserData[category]) + else + table.insert(userData, newUserData[category]) + end + end + end + + end + if userData then + userCategoryButtons = processCategory(userData) + end + + rows = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.Y/buttonHeight) + columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth) + + populateSetsFrame() + + insertPanelCloseCon = setGui.SetPanel.CancelButton.MouseButton1Click:connect(function() + setGui.SetPanel.Visible = false + if dialogClosed then dialogClosed() end + end) + + local setVisibilityFunction = function(visible) + if visible then + setGui.SetPanel.Visible = true + else + setGui.SetPanel.Visible = false + end + end + + local getVisibilityFunction = function() + if setGui then + if setGui:FindFirstChild("SetPanel") then + return setGui.SetPanel.Visible + end + end + + return false + end + + return setGui, setVisibilityFunction, getVisibilityFunction, waterTypeChangedEvent +end + +t.CreateTerrainMaterialSelector = function(size,position) + local terrainMaterialSelectionChanged = Instance.new("BindableEvent") + terrainMaterialSelectionChanged.Name = "TerrainMaterialSelectionChanged" + + local selectedButton = nil + + local frame = Instance.new("Frame") + frame.Name = "TerrainMaterialSelector" + if size then + frame.Size = size + else + frame.Size = UDim2.new(0, 245, 0, 230) + end + if position then + frame.Position = position + end + frame.BorderSizePixel = 0 + frame.BackgroundColor3 = Color3.new(0,0,0) + frame.Active = true + + terrainMaterialSelectionChanged.Parent = frame + + local waterEnabled = true -- todo: turn this on when water is ready + + local materialToImageMap = {} + local materialNames = {"Grass", "Sand", "Brick", "Granite", "Asphalt", "Iron", "Aluminum", "Gold", "Plank", "Log", "Gravel", "Cinder Block", "Stone Wall", "Concrete", "Plastic (red)", "Plastic (blue)"} + if waterEnabled then + table.insert(materialNames,"Water") + end + local currentMaterial = 1 + + function getEnumFromName(choice) + if choice == "Grass" then return 1 end + if choice == "Sand" then return 2 end + if choice == "Erase" then return 0 end + if choice == "Brick" then return 3 end + if choice == "Granite" then return 4 end + if choice == "Asphalt" then return 5 end + if choice == "Iron" then return 6 end + if choice == "Aluminum" then return 7 end + if choice == "Gold" then return 8 end + if choice == "Plank" then return 9 end + if choice == "Log" then return 10 end + if choice == "Gravel" then return 11 end + if choice == "Cinder Block" then return 12 end + if choice == "Stone Wall" then return 13 end + if choice == "Concrete" then return 14 end + if choice == "Plastic (red)" then return 15 end + if choice == "Plastic (blue)" then return 16 end + if choice == "Water" then return 17 end + end + + function getNameFromEnum(choice) + if choice == Enum.CellMaterial.Grass or choice == 1 then return "Grass"end + if choice == Enum.CellMaterial.Sand or choice == 2 then return "Sand" end + if choice == Enum.CellMaterial.Empty or choice == 0 then return "Erase" end + if choice == Enum.CellMaterial.Brick or choice == 3 then return "Brick" end + if choice == Enum.CellMaterial.Granite or choice == 4 then return "Granite" end + if choice == Enum.CellMaterial.Asphalt or choice == 5 then return "Asphalt" end + if choice == Enum.CellMaterial.Iron or choice == 6 then return "Iron" end + if choice == Enum.CellMaterial.Aluminum or choice == 7 then return "Aluminum" end + if choice == Enum.CellMaterial.Gold or choice == 8 then return "Gold" end + if choice == Enum.CellMaterial.WoodPlank or choice == 9 then return "Plank" end + if choice == Enum.CellMaterial.WoodLog or choice == 10 then return "Log" end + if choice == Enum.CellMaterial.Gravel or choice == 11 then return "Gravel" end + if choice == Enum.CellMaterial.CinderBlock or choice == 12 then return "Cinder Block" end + if choice == Enum.CellMaterial.MossyStone or choice == 13 then return "Stone Wall" end + if choice == Enum.CellMaterial.Cement or choice == 14 then return "Concrete" end + if choice == Enum.CellMaterial.RedPlastic or choice == 15 then return "Plastic (red)" end + if choice == Enum.CellMaterial.BluePlastic or choice == 16 then return "Plastic (blue)" end + + if waterEnabled then + if choice == Enum.CellMaterial.Water or choice == 17 then return "Water" end + end + end + + + local function updateMaterialChoice(choice) + currentMaterial = getEnumFromName(choice) + terrainMaterialSelectionChanged:Fire(currentMaterial) + end + + -- we so need a better way to do this + for i,v in pairs(materialNames) do + materialToImageMap[v] = {} + if v == "Grass" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=56563112" + elseif v == "Sand" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=62356652" + elseif v == "Brick" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=65961537" + elseif v == "Granite" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532153" + elseif v == "Asphalt" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532038" + elseif v == "Iron" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532093" + elseif v == "Aluminum" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531995" + elseif v == "Gold" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532118" + elseif v == "Plastic (red)" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531848" + elseif v == "Plastic (blue)" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531924" + elseif v == "Plank" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532015" + elseif v == "Log" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532051" + elseif v == "Gravel" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532206" + elseif v == "Cinder Block" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532103" + elseif v == "Stone Wall" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531804" + elseif v == "Concrete" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532059" + elseif v == "Water" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=81407474" + else materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=66887593" -- fill in the rest here!! + end + end + + local scrollFrame, scrollUp, scrollDown, recalculateScroll = t.CreateScrollingFrame(nil,"grid") + scrollFrame.Size = UDim2.new(0.85,0,1,0) + scrollFrame.Position = UDim2.new(0,0,0,0) + scrollFrame.Parent = frame + + scrollUp.Parent = frame + scrollUp.Visible = true + scrollUp.Position = UDim2.new(1,-19,0,0) + + scrollDown.Parent = frame + scrollDown.Visible = true + scrollDown.Position = UDim2.new(1,-19,1,-17) + + local function goToNewMaterial(buttonWrap, materialName) + updateMaterialChoice(materialName) + buttonWrap.BackgroundTransparency = 0 + selectedButton.BackgroundTransparency = 1 + selectedButton = buttonWrap + end + + local function createMaterialButton(name) + local buttonWrap = Instance.new("TextButton") + buttonWrap.Text = "" + buttonWrap.Size = UDim2.new(0,32,0,32) + buttonWrap.BackgroundColor3 = Color3.new(1,1,1) + buttonWrap.BorderSizePixel = 0 + buttonWrap.BackgroundTransparency = 1 + buttonWrap.AutoButtonColor = false + buttonWrap.Name = tostring(name) + + local imageButton = Instance.new("ImageButton") + imageButton.AutoButtonColor = false + imageButton.BackgroundTransparency = 1 + imageButton.Size = UDim2.new(0,30,0,30) + imageButton.Position = UDim2.new(0,1,0,1) + imageButton.Name = tostring(name) + imageButton.Parent = buttonWrap + imageButton.Image = materialToImageMap[name].Regular + + local enumType = Instance.new("NumberValue") + enumType.Name = "EnumType" + enumType.Parent = buttonWrap + enumType.Value = 0 + + imageButton.MouseEnter:connect(function() + buttonWrap.BackgroundTransparency = 0 + end) + imageButton.MouseLeave:connect(function() + if selectedButton ~= buttonWrap then + buttonWrap.BackgroundTransparency = 1 + end + end) + imageButton.MouseButton1Click:connect(function() + if selectedButton ~= buttonWrap then + goToNewMaterial(buttonWrap, tostring(name)) + end + end) + + return buttonWrap + end + + for i = 1, #materialNames do + local imageButton = createMaterialButton(materialNames[i]) + + if materialNames[i] == "Grass" then -- always start with grass as the default + selectedButton = imageButton + imageButton.BackgroundTransparency = 0 + end + + imageButton.Parent = scrollFrame + end + + local forceTerrainMaterialSelection = function(newMaterialType) + if not newMaterialType then return end + if currentMaterial == newMaterialType then return end + + local matName = getNameFromEnum(newMaterialType) + local buttons = scrollFrame:GetChildren() + for i = 1, #buttons do + if buttons[i].Name == "Plastic (blue)" and matName == "Plastic (blue)" then goToNewMaterial(buttons[i],matName) return end + if buttons[i].Name == "Plastic (red)" and matName == "Plastic (red)" then goToNewMaterial(buttons[i],matName) return end + if string.find(buttons[i].Name, matName) then + goToNewMaterial(buttons[i],matName) + return + end + end + end + + frame.Changed:connect(function ( prop ) + if prop == "AbsoluteSize" then + recalculateScroll() + end + end) + + recalculateScroll() + return frame, terrainMaterialSelectionChanged, forceTerrainMaterialSelection +end + +t.CreateLoadingFrame = function(name,size,position) + game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=35238053") + + local loadingFrame = Instance.new("Frame") + loadingFrame.Name = "LoadingFrame" + loadingFrame.Style = Enum.FrameStyle.RobloxRound + + if size then loadingFrame.Size = size + else loadingFrame.Size = UDim2.new(0,300,0,160) end + if position then loadingFrame.Position = position + else loadingFrame.Position = UDim2.new(0.5, -150, 0.5,-80) end + + local loadingBar = Instance.new("Frame") + loadingBar.Name = "LoadingBar" + loadingBar.BackgroundColor3 = Color3.new(0,0,0) + loadingBar.BorderColor3 = Color3.new(79/255,79/255,79/255) + loadingBar.Position = UDim2.new(0,0,0,41) + loadingBar.Size = UDim2.new(1,0,0,30) + loadingBar.Parent = loadingFrame + + local loadingGreenBar = Instance.new("ImageLabel") + loadingGreenBar.Name = "LoadingGreenBar" + loadingGreenBar.Image = "http://www.roblox.com/asset/?id=35238053" + loadingGreenBar.Position = UDim2.new(0,0,0,0) + loadingGreenBar.Size = UDim2.new(0,0,1,0) + loadingGreenBar.Visible = false + loadingGreenBar.Parent = loadingBar + + local loadingPercent = Instance.new("TextLabel") + loadingPercent.Name = "LoadingPercent" + loadingPercent.BackgroundTransparency = 1 + loadingPercent.Position = UDim2.new(0,0,1,0) + loadingPercent.Size = UDim2.new(1,0,0,14) + loadingPercent.Font = Enum.Font.Arial + loadingPercent.Text = "0%" + loadingPercent.FontSize = Enum.FontSize.Size14 + loadingPercent.TextColor3 = Color3.new(1,1,1) + loadingPercent.Parent = loadingBar + + local cancelButton = Instance.new("TextButton") + cancelButton.Name = "CancelButton" + cancelButton.Position = UDim2.new(0.5,-60,1,-40) + cancelButton.Size = UDim2.new(0,120,0,40) + cancelButton.Font = Enum.Font.Arial + cancelButton.FontSize = Enum.FontSize.Size18 + cancelButton.TextColor3 = Color3.new(1,1,1) + cancelButton.Text = "Cancel" + cancelButton.Style = Enum.ButtonStyle.RobloxButton + cancelButton.Parent = loadingFrame + + local loadingName = Instance.new("TextLabel") + loadingName.Name = "loadingName" + loadingName.BackgroundTransparency = 1 + loadingName.Size = UDim2.new(1,0,0,18) + loadingName.Position = UDim2.new(0,0,0,2) + loadingName.Font = Enum.Font.Arial + loadingName.Text = name + loadingName.TextColor3 = Color3.new(1,1,1) + loadingName.TextStrokeTransparency = 1 + loadingName.FontSize = Enum.FontSize.Size18 + loadingName.Parent = loadingFrame + + local cancelButtonClicked = Instance.new("BindableEvent") + cancelButtonClicked.Name = "CancelButtonClicked" + cancelButtonClicked.Parent = cancelButton + cancelButton.MouseButton1Click:connect(function() + cancelButtonClicked:Fire() + end) + + local updateLoadingGuiPercent = function(percent, tweenAction, tweenLength) + if percent and type(percent) ~= "number" then + error("updateLoadingGuiPercent expects number as argument, got",type(percent),"instead") + end + + local newSize = nil + if percent < 0 then + newSize = UDim2.new(0,0,1,0) + elseif percent > 1 then + newSize = UDim2.new(1,0,1,0) + else + newSize = UDim2.new(percent,0,1,0) + end + + if tweenAction then + if not tweenLength then + error("updateLoadingGuiPercent is set to tween new percentage, but got no tween time length! Please pass this in as third argument") + end + + if (newSize.X.Scale > 0) then + loadingGreenBar.Visible = true + loadingGreenBar:TweenSize( newSize, + Enum.EasingDirection.Out, + Enum.EasingStyle.Quad, + tweenLength, + true) + else + loadingGreenBar:TweenSize( newSize, + Enum.EasingDirection.Out, + Enum.EasingStyle.Quad, + tweenLength, + true, + function() + if (newSize.X.Scale < 0) then + loadingGreenBar.Visible = false + end + end) + end + + else + loadingGreenBar.Size = newSize + loadingGreenBar.Visible = (newSize.X.Scale > 0) + end + end + + loadingGreenBar.Changed:connect(function(prop) + if prop == "Size" then + loadingPercent.Text = tostring( math.ceil(loadingGreenBar.Size.X.Scale * 100) ) .. "%" + end + end) + + return loadingFrame, updateLoadingGuiPercent, cancelButtonClicked +end + +t.CreatePluginFrame = function (name,size,position,scrollable,parent) + function createMenuButton(size,position,text,fontsize,name,parent) + local button = Instance.new("TextButton",parent) + button.AutoButtonColor = false + button.Name = name + button.BackgroundTransparency = 1 + button.Position = position + button.Size = size + button.Font = Enum.Font.ArialBold + button.FontSize = fontsize + button.Text = text + button.TextColor3 = Color3.new(1,1,1) + button.BorderSizePixel = 0 + button.BackgroundColor3 = Color3.new(20/255,20/255,20/255) + + button.MouseEnter:connect(function ( ) + if button.Selected then return end + button.BackgroundTransparency = 0 + end) + button.MouseLeave:connect(function ( ) + if button.Selected then return end + button.BackgroundTransparency = 1 + end) + + return button + + end + + local dragBar = Instance.new("Frame",parent) + dragBar.Name = tostring(name) .. "DragBar" + dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255) + dragBar.BorderColor3 = Color3.new(0,0,0) + if size then + dragBar.Size = UDim2.new(size.X.Scale,size.X.Offset,0,20) + UDim2.new(0,20,0,0) + else + dragBar.Size = UDim2.new(0,183,0,20) + end + if position then + dragBar.Position = position + end + dragBar.Active = true + dragBar.Draggable = true + --dragBar.Visible = false + dragBar.MouseEnter:connect(function ( ) + dragBar.BackgroundColor3 = Color3.new(49/255,49/255,49/255) + end) + dragBar.MouseLeave:connect(function ( ) + dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255) + end) + + -- plugin name label + local pluginNameLabel = Instance.new("TextLabel",dragBar) + pluginNameLabel.Name = "BarNameLabel" + pluginNameLabel.Text = " " .. tostring(name) + pluginNameLabel.TextColor3 = Color3.new(1,1,1) + pluginNameLabel.TextStrokeTransparency = 0 + pluginNameLabel.Size = UDim2.new(1,0,1,0) + pluginNameLabel.Font = Enum.Font.ArialBold + pluginNameLabel.FontSize = Enum.FontSize.Size18 + pluginNameLabel.TextXAlignment = Enum.TextXAlignment.Left + pluginNameLabel.BackgroundTransparency = 1 + + -- close button + local closeButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-16,0.5,-8),"X",Enum.FontSize.Size14,"CloseButton",dragBar) + local closeEvent = Instance.new("BindableEvent") + closeEvent.Name = "CloseEvent" + closeEvent.Parent = closeButton + closeButton.MouseButton1Click:connect(function () + closeEvent:Fire() + closeButton.BackgroundTransparency = 1 + end) + + -- help button + local helpButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-51,0.5,-8),"?",Enum.FontSize.Size14,"HelpButton",dragBar) + local helpFrame = Instance.new("Frame",dragBar) + helpFrame.Name = "HelpFrame" + helpFrame.BackgroundColor3 = Color3.new(0,0,0) + helpFrame.Size = UDim2.new(0,300,0,552) + helpFrame.Position = UDim2.new(1,5,0,0) + helpFrame.Active = true + helpFrame.BorderSizePixel = 0 + helpFrame.Visible = false + + helpButton.MouseButton1Click:connect(function( ) + helpFrame.Visible = not helpFrame.Visible + if helpFrame.Visible then + helpButton.Selected = true + helpButton.BackgroundTransparency = 0 + local screenGui = getScreenGuiAncestor(helpFrame) + if screenGui then + if helpFrame.AbsolutePosition.X + helpFrame.AbsoluteSize.X > screenGui.AbsoluteSize.X then --position on left hand side + helpFrame.Position = UDim2.new(0,-5 - helpFrame.AbsoluteSize.X,0,0) + else -- position on right hand side + helpFrame.Position = UDim2.new(1,5,0,0) + end + else + helpFrame.Position = UDim2.new(1,5,0,0) + end + else + helpButton.Selected = false + helpButton.BackgroundTransparency = 1 + end + end) + + local minimizeButton = createMenuButton(UDim2.new(0,16,0,17),UDim2.new(1,-34,0.5,-8),"-",Enum.FontSize.Size14,"MinimizeButton",dragBar) + minimizeButton.TextYAlignment = Enum.TextYAlignment.Top + + local minimizeFrame = Instance.new("Frame",dragBar) + minimizeFrame.Name = "MinimizeFrame" + minimizeFrame.BackgroundColor3 = Color3.new(73/255,73/255,73/255) + minimizeFrame.BorderColor3 = Color3.new(0,0,0) + minimizeFrame.Position = UDim2.new(0,0,1,0) + if size then + minimizeFrame.Size = UDim2.new(size.X.Scale,size.X.Offset,0,50) + UDim2.new(0,20,0,0) + else + minimizeFrame.Size = UDim2.new(0,183,0,50) + end + minimizeFrame.Visible = false + + local minimizeBigButton = Instance.new("TextButton",minimizeFrame) + minimizeBigButton.Position = UDim2.new(0.5,-50,0.5,-20) + minimizeBigButton.Name = "MinimizeButton" + minimizeBigButton.Size = UDim2.new(0,100,0,40) + minimizeBigButton.Style = Enum.ButtonStyle.RobloxButton + minimizeBigButton.Font = Enum.Font.ArialBold + minimizeBigButton.FontSize = Enum.FontSize.Size18 + minimizeBigButton.TextColor3 = Color3.new(1,1,1) + minimizeBigButton.Text = "Show" + + local separatingLine = Instance.new("Frame",dragBar) + separatingLine.Name = "SeparatingLine" + separatingLine.BackgroundColor3 = Color3.new(115/255,115/255,115/255) + separatingLine.BorderSizePixel = 0 + separatingLine.Position = UDim2.new(1,-18,0.5,-7) + separatingLine.Size = UDim2.new(0,1,0,14) + + local otherSeparatingLine = separatingLine:clone() + otherSeparatingLine.Position = UDim2.new(1,-35,0.5,-7) + otherSeparatingLine.Parent = dragBar + + local widgetContainer = Instance.new("Frame",dragBar) + widgetContainer.Name = "WidgetContainer" + widgetContainer.BackgroundTransparency = 1 + widgetContainer.Position = UDim2.new(0,0,1,0) + widgetContainer.BorderColor3 = Color3.new(0,0,0) + if not scrollable then + widgetContainer.BackgroundTransparency = 0 + widgetContainer.BackgroundColor3 = Color3.new(72/255,72/255,72/255) + end + + if size then + if scrollable then + widgetContainer.Size = size + else + widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,size.Y.Scale,size.Y.Offset) + end + else + if scrollable then + widgetContainer.Size = UDim2.new(0,163,0,400) + else + widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,0,400) + end + end + if position then + widgetContainer.Position = position + UDim2.new(0,0,0,20) + end + + local frame,control,verticalDragger = nil + if scrollable then + --frame for widgets + frame,control = t.CreateTrueScrollingFrame() + frame.Size = UDim2.new(1, 0, 1, 0) + frame.BackgroundColor3 = Color3.new(72/255,72/255,72/255) + frame.BorderColor3 = Color3.new(0,0,0) + frame.Active = true + frame.Parent = widgetContainer + control.Parent = dragBar + control.BackgroundColor3 = Color3.new(72/255,72/255,72/255) + control.BorderSizePixel = 0 + control.BackgroundTransparency = 0 + control.Position = UDim2.new(1,-21,1,1) + if size then + control.Size = UDim2.new(0,21,size.Y.Scale,size.Y.Offset) + else + control.Size = UDim2.new(0,21,0,400) + end + control:FindFirstChild("ScrollDownButton").Position = UDim2.new(0,0,1,-20) + + local fakeLine = Instance.new("Frame",control) + fakeLine.Name = "FakeLine" + fakeLine.BorderSizePixel = 0 + fakeLine.BackgroundColor3 = Color3.new(0,0,0) + fakeLine.Size = UDim2.new(0,1,1,1) + fakeLine.Position = UDim2.new(1,0,0,0) + + verticalDragger = Instance.new("TextButton",widgetContainer) + verticalDragger.ZIndex = 2 + verticalDragger.AutoButtonColor = false + verticalDragger.Name = "VerticalDragger" + verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255) + verticalDragger.BorderColor3 = Color3.new(0,0,0) + verticalDragger.Size = UDim2.new(1,20,0,20) + verticalDragger.Position = UDim2.new(0,0,1,0) + verticalDragger.Active = true + verticalDragger.Text = "" + + local scrubFrame = Instance.new("Frame",verticalDragger) + scrubFrame.Name = "ScrubFrame" + scrubFrame.BackgroundColor3 = Color3.new(1,1,1) + scrubFrame.BorderSizePixel = 0 + scrubFrame.Position = UDim2.new(0.5,-5,0.5,0) + scrubFrame.Size = UDim2.new(0,10,0,1) + scrubFrame.ZIndex = 5 + local scrubTwo = scrubFrame:clone() + scrubTwo.Position = UDim2.new(0.5,-5,0.5,-2) + scrubTwo.Parent = verticalDragger + local scrubThree = scrubFrame:clone() + scrubThree.Position = UDim2.new(0.5,-5,0.5,2) + scrubThree.Parent = verticalDragger + + local areaSoak = Instance.new("TextButton",getScreenGuiAncestor(parent)) + areaSoak.Name = "AreaSoak" + areaSoak.Size = UDim2.new(1,0,1,0) + areaSoak.BackgroundTransparency = 1 + areaSoak.BorderSizePixel = 0 + areaSoak.Text = "" + areaSoak.ZIndex = 10 + areaSoak.Visible = false + areaSoak.Active = true + + local draggingVertical = false + local startYPos = nil + verticalDragger.MouseEnter:connect(function () + verticalDragger.BackgroundColor3 = Color3.new(60/255,60/255,60/255) + end) + verticalDragger.MouseLeave:connect(function () + verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255) + end) + verticalDragger.MouseButton1Down:connect(function(x,y) + draggingVertical = true + areaSoak.Visible = true + startYPos = y + end) + areaSoak.MouseButton1Up:connect(function ( ) + draggingVertical = false + areaSoak.Visible = false + end) + areaSoak.MouseMoved:connect(function(x,y) + if not draggingVertical then return end + + local yDelta = y - startYPos + if not control.ScrollDownButton.Visible and yDelta > 0 then + return + end + + if (widgetContainer.Size.Y.Offset + yDelta) < 150 then + widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,150) + control.Size = UDim2.new (0,21,0,150) + return + end + + startYPos = y + + if widgetContainer.Size.Y.Offset + yDelta >= 0 then + widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,widgetContainer.Size.Y.Offset + yDelta) + control.Size = UDim2.new(0,21,0,control.Size.Y.Offset + yDelta ) + end + end) + end + + local function switchMinimize() + minimizeFrame.Visible = not minimizeFrame.Visible + if scrollable then + frame.Visible = not frame.Visible + verticalDragger.Visible = not verticalDragger.Visible + control.Visible = not control.Visible + else + widgetContainer.Visible = not widgetContainer.Visible + end + + if minimizeFrame.Visible then + minimizeButton.Text = "+" + else + minimizeButton.Text = "-" + end + end + + minimizeBigButton.MouseButton1Click:connect(function ( ) + switchMinimize() + end) + + minimizeButton.MouseButton1Click:connect(function( ) + switchMinimize() + end) + + if scrollable then + return dragBar, frame, helpFrame, closeEvent + else + return dragBar, widgetContainer, helpFrame, closeEvent + end +end + +t.Help = + function(funcNameOrFunc) + --input argument can be a string or a function. Should return a description (of arguments and expected side effects) + if funcNameOrFunc == "CreatePropertyDropDownMenu" or funcNameOrFunc == t.CreatePropertyDropDownMenu then + return "Function CreatePropertyDropDownMenu. " .. + "Arguments: (instance, propertyName, enumType). " .. + "Side effect: returns a container with a drop-down-box that is linked to the 'property' field of 'instance' which is of type 'enumType'" + end + if funcNameOrFunc == "CreateDropDownMenu" or funcNameOrFunc == t.CreateDropDownMenu then + return "Function CreateDropDownMenu. " .. + "Arguments: (items, onItemSelected). " .. + "Side effect: Returns 2 results, a container to the gui object and a 'updateSelection' function for external updating. The container is a drop-down-box created around a list of items" + end + if funcNameOrFunc == "CreateMessageDialog" or funcNameOrFunc == t.CreateMessageDialog then + return "Function CreateMessageDialog. " .. + "Arguments: (title, message, buttons). " .. + "Side effect: Returns a gui object of a message box with 'title' and 'message' as passed in. 'buttons' input is an array of Tables contains a 'Text' and 'Function' field for the text/callback of each button" + end + if funcNameOrFunc == "CreateStyledMessageDialog" or funcNameOrFunc == t.CreateStyledMessageDialog then + return "Function CreateStyledMessageDialog. " .. + "Arguments: (title, message, style, buttons). " .. + "Side effect: Returns a gui object of a message box with 'title' and 'message' as passed in. 'buttons' input is an array of Tables contains a 'Text' and 'Function' field for the text/callback of each button, 'style' is a string, either Error, Notify or Confirm" + end + if funcNameOrFunc == "GetFontHeight" or funcNameOrFunc == t.GetFontHeight then + return "Function GetFontHeight. " .. + "Arguments: (font, fontSize). " .. + "Side effect: returns the size in pixels of the given font + fontSize" + end + if funcNameOrFunc == "LayoutGuiObjects" or funcNameOrFunc == t.LayoutGuiObjects then + + end + if funcNameOrFunc == "CreateScrollingFrame" or funcNameOrFunc == t.CreateScrollingFrame then + return "Function CreateScrollingFrame. " .. + "Arguments: (orderList, style) " .. + "Side effect: returns 4 objects, (scrollFrame, scrollUpButton, scrollDownButton, recalculateFunction). 'scrollFrame' can be filled with GuiObjects. It will lay them out and allow scrollUpButton/scrollDownButton to interact with them. Orderlist is optional (and specifies the order to layout the children. Without orderlist, it uses the children order. style is also optional, and allows for a 'grid' styling if style is passed 'grid' as a string. recalculateFunction can be called when a relayout is needed (when orderList changes)" + end + if funcNameOrFunc == "CreateTrueScrollingFrame" or funcNameOrFunc == t.CreateTrueScrollingFrame then + return "Function CreateTrueScrollingFrame. " .. + "Arguments: (nil) " .. + "Side effect: returns 2 objects, (scrollFrame, controlFrame). 'scrollFrame' can be filled with GuiObjects, and they will be clipped if not inside the frame's bounds. controlFrame has children scrollup and scrolldown, as well as a slider. controlFrame can be parented to any guiobject and it will readjust itself to fit." + end + if funcNameOrFunc == "AutoTruncateTextObject" or funcNameOrFunc == t.AutoTruncateTextObject then + return "Function AutoTruncateTextObject. " .. + "Arguments: (textLabel) " .. + "Side effect: returns 2 objects, (textLabel, changeText). The 'textLabel' input is modified to automatically truncate text (with ellipsis), if it gets too small to fit. 'changeText' is a function that can be used to change the text, it takes 1 string as an argument" + end + if funcNameOrFunc == "CreateSlider" or funcNameOrFunc == t.CreateSlider then + return "Function CreateSlider. " .. + "Arguments: (steps, width, position) " .. + "Side effect: returns 2 objects, (sliderGui, sliderPosition). The 'steps' argument specifies how many different positions the slider can hold along the bar. 'width' specifies in pixels how wide the bar should be (modifiable afterwards if desired). 'position' argument should be a UDim2 for slider positioning. 'sliderPosition' is an IntValue whose current .Value specifies the specific step the slider is currently on." + end + if funcNameOrFunc == "CreateSliderNew" or funcNameOrFunc == t.CreateSliderNew then + return "Function CreateSliderNew. " .. + "Arguments: (steps, width, position) " .. + "Side effect: returns 2 objects, (sliderGui, sliderPosition). The 'steps' argument specifies how many different positions the slider can hold along the bar. 'width' specifies in pixels how wide the bar should be (modifiable afterwards if desired). 'position' argument should be a UDim2 for slider positioning. 'sliderPosition' is an IntValue whose current .Value specifies the specific step the slider is currently on." + end + if funcNameOrFunc == "CreateLoadingFrame" or funcNameOrFunc == t.CreateLoadingFrame then + return "Function CreateLoadingFrame. " .. + "Arguments: (name, size, position) " .. + "Side effect: Creates a gui that can be manipulated to show progress for a particular action. Name appears above the loading bar, and size and position are udim2 values (both size and position are optional arguments). Returns 3 arguments, the first being the gui created. The second being updateLoadingGuiPercent, which is a bindable function. This function takes one argument (two optionally), which should be a number between 0 and 1, representing the percentage the loading gui should be at. The second argument to this function is a boolean value that if set to true will tween the current percentage value to the new percentage value, therefore our third argument is how long this tween should take. Our third returned argument is a BindableEvent, that when fired means that someone clicked the cancel button on the dialog." + end + if funcNameOrFunc == "CreateTerrainMaterialSelector" or funcNameOrFunc == t.CreateTerrainMaterialSelector then + return "Function CreateTerrainMaterialSelector. " .. + "Arguments: (size, position) " .. + "Side effect: Size and position are UDim2 values that specifies the selector's size and position. Both size and position are optional arguments. This method returns 3 objects (terrainSelectorGui, terrainSelected, forceTerrainSelection). terrainSelectorGui is just the gui object that we generate with this function, parent it as you like. TerrainSelected is a BindableEvent that is fired whenever a new terrain type is selected in the gui. ForceTerrainSelection is a function that takes an argument of Enum.CellMaterial and will force the gui to show that material as currently selected." + end + end + + + +local RbxGui + +local localTesting = true + +local screen = script.Parent +local screenResizeCon = nil + +local friendWord = "Friend" +local friendWordLowercase = "friend" + +local elementNames = {} +local elementNameToElement = {} + +local privilegeOwner = 255 +local privilegeAdmin = 240 +local privilegeMember = 128 +local privilegeVisitor = 10 +local privilegeBanned = 0 + +local inContextMenu = false +local contextMenu3d = false + +local bigEasingStyle = Enum.EasingStyle.Back +local smallEasingStyle = Enum.EasingStyle.Quart + +local personalServerContextAdded = false +local personalServerPlace = false +local success = pcall(function() personalServerPlace = game.IsPersonalServer end) +if not success then + personalServerPlace = false +end + +local friendRequestBlacklist = {} +local otherPlayerBlacklist = {} + +local currentSortName = "" + +local function waitForChild(instance, name) + while not instance:FindFirstChild(name) do + instance.ChildAdded:wait() + end +end + +local function waitForProperty(instance, prop) + while not instance[prop] do + instance.Changed:wait() + end +end + +local function Color3I(r,g,b) + return Color3.new(r/255,g/255,b/255) +end + +function robloxLock(instance) +end + +function ArrayRemove(t, obj) + for i, obj2 in ipairs(t) do + if obj == obj2 then + table.remove(t, i) + return true + end + end + return false +end + +local function getPlayers() + local result = {} + local players = game:GetService("Players"):GetChildren() + if players then + for i, player in ipairs(players) do + if player:IsA("Player") then + table.insert(result, player) + end + end + end + return result +end + +local brickColorTable = {} +for i = 0, 63 do + brickColorTable[BrickColor.palette(i).Name] = BrickColor.palette(i).Color +end + +local function remapColor(i, j) + brickColorTable[BrickColor.palette(i).Name] = BrickColor.palette(j).Color +end + +remapColor(13, 12) +remapColor(14, 12) +remapColor(15, 12) +remapColor(61, 29) +remapColor(63, 62) +remapColor(56, 50) +remapColor(45, 53) +remapColor(51, 20) +remapColor(4, 20) +remapColor(59, 35) +remapColor(60, 29) + +local function getColor(brickColor) + if brickColorTable[brickColor.Name] then + return brickColorTable[brickColor.Name] + else + return brickColor.Color; + end +end + + + +local function getTeams() + local result = {} + local teams = game:GetService("Teams"):GetChildren() + for i, team in ipairs(teams) do + if team:IsA("Team") then + table.insert(result, team) + end + end + return result +end + +local supportFriends = false +local currentBoardType = "PlayerList" +local currentStatCount = 0 + +local createBoardsFunction = nil + + +local playerTable = {} +local teamTable = {} +local teamColorTable = {} + +local removePlayerFunction = nil +local recreatePlayerFunction = nil +local addPlayerFunction = function(player) + if recreatePlayerFunction then + recreatePlayerFunction(player) + end +end +local sortPlayerListsFunction = nil + +local minimizedState = nil +local bigWindowImposter = nil +local smallWindowPosition = UDim2.new(0, -20, 0,5) +local smallWindowSize = UDim2.new(1,0,1,0) +local bigWindowSize = UDim2.new(0.6,0,0.6,0) +local bigWindowPosition = UDim2.new(.2, 0, .2,0) + +local smallWindowHeaderYSize = 32 + +local debounceTeamsChanged = false + +local currentWindowState = "Small" +local previousWindowState = nil +local transitionWindowsFunction = nil + +local container = nil +local topRightTrayContainer = nil + +local playerContextMenu = nil +local contextMenuElements = {} +local updateContextMenuItems = nil + +local function addContextMenuLabel(getText1, getText2, isVisible) + local t = {} + t.Type = "Label" + t.GetText1 = getText1 + t.GetText2 = getText2 + t.IsVisible = isVisible + table.insert(contextMenuElements, t) +end +local function addContextMenuButton(text, isVisible, isActive, doIt) + local t = {} + t.Text = text + t.Type = "Button" + t.IsVisible = isVisible + t.IsActive = isActive + t.DoIt = doIt + table.insert(contextMenuElements, t) +end + +local function getFriendStatus(player) + if player == game.Players.LocalPlayer then + return Enum.FriendStatus.NotFriend + else + local success, result = pcall(function() return game.Players.LocalPlayer:GetFriendStatus(player) end) + if success then + return result + else + return Enum.FriendStatus.NotFriend + end + end +end + + +local function getPrivilegeType(player) + local rank = player.PersonalServerRank + if rank >= privilegeOwner then + return privilegeOwner + elseif rank < privilegeOwner and rank >= privilegeAdmin then + return privilegeAdmin + elseif rank < privilegeAdmin and rank >= privilegeMember then + return privilegeMember + elseif rank < privilegeMember and rank >= privilegeVisitor then + return privilegeVisitor + else + return privilegeBanned + end +end + +--Populate the ContextMenus +addContextMenuLabel( + --GetText1 + function(player) + return "Loading..." + end, + --GetText2 + nil, + --IsVisible + function(player) + return getFriendStatus(player) == Enum.FriendStatus.Unknown + end) + +addContextMenuButton("Send " .. friendWord .. " Request", + --IsVisible + function(player) + return (not otherPlayerBlacklist[player]) and (getFriendStatus(player) == Enum.FriendStatus.NotFriend) + end, + --IsActive + function(player) + return true + end, + --DoIt? + function(player) + otherPlayerBlacklist[player] = true + return game.Players.LocalPlayer:RequestFriendship(player) + end +) +addContextMenuButton("Un" .. friendWordLowercase, + --IsVisible + function(player) + return getFriendStatus(player) == Enum.FriendStatus.Friend + end, + --IsActive + function(player) + return true + end, + --DoIt + function(player) + return game.Players.LocalPlayer:RevokeFriendship(player) + end +) +addContextMenuButton("Accept " .. friendWord .. " Request", + --IsVisible + function(player) + return (not friendRequestBlacklist[player]) and (getFriendStatus(player) == Enum.FriendStatus.FriendRequestReceived) + end, + --IsActive + function(player) + return true + end, + --DoIt + function(player) + return game.Players.LocalPlayer:RequestFriendship(player) + end +) + +addContextMenuButton("Deny " .. friendWord .. " Request", + --IsVisible + function(player) + return getFriendStatus(player) == Enum.FriendStatus.FriendRequestReceived + end, + --IsActive + function(player) + return true + end, + --DoIt + function(player) + friendRequestBlacklist[player] = true + return game.Players.LocalPlayer:RevokeFriendship(player) + end +) + +addContextMenuButton("Cancel " .. friendWord .. " Request", + --IsVisible + function(player) + return false -- disable cancel request for now (can lead to griefing) + --return getFriendStatus(player) == Enum.FriendStatus.FriendRequestSent + end, + --IsActive + function(player) + return true + end, + --DoIt + function(player) + otherPlayerBlacklist[player] = false + return game.Players.LocalPlayer:RevokeFriendship(player) + end +) + +function addPersonalServerContext() + if personalServerContextAdded then return end + personalServerContextAdded = true + addContextMenuButton("Ban", + --IsVisible + function(player) + return ( getPrivilegeType(game.Players.LocalPlayer) >= privilegeAdmin and (getPrivilegeType(player) < privilegeAdmin) ) + end, + --IsActive + function(player) + return true + end, + --DoIt + function(player) + player.PersonalServerRank = privilegeBanned + return true + end + ) + addContextMenuButton("Promote to Visitor", + --IsVisible + function(player) + return ( getPrivilegeType(game.Players.LocalPlayer) >= privilegeAdmin ) and ( getPrivilegeType(player) == privilegeBanned ) + end, + --IsActive + function(player) + return true + end, + --DoIt + function(player) + game:GetService("PersonalServerService"):Promote(player) + return true + end + ) + addContextMenuButton("Promote to Member", + --IsVisible + function(player) + return ( getPrivilegeType(game.Players.LocalPlayer) >= privilegeAdmin ) and ( getPrivilegeType(player) == privilegeVisitor ) + end, + --IsActive + function(player) + return true + end, + --DoIt + function(player) + game:GetService("PersonalServerService"):Promote(player) + return true + end + ) + addContextMenuButton("Promote to Admin", + --IsVisible + function(player) + return ( getPrivilegeType(game.Players.LocalPlayer) == privilegeOwner ) and ( getPrivilegeType(player) == privilegeMember ) + end, + --IsActive + function(player) + return true + end, + --DoIt + function(player) + game:GetService("PersonalServerService"):Promote(player) + return true + end + ) + addContextMenuButton("Demote to Member", + --IsVisible + function(player) + return ( getPrivilegeType(game.Players.LocalPlayer) == privilegeOwner ) and ( getPrivilegeType(player) == privilegeAdmin ) + end, + --IsActive + function(player) + return true + end, + --DoIt + function(player) + game:GetService("PersonalServerService"):Demote(player) + return true + end + ) + addContextMenuButton("Demote to Visitor", + --IsVisible + function(player) + return ( getPrivilegeType(game.Players.LocalPlayer) >= privilegeAdmin ) and ( getPrivilegeType(player) == privilegeMember ) + end, + --IsActive + function(player) + return true + end, + --DoIt + function(player) + game:GetService("PersonalServerService"):Demote(player) + return true + end + ) +end + +local function setupBuildToolManagement() + local buildToolManagerAssetId = 64164692 + game:GetService("ScriptContext"):AddCoreScript(buildToolManagerAssetId,game.Players.LocalPlayer,"BuildToolManager") +end + + +local function getStatColumns(players) + for i, player in ipairs(players) do + local leaderstats = player:FindFirstChild("leaderstats") + if leaderstats then + local stats = {} + local children = leaderstats:GetChildren() + if children then + for i, stat in ipairs(children) do + if stat:IsA("IntValue") then + table.insert(stats, stat) + else + --TODO: This should check for IntValue only but current ScoreHud does not + table.insert(stats, stat) + end + end + end + return stats + end + end + return nil +end + +local function determineBoardType() + local players = getPlayers() + + local foundLeaderstats = false + local numStats = 0 + local foundTeam = false + + local stats = getStatColumns(players) + if stats then + foundLeaderstats = true + numStats = #stats + end + + for i, player in ipairs(players) do + if not foundTeam then + if not player.Neutral then + foundTeam = true + break + end + end + end + + if foundLeaderstats and foundTeam then + return "TeamScore", numStats + elseif foundLeaderstats then + return "PlayerScore", numStats + elseif foundTeam then + return "TeamList", numStats + else + return "PlayerList", numStats + end +end + +local function toggleBigWindow() + if container == nil then + return + end + + if currentWindowState == "Big" then + --Hide it + if previousWindowState == nil or previousWindowState == "Big" or previousWindowState == "None" then + transitionWindowsFunction("None") + else + transitionWindowsFunction("Small") + end + else + previousWindowState = currentWindowState + transitionWindowsFunction("Big") + end +end +local previousBigPlayerList = nil +local function rebuildBoard(owner, boardType, numStats) + if topRightTrayContainer == nil then + topRightTrayContainer = owner:FindFirstChild("PlayerListTopRightFrame") + if topRightTrayContainer == nil then + topRightTrayContainer = Instance.new("Frame") + topRightTrayContainer.Name = "PlayerListTopRightFrame" + topRightTrayContainer.BackgroundTransparency = 1 + topRightTrayContainer.Size = UDim2.new(0.2, 16, 0.42, 16) + topRightTrayContainer.Position = UDim2.new(0.8, 0, 0, 0) + topRightTrayContainer.Parent = container + end + end + if minimizedState == nil then + minimizedState = Instance.new("Frame") + minimizedState.Name = "MinimizedPlayerlist" + minimizedState.BackgroundTransparency = 1 + minimizedState.Position = UDim2.new(1, -166, 0,0) + minimizedState.Size = UDim2.new(0, 151, 0, 30) + + playerListButton = Instance.new("ImageButton") + playerListButton.Name = "GoSmallButton" + playerListButton.Image = "rbxasset://textures/ui/playerlist_hidden_small.png" + playerListButton.BackgroundTransparency = 1 + playerListButton.Size = UDim2.new(0.0, 35, 0, 30) + playerListButton.Position = UDim2.new(1, -35, 0, 0) + playerListButton.MouseButton1Click:connect( + function() + transitionWindowsFunction("Small") + end) + playerListButton.Parent = minimizedState + + minimizedState.Visible = false + robloxLock(minimizedState) + minimizedState.Parent = topRightTrayContainer + end + if bigWindowImposter == nil then + bigWindowImposter = owner:FindFirstChild("BigPlayerListWindowImposter") + if bigWindowImposter == nil then + bigWindowImposter = Instance.new("Frame") + bigWindowImposter.Name = "BigPlayerListWindowImposter" + bigWindowImposter.Visible = false + bigWindowImposter.BackgroundColor3 = Color3.new(0,0,0) + bigWindowImposter.BackgroundTransparency = 0.7 + bigWindowImposter.BorderSizePixel = 0 + bigWindowImposter.Size = UDim2.new(0.4, 7, 0.4, 7) + bigWindowImposter.Position = UDim2.new(0.3, 0, 0.3, 0) + robloxLock(bigWindowImposter) + bigWindowImposter.Parent = container + end + end + if container == nil or container ~= owner then + container = owner + + topRightTrayContainer.Parent = container + bigWindowImposter.Parent = container + end + + local smallVisible = true + local bigVisible = false + if container then + if topRightTrayContainer then + --Delete the old boards + if topRightTrayContainer:FindFirstChild("SmallPlayerlist") then + smallVisible = topRightTrayContainer.SmallPlayerlist.Visible + topRightTrayContainer.SmallPlayerlist.Parent = nil + end + end + if container:FindFirstChild("BigPlayerlist") then + bigVisible = container.BigPlayerlist.Visible or (previousBigPlayerList ~= nil) + container.BigPlayerlist.Parent = nil + if previousBigPlayerList ~= nil then + pcall(function() game.GuiService:RemoveCenterDialog(previousBigPlayerList) end) + previousBigPlayerList = nil + end + end + end + + local smallBoard, bigBoard = createBoardsFunction(boardType, numStats) + if smallBoard then + smallBoard.Visible = smallVisible + smallBoard.Parent = topRightTrayContainer + recalculateSmallPlayerListSize(smallBoard) + end + if bigBoard then + if bigVisible then + previousBigPlayerList = bigBoard + local centerDialogSupported, msg = pcall(function() game.GuiService:AddCenterDialog(previousBigPlayerList, Enum.CenterDialogType.PlayerInitiatedDialog, + function() + previousBigPlayerList.Visible = true + end, + function() + previousBigPlayerList.Visible = false + end) + end) + bigBoard.Visible = bigVisible + else + bigBoard.Visible = false + end + bigBoard.Parent = container + end + return container +end + +function recalculateSmallPlayerListSize(smallPlayerList) +end + + +local function showBigPlayerWindow() + if container:FindFirstChild("BigPlayerlist") then + if container.BigPlayerlist.Visible then + return + end + end + + bigWindowImposter.Visible = true + bigWindowImposter:TweenSizeAndPosition(bigWindowSize, bigWindowPosition, Enum.EasingDirection.Out, bigEasingStyle, 0.3, true, + function(state) + if state == Enum.TweenStatus.Completed then + bigWindowImposter.Visible = false + if container:FindFirstChild("BigPlayerlist") then + container.BigPlayerlist.Visible = true + end + end + end) +end + +local function hideBigPlayerWindow(completed) + if playerContextMenu then + playerContextMenu.Visible = false + end + + if container:FindFirstChild("BigPlayerlist") then + if container.BigPlayerlist.Visible == false and bigWindowImposter.Visible == false then + if completed then + completed() + end + --Already completely hidden + return + end + container.BigPlayerlist.Visible = false + end + + local completedFunction = completed + bigWindowImposter.Visible = true + bigWindowImposter:TweenSizeAndPosition(UDim2.new(0.4, 0, 0.4, 0), UDim2.new(0.3, 0, 0.3, 0), Enum.EasingDirection.In, Enum.EasingStyle.Quart, 0.15, true, + function(state) + if state == Enum.TweenStatus.Completed then + bigWindowImposter.Visible = false + if completedFunction then + completedFunction() + end + end + end) +end +local function hideSmallPlayerWindow(completed) + if playerContextMenu then + playerContextMenu.Visible = false + end + if topRightTrayContainer:FindFirstChild("SmallPlayerlist") then + local completedFunction = completed + if topRightTrayContainer.SmallPlayerlist.Visible then + topRightTrayContainer.SmallPlayerlist:TweenPosition(UDim2.new(1,0,smallWindowPosition.Y.Scale, smallWindowPosition.Y.Offset), Enum.EasingDirection.Out, smallEasingStyle, 0.3, true, + function(state) + if state == Enum.TweenStatus.Completed then + if topRightTrayContainer:FindFirstChild("SmallPlayerlist") then + topRightTrayContainer.SmallPlayerlist.Visible = false + end + if completedFunction then + completedFunction() + end + end + end) + return + end + end + if completed then + completed() + end +end + + +transitionWindowsFunction = function(desiredState) + if desiredState == "Big" then + minimizedState.Visible = false + hideSmallPlayerWindow() + + if previousBigPlayerList ~= nil then + if previousBigPlayerList ~= container:FindFirstChild("BigPlayerlist") then + pcall(function() game.GuiService:RemoveCenterDialog(previousBigPlayerList) end) + previousBigPlayerList = nil + previousBigPlayerList = container:FindFirstChild("BigPlayerlist") + end + else + previousBigPlayerList = container:FindFirstChild("BigPlayerlist") + end + + if previousBigPlayerList then + local firstShow = false + local centerDialogSupported, msg = pcall(function() game.GuiService:AddCenterDialog(previousBigPlayerList, Enum.CenterDialogType.PlayerInitiatedDialog, + function() + if not firstShow then + showBigPlayerWindow() + firstShow = true + else + previousBigPlayerList.Visible = true + end + end, + function() + if previousBigPlayerList then + previousBigPlayerList.Visible = false + end + end) + end) + if centerDialogSupported == false then + print("Exception", msg) + showBigPlayerWindow() + end + else + showBigPlayerWindow() + end + currentWindowState = "Big" + elseif desiredState == "Small" then + minimizedState.Visible = false + if previousBigPlayerList ~= nil then + pcall(function() game.GuiService:RemoveCenterDialog(previousBigPlayerList) end) + previousBigPlayerList = nil + end + + hideBigPlayerWindow() + if topRightTrayContainer:FindFirstChild("SmallPlayerlist") then + if not topRightTrayContainer.SmallPlayerlist.Visible or topRightTrayContainer.SmallPlayerlist.Position ~= smallWindowPosition then + topRightTrayContainer.SmallPlayerlist.Visible = true + topRightTrayContainer.SmallPlayerlist:TweenPosition(smallWindowPosition, Enum.EasingDirection.Out, smallEasingStyle, 0.3, true) + end + end + currentWindowState = "Small" + elseif desiredState == "None" then + if previousBigPlayerList ~= nil then + pcall(function() game.GuiService:RemoveCenterDialog(previousBigPlayerList) end) + previousBigPlayerList = nil + end + + local smallDone = false + local bigDone = false + hideSmallPlayerWindow( + function() + smallDone = true + if bigDone and smallDone then + minimizedState.Visible = true + end + end) + hideBigPlayerWindow( + function() + bigDone = true + if bigDone and smallDone then + minimizedState.Visible = true + end + end) + currentWindowState = "None" + end +end + +local function getStatValuesForPlayer(player) + local leaderstats = player:FindFirstChild("leaderstats") + if leaderstats then + local children = leaderstats:GetChildren() + if children then + local result = {} + --Just go based on position + for i, stat in ipairs(children) do + if stat:IsA("IntValue") then + table.insert(result, stat) + else + table.insert(result, 0) + end + end + + return result, leaderstats + end + end + return nil +end + +--ChildAdded on Player (if it's name is "leaderstats") + +if UserSettings and LoadLibrary then + + RbxGui,msg = t + + local function createTeamName(name, color) + local fontHeight = 20 + local frame = Instance.new("Frame") + frame.Name = "Team-" .. name + frame.BorderSizePixel = 0 + frame.BackgroundTransparency = 0.5 + frame.BackgroundColor3 = Color3.new(1,1,1) + frame.Size = UDim2.new(1, 0, 0, fontHeight) + frame.Position = UDim2.new(0,0,0,0) + + local label = Instance.new("TextLabel") + label.Name = "NameLabel" + label.Text = " " .. name + label.Font = Enum.Font.ArialBold + label.FontSize = Enum.FontSize.Size18 + label.Position = UDim2.new(0,0,0,0) + label.Size = UDim2.new(1,0,1,0) + label.TextColor3 = Color3.new(1,1,1) + label.BackgroundTransparency = 0.5 + label.BackgroundColor3 = getColor(color) + label.BorderSizePixel = 0 + label.TextXAlignment = Enum.TextXAlignment.Left + + local changeFunc = nil + label, changeFunc = RbxGui.AutoTruncateTextObject(label) + label.Parent = frame + + return frame, changeFunc + end + + local function getFriendStatusIcon(friendStatus) + if friendStatus == Enum.FriendStatus.Unknown or friendStatus == Enum.FriendStatus.NotFriend then + return nil + elseif friendStatus == Enum.FriendStatus.Friend then + return "rbxasset://textures/ui/PlayerlistFriendIcon.png" + elseif friendStatus == Enum.FriendStatus.FriendRequestSent then + return "rbxasset://textures/ui/PlayerlistFriendRequestSentIcon.png" + elseif friendStatus == Enum.FriendStatus.FriendRequestReceived then + return "rbxasset://textures/ui/PlayerlistFriendRequestReceivedIcon.png" + else + error("Unknown FriendStatus: " .. friendStatus) + end + end + + local function getMembershipTypeIcon(membershipType, playerName) + if membershipType == Enum.MembershipType.None then + return "rbxasset://../../../shareddata/charcustom/custom/icons/"..playerName..".png" + elseif membershipType == Enum.MembershipType.BuildersClub then + return "rbxasset://textures/ui/TinyBcIcon.png" + elseif membershipType == Enum.MembershipType.TurboBuildersClub then + return "rbxasset://textures/ui/TinyTbcIcon.png" + elseif membershipType == Enum.MembershipType.OutrageousBuildersClub then + return "rbxasset://textures/ui/TinyObcIcon.png" + else + error("Uknown membershipType" .. membershipType) + end + end + + + local function updatePlayerFriendStatus(nameObject, friendStatus) + local fontHeight = 20 + + local friendIconImage = getFriendStatusIcon(friendStatus) + nameObject.MembershipTypeLabel.FriendStatusLabel.Visible = (friendIconImage ~= nil) + + if friendIconImage ~= nil then + --Show friend icon + nameObject.MembershipTypeLabel.FriendStatusLabel.Image = friendIconImage + nameObject.NameLabel.Position =UDim2.new(0,2*fontHeight,0,1) + nameObject.NameLabel.Size = UDim2.new(1,-2*fontHeight,1,-2) + else + --Hide the friend icon + nameObject.NameLabel.Position = UDim2.new(0,fontHeight+1,0,1) + nameObject.NameLabel.Size = UDim2.new(1,-(fontHeight+1),1,-2) + end + end + local function updatePlayerName(nameObject, membershipStatus, teamColor) + local fontHeight = 20 + + local playerName = nameObject.NameLabel.Text + + nameObject.Size = UDim2.new(1,0,0,fontHeight) + nameObject.MembershipTypeLabel.Image = getMembershipTypeIcon(membershipStatus, playerName) + end + + + local function updatePlayerNameColor(player, teamColor) + local function updatePlayerNameColorHelper(nameObject) + if teamColor ~= nil then + nameObject.NameLabel.TextColor3 = getColor(teamColor) + nameObject.NameLabel.FullNameLabel.TextColor3 = getColor(teamColor) + else + nameObject.NameLabel.TextColor3 = Color3.new(1,1,1) + nameObject.NameLabel.FullNameLabel.TextColor3 = Color3.new(1,1,1) + end + end + + updatePlayerNameColorHelper(playerTable[player].NameObjectSmall) + updatePlayerNameColorHelper(playerTable[player].NameObjectBig) + end + + + local function createPlayerName(name, membershipStatus, teamColor, friendStatus) + local frame = Instance.new("Frame") + frame.Name = "Player_" .. name + frame.BackgroundColor3 = Color3.new(1,1,1) + frame.BackgroundTransparency = 0.5 + frame.BorderSizePixel = 0 + + local membershipStatusLabel = Instance.new("ImageLabel") + membershipStatusLabel.Name = "MembershipTypeLabel" + membershipStatusLabel.BackgroundTransparency = 1 + membershipStatusLabel.Size = UDim2.new(1,0,1,0) + membershipStatusLabel.Position = UDim2.new(0,0,0,0) + membershipStatusLabel.SizeConstraint = Enum.SizeConstraint.RelativeYY + membershipStatusLabel.Parent = frame + + local friendStatusLabel = Instance.new("ImageLabel") + friendStatusLabel.Name = "FriendStatusLabel" + friendStatusLabel.Visible = false + friendStatusLabel.BackgroundTransparency = 1 + friendStatusLabel.Size = UDim2.new(1,0,1,0) + friendStatusLabel.Position = UDim2.new(1,0,0,0) + friendStatusLabel.Parent = membershipStatusLabel + + local changeNameFunction + local nameLabel = Instance.new("TextLabel") + nameLabel.Name = "NameLabel" + nameLabel.Text = name + nameLabel.Font = Enum.Font.ArialBold + nameLabel.FontSize = Enum.FontSize.Size14 + nameLabel.TextColor3 = Color3.new(1,1,1) + nameLabel.BackgroundTransparency = 1 + nameLabel.BackgroundColor3 = Color3.new(0,0,0) + nameLabel.TextXAlignment = Enum.TextXAlignment.Left + nameLabel, changeNameFunction = RbxGui.AutoTruncateTextObject(nameLabel) + nameLabel.Parent = frame + + updatePlayerName(frame, membershipStatus, teamColor) + if supportFriends and not friendRequestBlacklist[game.Players:FindFirstChild(name)] then + updatePlayerFriendStatus(frame, friendStatus) + else + updatePlayerFriendStatus(frame, Enum.FriendStatus.NotFriend) + end + return frame, changeNameFunction + end + + local function createStatColumn(i, numColumns, isTeam, color3, isHeader, stat) + local textLabel = Instance.new("TextButton") + textLabel.Name = "Stat" .. i + textLabel.AutoButtonColor = false + textLabel.TextColor3 = Color3.new(1,1,1) + textLabel.TextXAlignment = Enum.TextXAlignment.Right + textLabel.TextYAlignment = Enum.TextYAlignment.Center + textLabel.FontSize = Enum.FontSize.Size14 + + if isHeader then + textLabel.FontSize = Enum.FontSize.Size18 + else + textLabel.FontSize = Enum.FontSize.Size14 + end + if isHeader or isTeam then + textLabel.Font = Enum.Font.ArialBold + else + textLabel.Font = Enum.Font.Arial + end + + if isTeam then + textLabel.BackgroundColor3 = color3 + textLabel.Text = 0 + else + textLabel.BackgroundColor3 = Color3.new(0,0,0) + textLabel.Text = "" + end + textLabel.BackgroundTransparency = 1 + if i == numColumns then + textLabel.Size = UDim2.new(1/numColumns, -6, 1, 0) + else + textLabel.Size = UDim2.new(1/numColumns, -4, 1, 0) + end + + textLabel.Position = UDim2.new((i-1) * (1/numColumns), 0, 0, 0) + + local truncLabel, changer = RbxGui.AutoTruncateTextObject(textLabel) + + if isHeader then + local mouseCon = {} + + mouseCon[1] = truncLabel.MouseEnter:connect(function() + truncLabel.BackgroundTransparency = 0.2 + end) + mouseCon[2] = truncLabel.MouseLeave:connect(function() + truncLabel.BackgroundTransparency = 1 + end) + + mouseCon[3] = truncLabel.MouseButton1Click:connect(function() + sortPlayerListsFunction(truncLabel:GetChildren()[1].Name, (currentSortName == truncLabel:GetChildren()[1].Name) ) + truncLabel.BackgroundTransparency = 1 + end) + + mouseCon[4] = truncLabel:GetChildren()[1].MouseButton1Click:connect(function() + sortPlayerListsFunction(textLabel.Name, (currentSortName == truncLabel.Name) ) + truncLabel.BackgroundTransparency = 1 + end) + + mouseCon[5] = nil + mouseCon[5] = truncLabel.AncestryChanged:connect(function(child,parent) + if parent == nil then + for i,connection in pairs(mouseCon) do + connection:disconnect() + end + end + end) + end + + return truncLabel, changer + end + + local function createStatHeaders(stats, numColumns, isBig) + local frame = Instance.new("Frame") + frame.Name = "Headers" + frame.BorderSizePixel = 0 + frame.BackgroundColor3 = Color3.new(0,0,0) + frame.BackgroundTransparency = 1 + + local nameSize + if isBig then + nameSize = 0.5 + elseif numColumns == 1 then + nameSize = 0.7 + elseif numColumns == 2 then + nameSize = 0.6 + else + nameSize = 0.45 + end + frame.Size = UDim2.new(1-nameSize, 0, 1,0) + if isBig then + frame.Position = UDim2.new(nameSize,-25, 0,0) + else + frame.Position = UDim2.new(nameSize,0, 0,0) + end + + local i = 1 + while i <= numColumns do + local headerColumn, changeText = createStatColumn(i, numColumns, false, nil, true,stats[i]) + changeText(stats[i].Name) + headerColumn.Parent = frame + i = i + 1 + end + return frame, textChangers + end + + local function createStatColumns(nameObject, numColumns, isTeam, isBig) + local frame = Instance.new("Frame") + frame.Name = nameObject.Name .. "_WithStats" + frame.BorderSizePixel = 0 + frame.BackgroundColor3 = nameObject.BackgroundColor3 + frame.BackgroundTransparency = nameObject.BackgroundTransparency + frame.Size = nameObject.Size + frame.Position = nameObject.Position + + nameObject.BackgroundTransparency = 1 + + if numColumns == 0 then + nameObject.Size = UDim2.new(1,0,1,0) + nameObject.Position = UDim2.new(0,0,0,0) + nameObject.Parent = frame + return frame + end + + local statFrame = Instance.new("Frame") + statFrame.Name = "Stats" + if isTeam then + statFrame.BorderSizePixel = 0 + statFrame.BackgroundColor3 = nameObject.NameLabel.BackgroundColor3 + statFrame.BackgroundTransparency = nameObject.NameLabel.BackgroundTransparency + else + statFrame.BackgroundTransparency = 1 + end + + local nameSize + if isBig then + nameSize = 0.5 + elseif numColumns == 1 then + nameSize = 0.7 + elseif numColumns == 2 then + nameSize = 0.6 + else + nameSize = 0.45 + end + nameObject.Size = UDim2.new(nameSize, 0, 1, 0) + nameObject.Position = UDim2.new(0, 0, 0, 0) + statFrame.Size = UDim2.new(1-nameSize,0, 1,0) + statFrame.Position = UDim2.new(nameSize,0, 0,0) + + nameObject.Parent = frame + statFrame.Parent = frame + + local textChangers = {} + local i = 1 + while i <= numColumns do + local statColumn, changeText = createStatColumn(i, numColumns, isTeam, statFrame.BackgroundColor3) + statColumn.Parent = statFrame + table.insert(textChangers, changeText) + + i = i + 1 + end + + return frame, statFrame, textChangers + end + + local function createAlternatingRows(objects) + for i, line in ipairs(objects) do + if i % 2 == 0 then + line.BackgroundTransparency = 1 + else + line.BackgroundTransparency = 0.95 + end + end + end + local removeFromTeam = nil + + local function clearTableEntry(obj, tableInfo) + if tableInfo.MainObjectSmall then + tableInfo.MainObjectSmall.Parent = nil + tableInfo.MainObjectSmall = nil + end + if tableInfo.MainObjectBig then + tableInfo.MainObjectBig.Parent = nil + tableInfo.MainObjectBig = nil + end + if tableInfo.Connections then + for i, connection in ipairs(tableInfo.Connections) do + connection:disconnect() + end + tableInfo.Connections = nil + end + if tableInfo.LeaderStatConnections then + for i, connection in ipairs(tableInfo.LeaderStatConnections) do + connection:disconnect() + end + tableInfo.LeaderStatConnections = nil + end + if tableInfo.CurrentTeam then + removeFromTeam(obj) + tableInfo.CurrentTeam = nil + end + if tableInfo.Players then + for i, player in ipairs(tableInfo.Players) do + playerTable[player].CurrentTeam = nil + end + tableInfo.Players = {} + end + if tableInfo.StatValues then + tableInfo.StatValues = nil + end + end + + local function resetPlayerTable() + for player, info in pairs(playerTable) do + clearTableEntry(player, info) + playerTable[player] = nil + end + playerTable = {} + end + + local function resetTeamTable() + for team, info in pairs(teamTable) do + clearTableEntry(team, info) + teamTable[team] = nil + end + teamTable = {} + teamColorTable = {} + end + + local function getBoardTypeInfo() + local isTeam = (currentBoardType == "TeamScore" or currentBoardType == "TeamList") + local isScore = (currentBoardType == "TeamScore" or currentBoardType == "PlayerScore") + return isTeam, isScore + end + + + local function recomputeTeamScore(team, column) + if not team or team == "Neutral" then + return + end + + local function recomputeScoreHelper(statChangers) + if statChangers and column <= #statChangers then + local sum = 0 + for i, p in ipairs(teamTable[team].Players) do + if playerTable[p].StatValues and column <= #playerTable[p].StatValues then + sum = sum + playerTable[p].StatValues[column].Value + end + end + statChangers[column](sum) + end + end + + recomputeScoreHelper(teamTable[team].StatChangersSmall) + recomputeScoreHelper(teamTable[team].StatChangersBig) + end + local function recomputeCompleteTeamScore(team) + local col = 1 + while col <= currentStatCount do + recomputeTeamScore(team, col) + col = col + 1 + end + end + removeFromTeam = function(player) + if playerTable[player].CurrentTeam ~= nil and teamTable[playerTable[player].CurrentTeam] ~= nil then + ArrayRemove(teamTable[playerTable[player].CurrentTeam].Players, player) + recomputeCompleteTeamScore(playerTable[player].CurrentTeam) + playerTable[player].CurrentTeam = nil + end + end + + local function assignToTeam(player) + local isTeam, isScore = getBoardTypeInfo() + + if isTeam then + local newTeam = nil + + if player.Neutral or teamColorTable[player.TeamColor.Name] == nil then + newTeam = "Neutral" + else + newTeam = teamColorTable[player.TeamColor.Name] + end + + if playerTable[player].CurrentTeam == newTeam then + return + end + + local oldTeam = playerTable[player].LastTeam + removeFromTeam(player) + + playerTable[player].CurrentTeam = newTeam + + if teamTable[oldTeam] and teamTable[oldTeam]["NameChangeFuncBig"] then + if #teamTable[oldTeam].Players < 1 then + teamTable[oldTeam]["NameChangeFuncBig"](" " .. oldTeam.Name) + else + teamTable[oldTeam]["NameChangeFuncBig"](" " .. oldTeam.Name .. " (" .. tostring(#teamTable[oldTeam].Players) ..")") + end + end + + if teamTable[newTeam] then + table.insert(teamTable[newTeam].Players, player) + if newTeam["Name"] then + if teamTable[newTeam]["NameChangeFuncBig"] then + if #teamTable[newTeam].Players < 1 then + teamTable[newTeam]["NameChangeFuncBig"](" " .. newTeam.Name) + else + teamTable[newTeam]["NameChangeFuncBig"](" " .. newTeam.Name .. " (" .. tostring(#teamTable[newTeam].Players) ..")") + end + end + end + end + + if newTeam == "Neutral" then + updatePlayerNameColor(player, nil) + else + updatePlayerNameColor(player, player.TeamColor) + end + + playerTable[player].LastTeam = newTeam + + recomputeCompleteTeamScore(newTeam) + + --Relayout + if sortPlayerListsFunction then + sortPlayerListsFunction() + end + end + end + + local function buildTeamObject(team, numStatColumns, suffix) + local isTeam, isScore = getBoardTypeInfo() + local teamObject, changeFunc = createTeamName(team.Name, team.TeamColor) + teamObject.NameLabel.Text = " " .. team.Name .. " (0)" + if not teamTable[team] then + teamTable[team] = {} + end + teamTable[team]["NameObject" .. suffix] = teamObject + teamTable[team]["NameChangeFunc" .. suffix] = changeFunc + if isScore then + local statObject + local textChangers + teamObject, statObject, textChangers = createStatColumns(teamObject, numStatColumns, true, suffix == "Big") + teamTable[team]["StatObject" .. suffix] = statObject + teamTable[team]["StatChangers" .. suffix] = textChangers + end + teamTable[team]["MainObject" .. suffix] = teamObject + changeFunc(" " .. team.Name) + if not teamTable[team].Players then + teamTable[team].Players = {} + else + if suffix ~= "Small" and #teamTable[team].Players > 0 then + changeFunc(" " .. team.Name .. " (" .. tostring(#teamTable[team].Players) ..")") + end + end + + return teamObject + end + + local currentContextMenuPlayer = nil + local function updatePlayerContextMenu(player,x,y) + currentContextMenuPlayer = player + local elementHeight = 18 + local function highlight(button) + button.TextColor3 = Color3.new(0,0,0) + button.BackgroundColor3 = Color3.new(0.8,0.8,0.8) + end + local function clearHighlight(button) + button.TextColor3 = Color3.new(1,1,1) + button.BackgroundColor3 = Color3.new(0,0,0) + end + if playerContextMenu == nil then + elementNames = {} + elementNameToElement = {} + + for i, contextElement in ipairs(contextMenuElements) do + table.insert(elementNames, contextElement.Text) + elementNameToElement[tostring(contextElement.Text)] = contextElement + end + + playerContextMenu = Instance.new("TextButton") + playerContextMenu.Name = "PlayerListContextMenu" + playerContextMenu.Style = Enum.ButtonStyle.RobloxButton + playerContextMenu.Text = "" + playerContextMenu.Visible = false + playerContextMenu.ZIndex = 4 + + playerContextMenu.MouseLeave:connect(function() + local menuChildren = playerContextMenu:GetChildren() + for i = 1, #menuChildren do + if menuChildren[i].Name == "ChoiceButton" then + menuChildren[i].TextColor3 = Color3.new(1,1,1) + menuChildren[i].BackgroundTransparency = 1 + end + end + playerContextMenu.Visible = false + inContextMenu = false + end) + + playerContextMenu.MouseEnter:connect(function() + inContextMenu = true + end) + + for i = 1, #elementNames do + local newElementButton = Instance.new("TextButton") + newElementButton.Name = "ChoiceButton" + newElementButton.Text = elementNames[i] + newElementButton.TextColor3 = Color3.new(1,1,1) + newElementButton.Font = Enum.Font.Arial + newElementButton.FontSize = Enum.FontSize.Size14 + newElementButton.BackgroundTransparency = 1 + newElementButton.TextWrap = true + newElementButton.Size = UDim2.new(1,0,0,elementHeight) + newElementButton.Position = UDim2.new(0,0,0,elementHeight * (i - 1)) + newElementButton.ZIndex = playerContextMenu.ZIndex + 1 + + newElementButton.MouseEnter:connect(function() + newElementButton.TextColor3 = Color3.new(0,0,0) + newElementButton.BackgroundTransparency = 0 + end) + + newElementButton.MouseLeave:connect(function() + newElementButton.TextColor3 = Color3.new(1,1,1) + newElementButton.BackgroundTransparency = 1 + end) + + newElementButton.MouseButton1Click:connect(function() + local element = elementNameToElement[newElementButton.Text] + pcall(function() element.DoIt(currentContextMenuPlayer) end) + playerContextMenu.Visible = false + newElementButton.TextColor3 = Color3.new(1,1,1) + newElementButton.BackgroundTransparency = 1 + end) + + newElementButton.Parent = playerContextMenu + end + + robloxLock(playerContextMenu) + playerContextMenu.Parent = script.Parent + + end + + local visibleElements = 0 + for i, contextElement in ipairs(contextMenuElements) do + local isVisible = false + + if contextElement.IsVisible then + local success, visible = pcall(function() return contextElement.IsVisible(currentContextMenuPlayer) end) + if success then + isVisible = visible + else + print("Error in IsVisible call: " .. visible) + end + end + + if isVisible then + local foundElement = false + for i = 1, #elementNames do + if elementNames[i] == contextElement.Text then + foundElement = true + break + end + end + if not foundElement then + table.insert(elementNames,contextElement.Text) + end + visibleElements = visibleElements + 1 + else + for i = 1, #elementNames do + if elementNames[i] == contextElement.Text then + table.remove(elementNames,i) + break + end + end + end + end + playerContextMenu.Size = UDim2.new(0, 150, 0, elementHeight + (elementHeight * visibleElements) ) + + if x and y then + x = x - (playerContextMenu.AbsoluteSize.X/2) + if x + playerContextMenu.AbsoluteSize.X >= script.Parent.AbsoluteSize.X then + x = script.Parent.AbsoluteSize.X - playerContextMenu.AbsoluteSize.X + end + playerContextMenu.Position = UDim2.new(0, x, 0, y - 3) + end + + local elementPos = 0 + local contextChildren = playerContextMenu:GetChildren() + for i = 1, #contextChildren do + if contextChildren[i]:IsA("GuiObject") and contextChildren[i].Name == "ChoiceButton" then + contextChildren[i].Visible = false + for j = 1, #elementNames do + if elementNames[j] == contextChildren[i].Text then + contextChildren[i].Visible = true + contextChildren[i].Position = UDim2.new(0,0,0,elementPos * elementHeight) + elementPos = elementPos + 1 + break + end + end + end + end + end + + local function playerContextMenuHasItems() + if playerContextMenu then + local children = playerContextMenu:GetChildren() + for i = 1, #children do + if children[i]:IsA("GuiObject") and children[i].Name == "ChoiceButton" and children[i].Visible then + return true + end + end + end + return false + end + + local function showPlayerMenu(player, x, y) + updatePlayerContextMenu(player,x,y) + if not playerContextMenuHasItems() then return end -- don't show if we have nothing to show + playerContextMenu.Visible = true + end + + local function buildPlayerObject(player, numStatColumns, suffix) + if not player then return nil end + + local isTeam, isScore = getBoardTypeInfo() + + local playerObject = nil + local changePlayerNameFunction = nil + local currentColor = nil + if isTeam and not player.Neutral then + currentColor = player.TeamColor.Color + else + currentColor = Color3.new(1,1,1) + end + playerObject, changePlayerNameFunction = createPlayerName(player.Name, player.MembershipType, currentColor, getFriendStatus(player)) + + if not playerTable[player] then + playerTable[player] = {} + end + if not playerTable[player].Connections then + playerTable[player].Connections = {} + end + if not playerTable[player].CurrentTeam then + playerTable[player].CurrentTeam = nil + end + if not playerTable[player].LastTeam then + playerTable[player].LastTeam = nil + end + playerTable[player]["NameObject" .. suffix] = playerObject + playerTable[player]["ChangeName" .. suffix] = changePlayerNameFunction + + if isScore then + local statObject = nil + local textChangers = nil + playerObject, statObject, textChangers = createStatColumns(playerObject, numStatColumns, false, suffix == "Big") + playerTable[player]["StatObject" .. suffix]= statObject + playerTable[player]["StatChangers" .. suffix] = textChangers + + local statValues, leaderstats = getStatValuesForPlayer(player) + if not statValues or #statValues < numStatColumns then + if not playerTable[player].LeaderStatConnections then + playerTable[player].LeaderStatConnections = {} + end + --Setup a listener to see when this data gets filled in + if not leaderstats then + --We don't even have a leaderstats child, wait for one + table.insert(playerTable[player].LeaderStatConnections, + player.ChildAdded:connect( + function(child) + if child.Name == "leaderstats" then + --Connections will be torn down + recreatePlayerFunction(player) + else + table.insert(playerTable[player].LeaderStatConnections, + child.Changed:connect( + function(prop) + if prop == "Name" and child.Name == "leaderstats" then + --Connections will be torn down + recreatePlayerFunction(player) + end + end)) + end + end)) + else + --We have a leaderstats, but not enough children, recreate if we get them + table.insert(playerTable[player].LeaderStatConnections, + leaderstats.ChildAdded:connect( + function(child) + --TODO only look for IntValue + recreatePlayerFunction(player) + end) + ) + table.insert(playerTable[player].LeaderStatConnections, + leaderstats.AncestryChanged:connect( + function(child) + --We got deleted, try again + recreatePlayerFunction(player) + end) + ) + end + end + if statValues then + if not playerTable[player].StatValues then + playerTable[player].StatValues = {} + end + local pos = 1 + while pos <= numStatColumns and pos <= #statValues do + local currentColumn = pos + local statValue = statValues[pos] + local statChanger = textChangers[pos] + + local updateStat = function(val) + statChanger(val) + if playerTable[player] ~= nil then recomputeTeamScore(playerTable[player].CurrentTeam, currentColumn) end + end + if pos > #playerTable[player].StatValues then + table.insert(playerTable[player].StatValues, statValue) + end + + if type(statValue) ~= "number" and statValue["Changed"] then + table.insert(playerTable[player].Connections, + statValue.Changed:connect(updateStat) + ) + end + + table.insert(playerTable[player].Connections, + statValue.AncestryChanged:connect( + function() + recreatePlayerFunction(player) + end) + ) + updateStat(statValue.Value) + pos = pos + 1 + end + end + end + + if supportFriends and player ~= game.Players.LocalPlayer and player.userId > 0 and game.Players.LocalPlayer.userId > 0 then + local button = Instance.new("TextButton") + button.Name = playerObject.Name .. "Button" + button.Text = "" + button.Active = false + button.Size = playerObject.Size + button.Position = playerObject.Position + button.BackgroundColor3 = playerObject.BackgroundColor3 + + local secondButton = Instance.new("TextButton") + secondButton.Name = playerObject.Name .. "RealButton" + secondButton.Text = "" + secondButton.BackgroundTransparency = 1 + secondButton.BackgroundColor3 = playerObject.BackgroundColor3 + local theNameLabel = playerObject:findFirstChild("NameLabel",true) + secondButton.Parent.BackgroundTransparency = 1 + secondButton.Parent.Visible = true + secondButton.ZIndex = 2 + secondButton.Size = UDim2.new(1,0,1,0) + + local previousTransparency = nil + table.insert(playerTable[player].Connections, + secondButton.MouseEnter:connect( + function(x,y) + if playerContextMenu and playerContextMenu.Visible then + return + end -- don't update if we currently see it + + updatePlayerContextMenu(player,x,y) + if not playerContextMenuHasItems() then return end -- don't show if we have nothing to show + + if previousTransparency == nil then + previousTransparency = secondButton.BackgroundTransparency + end + secondButton.Parent.BackgroundTransparency = 0 + end)) + table.insert(playerTable[player].Connections, + secondButton.MouseLeave:connect( + function() + if previousTransparency ~= nil then + previousTransparency = nil + end + delay(0.01,function() + if playerContextMenu and not inContextMenu then + playerContextMenu.Visible = false + end + end) + secondButton.Parent.BackgroundTransparency = 1 + end)) + + local mouseDownX, mouseDownY + table.insert(playerTable[player].Connections, + secondButton.MouseButton1Down:connect(function(x,y) + mouseDownX = x + mouseDownY = y + end)) + table.insert(playerTable[player].Connections, + secondButton.MouseButton1Click:connect(function() + showPlayerMenu(player, mouseDownX, secondButton.AbsolutePosition.Y + secondButton.AbsoluteSize.Y ) + end)) + playerObject.BackgroundTransparency = 1 + playerObject.Size = UDim2.new(1,0,1,0) + playerObject.Position = UDim2.new(0,0,0,0) + playerObject.Parent = button + + playerTable[player]["MainObject" .. suffix] = button + + playerObject = button + else + playerTable[player]["MainObject" .. suffix] = playerObject + + if player == game.Players.LocalPlayer and supportFriends then + table.insert(playerTable[player].Connections, + player.FriendStatusChanged:connect( + function(otherPlayer, friendStatus) + if friendRequestBlacklist[otherPlayer] then + updatePlayerFriendStatus(playerTable[otherPlayer]["NameObject" .. suffix], Enum.FriendStatus.NotFriend) + elseif playerTable[otherPlayer] then + updatePlayerFriendStatus(playerTable[otherPlayer]["NameObject" .. suffix], friendStatus) + end + end) + ) + end + end + table.insert(playerTable[player].Connections, + player.Changed:connect( + function(prop) + if prop == "MembershipType" then + updatePlayerName(playerTable[player]["NameObject" .. suffix], player.MembershipType, currentColor) + elseif prop == "Name" then + playerTable[player]["ChangeName" .. suffix](player.Name) + elseif prop == "Neutral" or prop == "TeamColor" then + assignToTeam(player) + end + end) + ) + return playerObject + end + + local function doSort(tableToSort, objectName, order, startPos, sortType, ascending) + local orderedPlayerTable = {} + getLocalPlayer = false + for i, player in ipairs(tableToSort) do + if playerTable[player] then + if playerTable[player][objectName] ~= nil then + if player ~= game.Players.LocalPlayer then + table.insert(orderedPlayerTable,playerTable[player][objectName]) + else + getLocalPlayer = true + end + end + end + end + + if sortType == nil then -- default back to alphabetical sort + table.sort(orderedPlayerTable,function(a,b) + return string.lower(a:FindFirstChild("FullNameLabel",true).Text) < string.lower(b:FindFirstChild("FullNameLabel",true).Text) + end) + else -- we are sorting by a value + table.sort(orderedPlayerTable,function(a,b) + if ascending then + currentSortName = "" + return tonumber(a:FindFirstChild(sortType,true).Text) > tonumber(b:FindFirstChild(sortType,true).Text) + else + currentSortName = sortType + return tonumber(a:FindFirstChild(sortType,true).Text) < tonumber(b:FindFirstChild(sortType,true).Text) + end + end) + end + if getLocalPlayer and playerTable[game.Players.LocalPlayer] and playerTable[game.Players.LocalPlayer][objectName] then + table.insert(orderedPlayerTable,1,playerTable[game.Players.LocalPlayer][objectName]) + end + for i = 1, #orderedPlayerTable do + order[orderedPlayerTable[i]] = startPos + startPos = startPos + 1 + end + + return startPos + end + + local function orderScrollList(scrollOrder, objectName, scrollFrame, sortType, ascending) + local pos = 0 + local order = {} + local isTeam, isScore = getBoardTypeInfo() + for i, obj in ipairs(scrollOrder) do + order[obj] = 0 + end + + if isTeam then + local teams = getTeams() + for i, team in ipairs(teams) do + if teamTable[team][objectName] then + order[teamTable[team][objectName]] = pos + pos = pos + 1 + end + pos = doSort(teamTable[team].Players, objectName, order, pos, sortType, ascending) + end + + if #teamTable["Neutral"].Players > 0 then + teamTable["Neutral"][objectName].Parent = scrollFrame + order[teamTable["Neutral"][objectName]] = pos + pos = pos + 1 + doSort(teamTable["Neutral"].Players, objectName, order, pos, sortType, ascending) + else + teamTable["Neutral"][objectName].Parent = nil + end + else + local players = getPlayers() + doSort(players, objectName, order, pos, sortType, ascending) + end + + table.sort(scrollOrder, + function(a,b) + return order[a] < order[b] + end) + end + + local function createPlayerListBasics(frame, isBig) + local headerFrame = Instance.new("Frame") + headerFrame.Name = "Header" + headerFrame.BackgroundTransparency = 1 + headerFrame.Size = UDim2.new(1,-13,0,26) + headerFrame.Position = UDim2.new(0,0,0,0) + headerFrame.Parent = frame + + local lowerPaneFrame = Instance.new("Frame") + lowerPaneFrame.Name = "ScrollingArea" + lowerPaneFrame.BackgroundTransparency = 1 + lowerPaneFrame.Size = UDim2.new(1,-3,1,-26) + if not isBig then lowerPaneFrame.Size = UDim2.new(1,-3,1,-30) end + lowerPaneFrame.Position = UDim2.new(0,0,0,26) + lowerPaneFrame.Parent = frame + + local scrollOrder = {} + local scrollFrame, scrollUp, scrollDown, recalculateScroll, scrollBar = RbxGui.CreateScrollingFrame(scrollOrder) + + scrollBar.Size = UDim2.new(0, 17, 1, -36) + if isBig then scrollBar.Size = UDim2.new(0, 17, 1, -61) end + scrollBar.Parent = lowerPaneFrame + + scrollFrame.Parent = lowerPaneFrame + scrollUp.Parent = lowerPaneFrame + scrollDown.Parent = lowerPaneFrame + + if isBig then + scrollFrame.Position = UDim2.new(0,0,0,0) + scrollUp.Position = UDim2.new(1,-41,0,5) + scrollDown.Position = UDim2.new(1,-41,1,-35) + scrollBar.Position = UDim2.new(1, -41, 0, 24) + + scrollFrame.Size = UDim2.new(1,-48,1,-16) + headerFrame.Size = UDim2.new(1,-20,0,26) + + else + scrollBar.Position = UDim2.new(1, -15, 0, 14) + scrollBar.Size = UDim2.new(0,17,1,-36) + scrollFrame.Position = UDim2.new(0,1,0,0) + scrollUp.Position = UDim2.new(1,-15,0,-5) + scrollDown.Position = UDim2.new(1,-15,1,-20) + + lowerPaneFrame.Position = UDim2.new(0,0,0,30) + + local toggleScrollBar = function(visible) + if visible then + scrollFrame.Size = UDim2.new(1,-16,1,0) + headerFrame.Size = UDim2.new(1,-16,0,smallWindowHeaderYSize) + else + scrollFrame.Size = UDim2.new(1,0,1,0) + headerFrame.Size = UDim2.new(1,0,0,smallWindowHeaderYSize) + end + scrollUp.Visible = visible + scrollDown.Visible = visible + scrollBar.Visible = visible + end + scrollUp.Changed:connect(function(prop) + if prop == "Active" then + toggleScrollBar(scrollUp.Active or scrollDown.Active) + end + end) + + scrollDown.Changed:connect(function(prop) + if prop == "Active" then + toggleScrollBar(scrollUp.Active or scrollDown.Active) + end + end) + + toggleScrollBar(scrollUp.Active or scrollDown.Active) + end + return headerFrame, scrollFrame, recalculateScroll, scrollOrder + end + + createBoardsFunction = function (boardType, numStatColumns) + local updatePlayerCount = function() + return #getPlayers() + end + + local smallFrame = Instance.new("Frame") + smallFrame.Name = "SmallPlayerlist" + smallFrame.Position = smallWindowPosition + smallFrame.Active = false + smallFrame.Size = smallWindowSize + smallFrame.BackgroundColor3 = Color3.new(0,0,0) + smallFrame.BackgroundTransparency = 0.7 + smallFrame.BorderSizePixel = 0 + + local bigFrame = Instance.new("Frame") + bigFrame.Name = "BigPlayerlist" + bigFrame.Size = bigWindowSize + bigFrame.Position = bigWindowPosition + bigFrame.BackgroundColor3 = Color3.new(0,0,0) + bigFrame.BackgroundTransparency = 0.7 + bigFrame.BorderSizePixel = 0 + bigFrame.Visible = false + + local bigFrameWrapper = Instance.new("Frame") + bigFrameWrapper.Name = "Expander" + bigFrameWrapper.Size = UDim2.new(1,21,1,16) + bigFrameWrapper.Position = UDim2.new(0, 0, 0,0) + bigFrameWrapper.BackgroundTransparency = 1 + bigFrameWrapper.Parent = bigFrame + + local smallHeaderFrame, scrollFrameSmall, recalculateScrollSmall, scrollOrderSmall = createPlayerListBasics(smallFrame, false) + local bigHeaderFrame, scrollFrameBig, recalculateScrollBig, scrollOrderBig = createPlayerListBasics(bigFrameWrapper, true) + + local playerListButton = Instance.new("ImageButton") + playerListButton.Name = "GoBigButton" + playerListButton.BackgroundTransparency = 1 + playerListButton.Image = "rbxasset://textures/ui/playerlist_small_maximize.png" + playerListButton.Size = UDim2.new(0.0, 35, 0, 29) + playerListButton.Position = UDim2.new(0, 0, 0, 0) + playerListButton.MouseButton1Click:connect( + function() + toggleBigWindow() + end) + playerListButton.Parent = smallHeaderFrame + + playerListButton = Instance.new("ImageButton") + playerListButton.Name = "CloseButton" + playerListButton.BackgroundTransparency = 1 + playerListButton.Image = "rbxasset://textures/ui/playerlist_small_hide.png" + playerListButton.Size = UDim2.new(0.0, 38, 0, 29) + playerListButton.Position = UDim2.new(0, 35, 0, 0) + playerListButton.MouseButton1Click:connect( + function() + transitionWindowsFunction("None") + end) + playerListButton.Parent = smallHeaderFrame + + playerListButton = Instance.new("ImageButton") + playerListButton.Name = "CloseButton" + playerListButton.Image = "rbxasset://textures/ui/playerlist_big_hide.png" + playerListButton.BackgroundTransparency = 1 + playerListButton.Size = UDim2.new(0.0, 29, 0, 29) + playerListButton.Position = UDim2.new(1, -30, 0.5, -13) + playerListButton.MouseButton1Click:connect( + function() + toggleBigWindow() + end) + playerListButton.Parent = bigHeaderFrame + + local placeName = Instance.new("TextButton") + placeName.Name = "PlaceName" + placeName.Text = " Players (" .. tostring(updatePlayerCount()) .. ")" + placeName.AutoButtonColor = false + placeName.FontSize = Enum.FontSize.Size24 + placeName.TextXAlignment = Enum.TextXAlignment.Left + placeName.Font = Enum.Font.ArialBold + placeName.BorderSizePixel = 0 + placeName.BackgroundColor3 = Color3.new(0,0,0) + placeName.BackgroundTransparency = 1 + placeName.TextColor3 = Color3.new(1,1,1) + placeName.Size = UDim2.new(0.4, 0, 1, 0) + placeName.Position = UDim2.new(0, 0, 0.0, 0) + placeName = RbxGui.AutoTruncateTextObject(placeName) + placeName.Parent = bigHeaderFrame + + placeName.MouseEnter:connect(function() + placeName.BackgroundTransparency = 0.2 + end) + + placeName.MouseLeave:connect(function() + placeName.BackgroundTransparency = 1 + end) + + placeName.MouseButton1Click:connect(function() + sortPlayerListsFunction() + end) + + currentBoardType = boardType + currentStatCount = numStatColumns + local isTeam, isScore = getBoardTypeInfo() + local players = getPlayers() + + if isScore then + local statColumns = getStatColumns(players) + numStatColumns = #statColumns + if numStatColumns > 3 then + numStatColumns = 3 + end + createStatHeaders(statColumns, numStatColumns, false).Parent = smallHeaderFrame + createStatHeaders(statColumns, currentStatCount, true).Parent = bigHeaderFrame + end + + --Clean up all old stuff + resetPlayerTable() + updatePlayerCount() + + for i, player in ipairs(players) do + local playerObject = buildPlayerObject(player, numStatColumns, "Small") + table.insert(scrollOrderSmall, playerObject) + playerObject.Parent = scrollFrameSmall + + playerObject = buildPlayerObject(player, currentStatCount, "Big") + table.insert(scrollOrderBig, playerObject) + playerObject.Parent = scrollFrameBig + end + + --Clean up old stuff + resetTeamTable() + + local teamStatObjects = {} + if isTeam then + local teams = getTeams() + local i = #teams + while i >= 1 do + --We go backwards so the "first" team color gets the team + local team = teams[i] + teamColorTable[team.TeamColor.Name] = team + i = i - 1 + end + + --Adding/Removing a Team causes a full invalidation of the board + for i, team in ipairs(teams) do + local teamObject = buildTeamObject(team, numStatColumns, "Small") + table.insert(scrollOrderSmall, teamObject) + teamObject.Parent = scrollFrameSmall + + teamObject = buildTeamObject(team, currentStatCount, "Big") + table.insert(scrollOrderBig, teamObject) + teamObject.Parent = scrollFrameBig + end + + teamTable["Neutral"] = {} + teamTable["Neutral"].Players = {} + + local neutralTeamObject = createTeamName("Neutral", BrickColor.palette(8)) + teamTable["Neutral"].NameObjectSmall = neutralTeamObject + teamTable["Neutral"].StatObjectSmall = nil + teamTable["Neutral"].MainObjectSmall = neutralTeamObject + table.insert(scrollOrderSmall, neutralTeamObject) + + neutralTeamObject = createTeamName("Neutral", BrickColor.palette(8)) + teamTable["Neutral"].NameObjectBig = neutralTeamObject + teamTable["Neutral"].StatObjectBig = nil + teamTable["Neutral"].MainObjectBig = neutralTeamObject + table.insert(scrollOrderBig, neutralTeamObject) + + local neutralPlayers = {} + for i, player in ipairs(players) do + assignToTeam(player) + end + end + + removePlayerFunction = function(player) + if playerTable[player] then + clearTableEntry(player, playerTable[player]) + + placeName.Text = " Players (" .. tostring(updatePlayerCount()) .. ")" + + ArrayRemove(scrollOrderSmall, playerTable[player].MainObjectSmall) + ArrayRemove(scrollOrderBig, playerTable[player].MainObjectBig) + + playerTable[player] = nil + recalculateSmallPlayerListSize(smallFrame) + end + end + recreatePlayerFunction = function(player) + placeName.Text = " Players (" .. tostring(updatePlayerCount()) .. ")" + + removePlayerFunction(player) + + local playerObject = buildPlayerObject(player, numStatColumns, "Small") + table.insert(scrollOrderSmall, playerObject) + robloxLock(playerObject) + playerObject.Parent = scrollFrameSmall + + playerObject = buildPlayerObject(player, currentStatCount, "Big") + table.insert(scrollOrderBig, playerObject) + robloxLock(playerObject) + playerObject.Parent = scrollFrameBig + + local isTeam, isScore = getBoardTypeInfo() + if isTeam then + assignToTeam(player) + end + + sortPlayerListsFunction() + recalculateSmallPlayerListSize(smallFrame) + end + + if screenResizeCon then screenResizeCon:disconnect() end + screenResizeCon = screen.Changed:connect( + function(prop) + if prop == "AbsoluteSize" then + wait() + recalculateSmallPlayerListSize(smallFrame) + end + end) + + sortPlayerListsFunction = function(sortType, ascending) + orderScrollList(scrollOrderSmall, "MainObjectSmall", scrollFrameSmall, sortType, ascending) + recalculateScrollSmall() + createAlternatingRows(scrollOrderSmall) + + orderScrollList(scrollOrderBig, "MainObjectBig", scrollFrameBig, sortType, ascending) + recalculateScrollBig() + createAlternatingRows(scrollOrderBig) + end + + sortPlayerListsFunction() + + robloxLock(smallFrame) + robloxLock(bigFrame) + return smallFrame, bigFrame + end + + --Teams changing invalidates the whole board + local function teamsChanged() + if debounceTeamsChanged then + return + end + + debounceTeamsChanged = true + wait() + rebuildBoard(script.Parent, determineBoardType()) + debounceTeamsChanged = false + end + + + local checkIfBoardChanged = function() + local newBoardType, numStats = determineBoardType() + if newBoardType ~= currentBoardType or numStats ~= currentStatCount then + rebuildBoard(script.Parent, newBoardType, numStats) + end + end + + local function buildPlayerList() + waitForChild(game, "Players") + waitForProperty(game.Players, "LocalPlayer") + + local teams = game:GetService("Teams") + if teams then + local teamConnections = {} + + teams.ChildAdded:connect( + function(child) + if child:IsA("Team") then + teamsChanged() + teamConnections[child] = child.Changed:connect( + function(prop) + if prop == "TeamColor" or prop == "Name" then + --Rebuild when things change + teamsChanged() + end + end) + end + end) + teams.ChildRemoved:connect( + function(child) + if child:IsA("Team") then + if teamConnections[child] then + teamConnections[child]:disconnect() + teamConnections[child] = nil + end + teamsChanged() + end + end) + end + + game.Players.ChildAdded:connect( + function(player) + if player:IsA("Player") then + addPlayerFunction(player) + end + end) + + game.Players.ChildRemoved:connect( + function(player) + if player:IsA("Player") then + if removePlayerFunction then + removePlayerFunction(player) + end + end + end) + + rebuildBoard(script.Parent, determineBoardType()) + + delay(0, + function() + while true do + wait(5) + checkIfBoardChanged() + end + end) + end + + buildPlayerList() +end + +if not personalServerPlace then -- one more backup check + local theBool = game.Workspace:FindFirstChild("PSVariable") + if theBool and theBool:IsA("BoolValue") then + personalServerPlace = true + end +end + +if personalServerPlace then + addPersonalServerContext() + setupBuildToolManagement() +else + local psVarCon = nil + psVarCon = game.Workspace.ChildAdded:connect(function(child) + if child:IsA("BoolValue") and child.Name == "PSVariable" then + psVarCon:disconnect() + personalServerPlace = true + addPersonalServerContext() + setupBuildToolManagement() + end + end) +end + true + + + + + \ No newline at end of file diff --git a/clients/2011M/content/fonts/rightarm.mesh b/clients/2011M/content/fonts/rightarm.mesh new file mode 100644 index 0000000..14a52a4 Binary files /dev/null and b/clients/2011M/content/fonts/rightarm.mesh differ diff --git a/clients/2011M/content/fonts/rightleg.mesh b/clients/2011M/content/fonts/rightleg.mesh new file mode 100644 index 0000000..dab065d Binary files /dev/null and b/clients/2011M/content/fonts/rightleg.mesh differ diff --git a/clients/2011M/content/fonts/safechat.xml b/clients/2011M/content/fonts/safechat.xml new file mode 100644 index 0000000..199e3b2 --- /dev/null +++ b/clients/2011M/content/fonts/safechat.xml @@ -0,0 +1,737 @@ + + null + nil + Use the Chat menu to talk to me. + I can only see menu chats. + + Hello + + Hi + Hi there! + Hi everyone + + + Howdy + Howdy partner! + + + Greetings + Greetings everyone + Greetings Robloxians! + Seasons greetings! + + + Welcome + Welcome to my place + Welcome to our base + Welcome to my barbeque + + Hey there! + + What's up? + How are you doing? + How's it going? + What's new? + + + Good day + Good morning + Good afternoon + Good evening + Good night + + + Silly + Waaaaaaaz up?! + Hullo! + Behold greatness, mortals! + Pardon me, is this Sparta? + THIS IS SPARTAAAA! + + + Happy Holidays! + Happy New Year! + Happy Valentine's Day! + Beware the Ides of March! + Happy St. Patrick's Day! + Happy Easter! + Happy Earth Day! + Happy 4th of July! + Happy Thanksgiving! + Happy Halloween! + Happy Hanukkah! + Merry Christmas! + Happy Halloween! + Happy Earth Day! + Happy May Day! + Happy Towel Day! + Happy ROBLOX Day! + Happy LOL Day! + + + + Goodbye + + Good Night + Sweet dreams + Go to sleep! + Lights out! + Bedtime + Going to bed now + + + Later + See ya later + Later gator! + See you tomorrow + + + Bye + Hasta la bye bye! + + I'll be right back + I have to go + + Farewell + Take care + Have a nice day + Goodluck! + Ta-ta for now! + + + Peace + Peace out! + Peace dudes! + Rest in pieces! + + + Silly + To the batcave! + Over and out! + Happy trails! + I've got to book it! + Tootles! + Smell you later! + GG! + My house is on fire! gtg. + + + + Friend + Wanna be friends? + + Follow me + Come to my place! + Come to my base! + Follow me, team! + Follow me + + + Your place is cool + Your place is fun + Your place is awesome + Your place looks good + This place is awesome! + + + Thank you + Thanks for playing + Thanks for visiting + Thanks for everything + No, thank you + Thanx + + + No problem + Don't worry + That's ok + np + + + You are ... + You are great! + You are good! + You are cool! + You are funny! + You are silly! + You are awesome! + You are doing something I don't like, please stop + + + I like ... + I like your name + I like your shirt + I like your place + I like your style + I like you + I like items + I like money + + + Sorry + My bad! + I'm sorry + Whoops! + Please forgive me. + I forgive you. + I didn't mean to do that. + Sorry, I'll stop now. + + + + Questions + + Who? + Who wants to be my friend? + Who wants to be on my team? + Who made this brilliant game? + LOLWHO? + + + What? + What is your favorite animal? + What is your favorite game? + What is your favorite movie? + What is your favorite TV show? + What is your favorite music? + What are your hobbies? + LOLWUT? + + + When? + When are you online? + When is the new version coming out? + When can we play again? + When will your place be done? + + + Where? + Where do you want to go? + Where are you going? + Where am I?! + Where did you go? + + + How? + How are you today? + How did you make this cool place? + LOLHOW? + + + Can I... + Can I have a tour? + Can I be on your team? + Can I be your friend? + Can I try something? + Can I have that please? + Can I have that back please? + Can I have borrow your hat? + Can I have borrow your gear? + + + + Answers + + You need help? + Check out the news section + Check out the help section + Read the wiki! + All the answers are in the wiki! + I will help you with this. + + + Some people ... + Me + Not me + You + All of us + Everyone but you + Builderman! + Telamon! + My team + My group + Mom + Dad + Sister + Brother + Cousin + Grandparent + Friend + + + Time ... + In the morning + In the afternoon + At night + Tomorrow + This week + This month + Sometime + Sometimes + Whenever you want + Never + After this + In 10 minutes + In a couple hours + In a couple days + + + Animals + + Cats + Lion + Tiger + Leopard + Cheetah + + + Dogs + Wolves + Beagle + Collie + Dalmatian + Poodle + Spaniel + Shepherd + Terrier + Retriever + + + Horses + Ponies + Stallions + Pwnyz + + + Reptiles + Dinosaurs + Lizards + Snakes + Turtles! + + Hamster + Monkey + Bears + + Fish + Goldfish + Sharks + Sea Bass + Halibut + Tropical Fish + + + Birds + Eagles + Penguins + Parakeets + Owls + Hawks + Pidgeons + + Elephants + + Mythical Beasts + Dragons + Unicorns + Sea Serpents + Sphinx + Cyclops + Minotaurs + Goblins + Honest Politicians + Ghosts + Scylla and Charybdis + + + + Games + + Roblox + BrickBattle + Community Building + Roblox Minigames + Contest Place + + Action + Puzzle + Strategy + Racing + RPG + Obstacle Course + Tycoon + + Board games + Chess + Checkers + Settlers of Catan + Tigris and Euphrates + El Grande + Stratego + Carcassonne + + + + Sports + Hockey + Soccer + Football + Baseball + Basketball + Volleyball + Tennis + Sports team practice + + Watersports + Surfing + Swimming + Water Polo + + + Winter sports + Skiing + Snowboarding + Sledding + Skating + + + Adventure + Rock climbing + Hiking + Fishing + Horseback riding + + + Wacky + Foosball + Calvinball + Croquet + Cricket + Dodgeball + Squash + Trampoline + + + + Movies/TV + Science Fiction + + Animated + Anime + + Comedy + Romantic + Action + Fantasy + + + Music + Country + Jazz + Rap + Hip-hop + Techno + Classical + Pop + Rock + + + Hobbies + + Computers + Building computers + Videogames + Coding + Hacking + + + The Internet + lol. teh internets! + Watching vids + + Dance + Gymnastics + + Martial Arts + Karate + Judo + Taikwon Do + Wushu + Street fighting + + Listening to music + + Music lessons + Playing in my band + Playing piano + Playing guitar + Playing violin + Playing drums + Playing a weird instrument + + Arts and crafts + + + Location + + USA + + West + Alaska + Arizona + California + Colorado + Hawaii + Idaho + Montana + Nevada + New Mexico + Oregon + Utah + Washington + Wyoming + + + Midwest + Illinois + Indiana + Iowa + Kansas + Michigan + Minnesota + Missouri + Nebraska + North Dakota + Ohio + South Dakota + Wisconsin + + + Northeast + Connecticut + Delaware + Maine + Maryland + Massachusetts + New Hampshire + New Jersey + New York + Pennsylvania + Rhode Island + Vermont + + + South + Alabama + Arkansas + Florida + Georgia + Kentucky + Louisiana + Mississippi + North Carolina + Oklahoma + South Carolina + Tennessee + Texas + Virginia + West Virginia + + + + Canada + Alberta + British Columbia + Manitoba + New Brunswick + Newfoundland + Northwest Territories + Nova Scotia + Nunavut + Ontario + Prince Edward Island + Quebec + Saskatchewan + Yukon + + Mexico + Central America + + Europe + + Great Britain + England + Scotland + Wales + Northern Ireland + + France + Germany + Spain + Italy + Poland + Switzerland + Greece + Romania + Netherlands + + + Asia + China + India + Japan + Korea + Russia + Vietnam + + + South America + Argentina + Brazil + + + Africa + Eygpt + Swaziland + + Australia + Middle East + Antarctica + New Zealand + + + Age + Rugrat + Kid + Tween + Teen + Twenties + Old + Ancient + Mesozoic + I don't want to say my age. Don't ask. + + + Mood + Good + Great! + Not bad + Sad + Hyper + Chill + Happy + Kind of mad + + Boy + Girl + I don't want to say boy or girl. Don't ask. + + + Game + Let's build + Let's battle + Nice one! + So far so good! + Lucky shot! + Oh man! + I challenge you to a fight! + Help me with this + Let's go to your game + Can you show me how do to that? + Backflip! + Frontflip! + Dance! + I'm on your side! + + Game Commands + regen + reset + go + fix + respawn + + + + Silly + Muahahahaha! + all your base are belong to me! + GET OFF MAH LAWN + TEH EPIK DUCK IS COMING!!! + ROFL + + 1337 + i r teh pwnz0r! + w00t! + z0mg h4x! + ub3rR0xXorzage! + + + + Yes + Absolutely! + Rock on! + Totally! + Juice! + Yay! + Yesh + + + No + Ummm. No. + ... + Stop! + Go away! + Don't do that + Stop breaking the rules + I don't want to + + + Ok + Well... ok + Sure + + + Uncertain + Maybe + I don't know + idk + I can't decide + Hmm... + + + + :-) + :-( + :D + :-O + lol + =D + D= + XD + ;D + ;) + O_O + =) + @_@ + >_< + T_T + ^_^ + <(0_0<) <(0_0)> (>0_0)> KIRBY DANCE + )'; + :3 + + + Ratings + Rate it! + I give it a 1 out of 10 + I give it a 2 out of 10 + I give it a 3 out of 10 + I give it a 4 out of 10 + I give it a 5 out of 10 + I give it a 6 out of 10 + I give it a 7 out of 10 + I give it a 8 out of 10 + I give it a 9 out of 10 + I give it a 10 out of 10! + + diff --git a/clients/2011M/content/fonts/torso.mesh b/clients/2011M/content/fonts/torso.mesh new file mode 100644 index 0000000..43d58d1 Binary files /dev/null and b/clients/2011M/content/fonts/torso.mesh differ diff --git a/clients/2011M/content/music/bass.wav b/clients/2011M/content/music/bass.wav new file mode 100644 index 0000000..5f4b791 Binary files /dev/null and b/clients/2011M/content/music/bass.wav differ diff --git a/clients/2011M/content/music/ufofly.wav b/clients/2011M/content/music/ufofly.wav new file mode 100644 index 0000000..359710b Binary files /dev/null and b/clients/2011M/content/music/ufofly.wav differ diff --git a/clients/2011M/content/particles/explosion.particle b/clients/2011M/content/particles/explosion.particle new file mode 100644 index 0000000..a7c5e1f --- /dev/null +++ b/clients/2011M/content/particles/explosion.particle @@ -0,0 +1,192 @@ +///////////////////////////////////////////////////////// +// The fast rising center plume of the explosion. +// Grows and rotates. +///////////////////////////////////////////////////////// +particle_system explosion/explosionPlume +{ + quota 40 + material explosion/explosionMatl + particle_width 6 + particle_height 6 + cull_each false + renderer billboard + billboard_type point + sorted false + local_space false + iteration_interval 0 + nonvisible_update_timeout 0 + billboard_type point + billboard_origin center + billboard_rotation_type vertex + common_up_vector 0 1 0 + point_rendering false + accurate_facing false + + emitter Ellipsoid + { + angle 16 + colour 1.0 0.4 0.2 1.0 + colour_range_start 1.0 0.4 0.2 1.0 + colour_range_end 0.7 0.2 0.1 0.6 + direction 0 1 0 + emission_rate 100 + position 0 6 0 + velocity 25 + velocity_min 25 + velocity_max 38 + time_to_live 1.5 + time_to_live_min 1.5 + time_to_live_max 1.5 + duration 0.2 + duration_min 0.2 + duration_max 0.2 + repeat_delay 10000 + repeat_delay_min 10000 + repeat_delay_max 10000 + width 3 + height 3 + depth 3 + } + + affector ColourFader + { + red -0.9 + green -0.5 + blue -0.3 + alpha -1.0 + } + affector Scaler + { + rate 13 + } + affector Rotator + { + rotation_speed_range_start 100 + rotation_speed_range_end 200 + rotation_range_start 100 + rotation_range_end 300 + } +} + + +///////////////////////////////////////////////////////// +//The slow moving base of the explosion. +///////////////////////////////////////////////////////// +particle_system explosion/explosionBase +{ + quota 40 + material explosion/explosionMatl + particle_width 20 + particle_height 20 + cull_each false + renderer billboard + billboard_type point + sorted false + local_space false + iteration_interval 0 + nonvisible_update_timeout 0 + billboard_type point + billboard_origin center + billboard_rotation_type vertex + common_up_vector 0 1 0 + point_rendering false + accurate_facing false + + emitter Ellipsoid + { + angle 100 + colour 1.0 0.4 0.2 1.0 + colour_range_start 1.0 0.4 0.2 1.0 + colour_range_end 0.7 0.2 0.1 0.6 + direction 0 1 0 + emission_rate 80 + position 0 0 0 + velocity 11 + velocity_min 11 + velocity_max 16 + time_to_live 1.5 + time_to_live_min 1.5 + time_to_live_max 1.5 + duration 0.2 + duration_min 0.2 + duration_max 0.2 + repeat_delay 10000 + repeat_delay_min 10000 + repeat_delay_max 10000 + width 15 + height 15 + depth 15 + } + + affector ColourFader + { + red -0.9 + green -0.5 + blue -0.3 + alpha -1.0 + } + affector Scaler + { + rate 5 + } +} + + +///////////////////////////////////////////////////////// +// The fast flying sparks of the explosion. +///////////////////////////////////////////////////////// +particle_system explosion/explosionSparks +{ + quota 120 + material explosion/explosparkMatl + particle_width 3 + particle_height 3 + cull_each false + renderer billboard + billboard_type point + sorted false + local_space false + iteration_interval 0 + nonvisible_update_timeout 0 + billboard_type point + billboard_origin center + billboard_rotation_type vertex + common_up_vector 0 1 0 + point_rendering false + accurate_facing false + + emitter Point + { + angle 120 + colour 1.0 0.6 0.4 1.0 + colour_range_start 1.0 0.6 0.4 1.0 + colour_range_end 1.0 0.6 0.4 1.0 + direction 0 1 0 + emission_rate 900 + position 0 0 0 + velocity 30 + velocity_min 30 + velocity_max 60 + time_to_live 1.2 + time_to_live_min 1.2 + time_to_live_max 1.2 + duration 0.2 + duration_min 0.1 + duration_max 0.1 + repeat_delay 10000 + repeat_delay_min 10000 + repeat_delay_max 10000 + } + + affector ColourFader + { + red -0.7 + green -0.6 + blue -0.4 + alpha -0.7 + } + affector Scaler + { + rate -3 + } +} diff --git a/clients/2011M/content/particles/explosionMat.material b/clients/2011M/content/particles/explosionMat.material new file mode 100644 index 0000000..8cce48d --- /dev/null +++ b/clients/2011M/content/particles/explosionMat.material @@ -0,0 +1,65 @@ + +///////////////////////////////////////////////////// +// Material used for bright explosion parts +///////////////////////////////////////////////////// +material explosion/explosionMatl +{ + technique + { + pass + { + lighting off + depth_write off + scene_blend add + + texture_unit + { + texture textures/explosion.png + } + } + } +} + +///////////////////////////////////////////////////// +// Bright sparks that fly out from explosions +///////////////////////////////////////////////////// +material explosion/explosparkMatl +{ + technique + { + pass + { + lighting off + depth_write off + scene_blend add + + texture_unit + { + texture textures/spark.png + } + } + } +} + + +/////////////////////////////////////////////////////////// +// Alpha blended smoke from explosions. +// Disabled because they overpower the bright explosion parts. +/////////////////////////////////////////////////////////// +material explosion/explosmokeMatl +{ + technique + { + pass + { + lighting off + depth_write off + scene_blend add + + texture_unit + { + texture textures/explosion.png + } + } + } +} \ No newline at end of file diff --git a/clients/2011M/content/particles/fire.particle b/clients/2011M/content/particles/fire.particle new file mode 100644 index 0000000..442fe8e --- /dev/null +++ b/clients/2011M/content/particles/fire.particle @@ -0,0 +1,59 @@ +///////////////////////////////////////////////////////// +// Fire +///////////////////////////////////////////////////////// + +// height and width modified by RbxParticleFactory for user input size +particle_system FireTemplate +{ + material fireMat1 + particle_width 5 + particle_height 5 + cull_each false + quota 40 + renderer billboard + billboard_type point + point_rendering false + accurate_facing false + sorted false + local_space false + iteration_interval 0 + nonvisible_update_timeout 0 + + // emission rate is modified by RbxParticleManager for throttling + // of particle systems + emitter Point + { + colour_range_start 240 240 240 + colour_range_end 240 240 240 + angle 18 + emission_rate 35 + time_to_live_min 1 + time_to_live_max 1 + direction 0 1 0 + velocity_min 2.33 + velocity_max 7.0 + } + affector Rotator + { + rotation_range_start 0 + rotation_range_end 365 + rotation_speed_range_start 0 + rotation_speed_range_end 100 + } + // modified in RbxParticleFactory for user input size + affector Scaler + { + rate -5.0 + } + // modified in RbxParticleFactory for user input colors + affector ColourInterpolator + { + time0 0 + colour0 240 240 240 1 + + time1 1 + colour1 240 240 240 1 + + } + +} diff --git a/clients/2011M/content/particles/fireMat.material b/clients/2011M/content/particles/fireMat.material new file mode 100644 index 0000000..f43bbd7 --- /dev/null +++ b/clients/2011M/content/particles/fireMat.material @@ -0,0 +1,22 @@ + +///////////////////////////////////////////////////// +// Material used for fire +///////////////////////////////////////////////////// +material fireMat1 +{ + technique + { + pass + { + lighting off + depth_write off + scene_blend add + + texture_unit + { + texture textures/fire_0.png + tex_address_mode clamp + } + } + } +} diff --git a/clients/2011M/content/particles/forceFieldBeam.particle b/clients/2011M/content/particles/forceFieldBeam.particle new file mode 100644 index 0000000..22914a9 --- /dev/null +++ b/clients/2011M/content/particles/forceFieldBeam.particle @@ -0,0 +1,55 @@ +///////////////////////////////////////////////////////// +// Beam +///////////////////////////////////////////////////////// +particle_system forceField/beam +{ + quota 40 + material PE/lensflare + particle_width 0.5 + particle_height 2 + cull_each false + billboard_type oriented_common + common_direction 0 1 0 + + emitter Ring + { + colour 1 1 1 0 + angle 0 + direction 0 1 0 + emission_rate 20 + position 0 -2 0 + velocity_min 2 + velocity_max 5 + time_to_live 2 + duration 0 + duration_min 0 + duration_max 0 + repeat_delay 0 + repeat_delay_min 0 + repeat_delay_max 0 + width 5 + height 5 + depth 1 + inner_width 0.8 + inner_height 0.8 + } + + //affector LinearForce +// { + // force_vector 0 -1 0 + // force_application add + //} + + affector ColourFader2 + { + red1 0 + green1 0 + blue1 0 + alpha1 1 + red2 0 + green2 0 + blue2 0 + alpha2 -1 + state_change 1 + } +} diff --git a/clients/2011M/content/particles/forceFieldRadial.particle b/clients/2011M/content/particles/forceFieldRadial.particle new file mode 100644 index 0000000..807f93d --- /dev/null +++ b/clients/2011M/content/particles/forceFieldRadial.particle @@ -0,0 +1,51 @@ +///////////////////////////////////////////////////////// +// Radial +///////////////////////////////////////////////////////// +particle_system forceField/radial +{ + material PE/lensflare + particle_width 5 + particle_height 5 + cull_each false + quota 6 + renderer billboard + billboard_type point + point_rendering false + accurate_facing false + sorted false + local_space false + iteration_interval 0 + nonvisible_update_timeout 0 + + // emission rate is modified by RbxParticleManager for throttling + // of particle systems + emitter Point + { + angle 18 + emission_rate 2 + time_to_live_min 2 + time_to_live_max 2 + direction 0 1 0 + velocity_min 0 + velocity_max 0.1 + } + affector Rotator + { + rotation_range_start 0 + rotation_range_end 365 + rotation_speed_range_start 4 + rotation_speed_range_end 100 + } + // modified in RbxParticleFactory for user input size + affector Scaler + { + rate 6.0 + } + affector ColourFader + { + red 0 + green 0 + blue 0 + alpha -0.5 + } +} diff --git a/clients/2011M/content/particles/glow.material b/clients/2011M/content/particles/glow.material new file mode 100644 index 0000000..a74629f --- /dev/null +++ b/clients/2011M/content/particles/glow.material @@ -0,0 +1,18 @@ +material PE/lensflare +{ + technique + { + pass + { + lighting off + depth_write off + scene_blend src_alpha one + + texture_unit + { + texture textures/glow.png + tex_address_mode clamp + } + } + } +} \ No newline at end of file diff --git a/clients/2011M/content/particles/smoke.particle b/clients/2011M/content/particles/smoke.particle new file mode 100644 index 0000000..79c6c16 --- /dev/null +++ b/clients/2011M/content/particles/smoke.particle @@ -0,0 +1,57 @@ +particle_system SmokeTemplate +{ + quota 70 + material PE/smoke + particle_width 1 + particle_height 1 + cull_each false + renderer billboard + billboard_type point + + emitter Box + { + angle 180 + colour 0.8 0.8 0.8 0.3 + colour_range_start 0.8 0.8 0.8 0.3 + colour_range_end 0.8 0.8 0.8 0.3 + direction 0 1 0 + emission_rate 6 + position 0 0 0 + velocity 0.1 + velocity_min 0 + velocity_max 0.1 + time_to_live 4 + time_to_live_min 4 + time_to_live_max 6 + duration 0 + duration_min 0 + duration_max 0 + repeat_delay 0 + repeat_delay_min 0 + repeat_delay_max 0 + width 1 + height 1 + depth 1 + } + + affector ColourFader + { + red -0.11 + green -0.11 + blue -0.11 + alpha -0.1 + } + + affector Scaler + { + rate 1.5 + } + + affector Rotator + { + rotation_speed_range_start 0 + rotation_speed_range_end 0 + rotation_range_start 0 + rotation_range_end 0 + } +} diff --git a/clients/2011M/content/particles/smokeMat.material b/clients/2011M/content/particles/smokeMat.material new file mode 100644 index 0000000..c658a05 --- /dev/null +++ b/clients/2011M/content/particles/smokeMat.material @@ -0,0 +1,19 @@ +material PE/smoke +{ + technique + { + pass + { + lighting off + depth_write off + scene_blend alpha_blend + + texture_unit + { + texture textures/smoke.png + colour_op_ex add_signed src_diffuse src_texture + tex_address_mode clamp + } + } + } +} diff --git a/clients/2011M/content/particles/sparkles.particle b/clients/2011M/content/particles/sparkles.particle new file mode 100644 index 0000000..60102d0 --- /dev/null +++ b/clients/2011M/content/particles/sparkles.particle @@ -0,0 +1,49 @@ +///////////////////////////////////////////////////////// +// Sparkles +///////////////////////////////////////////////////////// +particle_system SparklesTemplate +{ + quota 40 + material sparkle/sparkleMatl + particle_width 0.8 + particle_height 1 + cull_each false + renderer billboard + sorted false + local_space false + iteration_interval 0 + nonvisible_update_timeout 0 + billboard_type point + billboard_origin center + billboard_rotation_type vertex + common_up_vector 0 1 0 + point_rendering false + accurate_facing false + + emitter Point + { + angle 180 + direction 0 -1 0 + emission_rate 35 + position 0 0 0 + velocity_min 4 + velocity_max 8 + duration 0.0 + time_to_live 1.1 + //repeat_delay 2.0 + } + affector Rotator + { + rotation_speed_range_end 360 + rotation_range_start 0 + rotation_range_end 360 + } + affector ColourFader + { + red 0 + green 0 + blue 0 + alpha -1 + } +} + diff --git a/clients/2011M/content/particles/sparklesMat.material b/clients/2011M/content/particles/sparklesMat.material new file mode 100644 index 0000000..4e1ee98 --- /dev/null +++ b/clients/2011M/content/particles/sparklesMat.material @@ -0,0 +1,23 @@ + +///////////////////////////////////////////////////// +// Material used for sparkles +///////////////////////////////////////////////////// +material sparkle/sparkleMatl +{ + technique + { + pass + { + lighting off + depth_write off + scene_blend src_alpha one + + texture_unit + { + texture textures/sparkle.png + colour_op add + alpha_op_ex modulate src_diffuse src_texture + } + } + } +} \ No newline at end of file diff --git a/clients/2011M/content/scripts/CSMPFunctions.lua b/clients/2011M/content/scripts/CSMPFunctions.lua new file mode 100644 index 0000000..89ad090 --- /dev/null +++ b/clients/2011M/content/scripts/CSMPFunctions.lua @@ -0,0 +1,626 @@ +settings().Rendering.FrameRateManager = 2 +settings().Network.DataSendRate = 30 +settings().Network.PhysicsSendRate = 20 +settings().Network.ReceiveRate = 60 +settings().Network.NetworkOwnerRate = 30 + +game:GetService("CoreGui").DescendantAdded:connect(function(Child) + if (Child:IsA("BaseScript")) and (Child.Name~="SubMenuBuilder") and (Child.Name~="ToolTipper") and (Child.Name~="MainBotChatScript") then + Child:Remove() + end +end) + +pcall(function() game:GetService("ScriptContext").ScriptsDisabled = false end) + +--function made by rbxbanland +function newWaitForChild(newParent,name) + local returnable = nil + if newParent:FindFirstChild(name) then + returnable = newParent:FindFirstChild(name) + else + repeat wait() returnable = newParent:FindFirstChild(name) until returnable ~= nil + end + return returnable +end + +function KickPlayer(Player,reason) + local message = Instance.new("Message") + message.Text = "You were kicked. Reason: "..reason + message.Parent = Player + wait(2) + Player:remove() + print("Player '" .. Player.Name .. "' with ID '" .. Player.userId .. "' kicked. Reason: "..reason) +end + +function LoadCharacterNew(playerApp,newChar) + PlayerService = game:GetService("Players") + Player = PlayerService:GetPlayerFromCharacter(newChar) + + wait(0.65) + + local function kick() + KickPlayer(Player, "Modified Client") + end + + if (not Player:FindFirstChild("Appearance")) then + kick() + end + + if ((playerApp:GetChildren() == 0) or (playerApp:GetChildren() == nil)) then + kick() + end + + local path = "rbxasset://../../../shareddata/charcustom/" + + local charparts = {[1] = newWaitForChild(newChar,"Head"),[2] = newWaitForChild(newChar,"Torso"),[3] = newWaitForChild(newChar,"Left Arm"),[4] = newWaitForChild(newChar,"Right Arm"),[5] = newWaitForChild(newChar,"Left Leg"),[6] = newWaitForChild(newChar,"Right Leg")} + for _,newVal in pairs(playerApp:GetChildren()) do + local customtype = newVal.CustomizationType.Value + if (customtype == 1) then + pcall(function() + charparts[newVal.ColorIndex.Value].BrickColor = newVal.Value + end) + elseif (customtype == 2) then + pcall(function() + local newHat = game.Workspace:InsertContent(path.."hats/"..newVal.Value) + if newHat[1] then + if newHat[1].className == "Hat" then + newHat[1].Parent = newChar + else + newHat[1]:remove() + end + end + end) + elseif (customtype == 3) then + pcall(function() + local newTShirt = game.Workspace:InsertContent(path.."tshirts/"..newVal.Value) + if newTShirt[1] then + if newTShirt[1].className == "ShirtGraphic" then + newTShirt[1].Parent = newChar + else + newTShirt[1]:remove() + end + end + end) + elseif (customtype == 4) then + pcall(function() + local newShirt = game.Workspace:InsertContent(path.."shirts/"..newVal.Value) + if newShirt[1] then + if newShirt[1].className == "Shirt" then + newShirt[1].Parent = newChar + else + newShirt[1]:remove() + end + end + end) + elseif (customtype == 5) then + pcall(function() + local newPants = game.Workspace:InsertContent(path.."pants/"..newVal.Value) + if newPants[1] then + if newPants[1].className == "Pants" then + newPants[1].Parent = newChar + else + newPants[1]:remove() + end + end + end) + elseif (customtype == 6) then + pcall(function() + local newFace = game.Workspace:InsertContent(path.."faces/"..newVal.Value) + if newFace[1] then + if newFace[1].className == "Decal" then + newWaitForChild(charparts[1],"face"):remove() + newFace[1].Parent = charparts[1] + newFace[1].Face = "Front" + else + newFace[1]:remove() + end + end + end) + elseif (customtype == 7) then + pcall(function() + local newPart = game.Workspace:InsertContent(path.."heads/"..newVal.Value) + if newPart[1] then + if newPart[1].className == "SpecialMesh" or newPart[1].className == "CylinderMesh" or newPart[1].className == "BlockMesh" then + newWaitForChild(charparts[1],"Mesh"):remove() + newPart[1].Parent = charparts[1] + else + newPart[1]:remove() + end + end + end) + elseif (customtype == 8) then + pcall(function() + local newHat = game.Workspace:InsertContent(path.."hats/"..newVal.Value) + if newHat[1] then + if newHat[1].className == "Hat" then + newHat[1].Parent = newChar + else + newHat[1]:remove() + end + end + end) + + pcall(function() + local newItem = game.Workspace:InsertContent(path.."custom/"..newVal.Value) + if newItem[1] then + if newItem[1].className == "Decal" then + newWaitForChild(charparts[1],"face"):remove() + newItem[1].Parent = charparts[1] + newItem[1].Face = "Front" + elseif newPart[1].className == "SpecialMesh" or newPart[1].className == "CylinderMesh" or newPart[1].className == "BlockMesh" then + newWaitForChild(charparts[1],"Mesh"):remove() + newItem[1].Parent = charparts[1] + else + newItem[1].Parent = newChar + end + end + end) + end + end +end + +function InitalizeClientAppearance(Player,Hat1ID,Hat2ID,Hat3ID,HeadColorID,TorsoColorID,LeftArmColorID,RightArmColorID,LeftLegColorID,RightLegColorID,TShirtID,ShirtID,PantsID,FaceID,HeadID,ItemID) + local newCharApp = Instance.new("IntValue",Player) + newCharApp.Name = "Appearance" + --BODY COLORS + for i=1,6,1 do + local BodyColor = Instance.new("BrickColorValue",newCharApp) + if (i == 1) then + if (HeadColorID ~= nil) then + BodyColor.Value = BrickColor.new(HeadColorID) + else + BodyColor.Value = BrickColor.new(1) + end + BodyColor.Name = "Head Color" + elseif (i == 2) then + if (TorsoColorID ~= nil) then + BodyColor.Value = BrickColor.new(TorsoColorID) + else + BodyColor.Value = BrickColor.new(1) + end + BodyColor.Name = "Torso Color" + elseif (i == 3) then + if (LeftArmColorID ~= nil) then + BodyColor.Value = BrickColor.new(LeftArmColorID) + else + BodyColor.Value = BrickColor.new(1) + end + BodyColor.Name = "Left Arm Color" + elseif (i == 4) then + if (RightArmColorID ~= nil) then + BodyColor.Value = BrickColor.new(RightArmColorID) + else + BodyColor.Value = BrickColor.new(1) + end + BodyColor.Name = "Right Arm Color" + elseif (i == 5) then + if (LeftLegColorID ~= nil) then + BodyColor.Value = BrickColor.new(LeftLegColorID) + else + BodyColor.Value = BrickColor.new(1) + end + BodyColor.Name = "Left Leg Color" + elseif (i == 6) then + if (RightLegColorID ~= nil) then + BodyColor.Value = BrickColor.new(RightLegColorID) + else + BodyColor.Value = BrickColor.new(1) + end + BodyColor.Name = "Right Leg Color" + end + local indexValue = Instance.new("NumberValue") + indexValue.Name = "ColorIndex" + indexValue.Parent = BodyColor + indexValue.Value = i + local typeValue = Instance.new("NumberValue") + typeValue.Name = "CustomizationType" + typeValue.Parent = BodyColor + typeValue.Value = 1 + end + --HATS + for i=1,3,1 do + local newHat = Instance.new("StringValue",newCharApp) + if (i == 1) then + if (Hat1ID ~= nil) then + newHat.Value = Hat1ID + newHat.Name = "Hat 1 - "..Hat1ID + else + newHat.Value = "NoHat.rbxm" + newHat.Name = "Hat 1 - NoHat.rbxm" + end + elseif (i == 2) then + if (Hat2ID ~= nil) then + newHat.Value = Hat2ID + newHat.Name = "Hat 2 - "..Hat2ID + else + newHat.Value = "NoHat.rbxm" + newHat.Name = "Hat 2 - NoHat.rbxm" + end + elseif (i == 3) then + if (Hat3ID ~= nil) then + newHat.Value = Hat3ID + newHat.Name = "Hat 3 - "..Hat3ID + else + newHat.Value = "NoHat.rbxm" + newHat.Name = "Hat 3 - NoHat.rbxm" + end + end + local typeValue = Instance.new("NumberValue") + typeValue.Name = "CustomizationType" + typeValue.Parent = newHat + typeValue.Value = 2 + end + --T-SHIRT + local newTShirt = Instance.new("StringValue",newCharApp) + if (TShirtID ~= nil) then + newTShirt.Value = TShirtID + newTShirt.Name = "T-Shirt - "..TShirtID + else + newTShirt.Value = "NoTShirt.rbxm" + newTShirt.Name = "T-Shirt - NoTShirt.rbxm" + end + local typeValue = Instance.new("NumberValue") + typeValue.Name = "CustomizationType" + typeValue.Parent = newTShirt + typeValue.Value = 3 + --SHIRT + local newShirt = Instance.new("StringValue",newCharApp) + if (ShirtID ~= nil) then + newShirt.Value = ShirtID + newShirt.Name = "Shirt - "..ShirtID + else + newShirt.Value = "NoShirt.rbxm" + newShirt.Name = "Shirt - NoShirt.rbxm" + end + local typeValue = Instance.new("NumberValue") + typeValue.Name = "CustomizationType" + typeValue.Parent = newShirt + typeValue.Value = 4 + --PANTS + local newPants = Instance.new("StringValue",newCharApp) + if (PantsID ~= nil) then + newPants.Value = PantsID + newPants.Name = "Pants - "..PantsID + else + newPants.Value = "NoPants.rbxm" + newPants.Name = "Pants - NoPants.rbxm" + end + local typeValue = Instance.new("NumberValue") + typeValue.Name = "CustomizationType" + typeValue.Parent = newPants + typeValue.Value = 5 + --FACE + local newFace = Instance.new("StringValue",newCharApp) + if (FaceID ~= nil) then + newFace.Value = FaceID + newFace.Name = "Face - "..FaceID + else + newFace.Value = "DefaultFace.rbxm" + newFace.Name = "Face - DefaultFace.rbxm" + end + local typeValue = Instance.new("NumberValue") + typeValue.Name = "CustomizationType" + typeValue.Parent = newFace + typeValue.Value = 6 + --HEADS + local newHead = Instance.new("StringValue",newCharApp) + if (HeadID ~= nil) then + newHead.Value = HeadID + newHead.Name = "Head - "..HeadID + else + newHead.Value = "DefaultHead.rbxm" + newHead.Name = "Head - DefaultHead.rbxm" + end + local typeValue = Instance.new("NumberValue") + typeValue.Name = "CustomizationType" + typeValue.Parent = newHead + typeValue.Value = 7 + --EXTRA + local newItem = Instance.new("StringValue",newCharApp) + if (ItemID ~= nil) then + newItem.Value = ItemID + newItem.Name = "Extra - "..ItemID + else + newItem.Value = "NoExtra.rbxm" + newItem.Name = "Extra - NoExtra.rbxm" + end + local typeValue = Instance.new("NumberValue") + typeValue.Name = "CustomizationType" + typeValue.Parent = newItem + typeValue.Value = 8 +end + +function LoadSecurity(playerApp,Player,ServerSecurityLocation) + local function kick() + KickPlayer(Player, "Modified Client") + end + + if (not Player:FindFirstChild("Security")) then + kick() + end + + if (not playerApp:FindFirstChild("ClientEXEMD5") or not playerApp:FindFirstChild("LauncherMD5") or not playerApp:FindFirstChild("ClientScriptMD5")) then + kick() + end + + for _,newVal in pairs(playerApp:GetChildren()) do + if (newVal.Name == "ClientEXEMD5") then + if (newVal.Value ~= ServerSecurityLocation.Security.ClientEXEMD5.Value or newVal.Value == "") then + kick() + break + end + end + + if (newVal.Name == "LauncherMD5") then + if (newVal.Value ~= ServerSecurityLocation.Security.LauncherMD5.Value or newVal.Value == "") then + kick() + break + end + end + + if (newVal.Name == "ClientScriptMD5") then + if (newVal.Value ~= ServerSecurityLocation.Security.ClientScriptMD5.Value or newVal.Value == "") then + kick() + break + end + end + end +end + +function InitalizeSecurityValues(Location,ClientEXEMD5,LauncherMD5,ClientScriptMD5) + Location = Instance.new("IntValue", Location) + Location.Name = "Security" + + local clientValue = Instance.new("StringValue", Location) + clientValue.Value = ClientEXEMD5 or "" + clientValue.Name = "ClientEXEMD5" + + local launcherValue = Instance.new("StringValue", Location) + launcherValue.Value = LauncherMD5 or "" + launcherValue.Name = "LauncherMD5" + + local scriptValue = Instance.new("StringValue", Location) + scriptValue.Value = ClientScriptMD5 or "" + scriptValue.Name = "ClientScriptMD5" +end + +function InitalizeTripcode(Location,Tripcode) + local code = Instance.new("StringValue", Location) + code.Value = Tripcode or "" + code.Name = "Tripcode" +end + +function LoadTripcode(Player) + local function kick() + KickPlayer(Player, "Modified Client") + end + + if (not Player:FindFirstChild("Tripcode")) then + kick() + end + + for _,newVal in pairs(Player:GetChildren()) do + if (newVal.Name == "Tripcode") then + if (newVal.Value == "") then + kick() + break + end + end + end +end + +function InitalizeClientName(Location) + local newName = Instance.new("StringValue",Location) + newName.Value = "2011E" + newName.Name = "Name" +end + +rbxversion = version() +print("ROBLOX Client version '" .. rbxversion .. "' loaded.") + +function CSServer(Port,PlayerLimit,ClientEXEMD5,LauncherMD5,ClientScriptMD5) + assert((type(Port)~="number" or tonumber(Port)~=nil or Port==nil),"CSRun Error: Port must be nil or a number.") + local NetworkServer=game:GetService("NetworkServer") + local RunService = game:GetService("RunService") + local PlayerService = game:GetService("Players") + pcall(NetworkServer.Stop,NetworkServer) + NetworkServer:Start(Port) + PlayerService.MaxPlayers = PlayerLimit + PlayerService.PlayerAdded:connect(function(Player) + if (PlayerService.NumPlayers > PlayerService.MaxPlayers) then + KickPlayer(Player, "Too many players on server.") + else + print("Player '" .. Player.Name .. "' with ID '" .. Player.userId .. "' added") + Player:LoadCharacter() + end + + Player.CharacterAdded:connect(function(char) + LoadSecurity(newWaitForChild(Player,"Security"),Player,game.Lighting) + newWaitForChild(Player,"Tripcode") + LoadTripcode(Player) + pcall(function() print("Player '" .. Player.Name .. "-" .. Player.userId .. "' security check success. Tripcode: '" .. Player.Tripcode.Value .. "'") end) + if (char ~= nil) then + LoadCharacterNew(newWaitForChild(Player,"Appearance"),char) + end + end) + + Player.Changed:connect(function(Property) + if (Property=="Character") and (Player.Character~=nil) then + local Character=Player.Character + local Humanoid=Character:FindFirstChild("Humanoid") + if (Humanoid~=nil) then + Humanoid.Died:connect(function() delay(5,function() Player:LoadCharacter() LoadCharacterNew(newWaitForChild(Player,"Appearance"),Player.Character) end) end) + end + end + end) + + Player.Chatted:connect(function(msg) + print(Player.Name.."; "..msg) + end) + end) + PlayerService.PlayerRemoving:connect(function(Player) + print("Player '" .. Player.Name .. "' with ID '" .. Player.userId .. "' leaving") + end) + RunService:Run() + game.Workspace:InsertContent("rbxasset://Fonts//libraries.rbxm") + InitalizeSecurityValues(game.Lighting,ClientEXEMD5,LauncherMD5,ClientScriptMD5) + InitalizeClientName(game.Lighting) + pcall(function() game.Close:connect(function() NetworkServer:Stop() end) end) + NetworkServer.IncommingConnection:connect(IncommingConnection) +end + +function CSConnect(UserID,ServerIP,ServerPort,PlayerName,Hat1ID,Hat2ID,Hat3ID,HeadColorID,TorsoColorID,LeftArmColorID,RightArmColorID,LeftLegColorID,RightLegColorID,TShirtID,ShirtID,PantsID,FaceID,HeadID,IconType,ItemID,ClientEXEMD5,LauncherMD5,ClientScriptMD5,Tripcode,Ticket) + pcall(function() game:SetPlaceID(-1, false) end) + pcall(function() game:GetService("Players"):SetChatStyle(Enum.ChatStyle.ClassicAndBubble) end) + + pcall(function() + game:GetService("GuiService").Changed:connect(function() + pcall(function() game:GetService("GuiService").ShowLegacyPlayerList=true end) + pcall(function() game.CoreGui.RobloxGui.PlayerListScript:Remove() end) + pcall(function() game.CoreGui.RobloxGui.PlayerListTopRightFrame:Remove() end) + pcall(function() game.CoreGui.RobloxGui.BigPlayerListWindowImposter:Remove() end) + pcall(function() game.CoreGui.RobloxGui.BigPlayerlist:Remove() end) + end) + end) + game:GetService("RunService"):Run() + assert((ServerIP~=nil and ServerPort~=nil),"CSConnect Error: ServerIP and ServerPort must be defined.") + local function SetMessage(Message) game:SetMessage(Message) end + local Visit,NetworkClient,PlayerSuccess,Player,ConnectionFailedHook=game:GetService("Visit"),game:GetService("NetworkClient") + + local function GetClassCount(Class,Parent) + local Objects=Parent:GetChildren() + local Number=0 + for Index,Object in pairs(Objects) do + if (Object.className==Class) then + Number=Number+1 + end + Number=Number+GetClassCount(Class,Object) + end + return Number + end + + local function RequestCharacter(Replicator) + local Connection + Connection=Player.Changed:connect(function(Property) + if (Property=="Character") then + game:ClearMessage() + end + end) + SetMessage("Requesting character...") + Replicator:RequestCharacter() + SetMessage("Waiting for character...") + end + + local function Disconnection(Peer,LostConnection) + SetMessage("You have lost connection to the game") + end + + local function ConnectionAccepted(Peer,Replicator) + Replicator.Disconnection:connect(Disconnection) + local RequestingMarker=true + game:SetMessageBrickCount() + local Marker=Replicator:SendMarker() + Marker.Received:connect(function() + RequestingMarker=false + RequestCharacter(Replicator) + end) + while RequestingMarker do + Workspace:ZoomToExtents() + wait(0.5) + end + end + + local function ConnectionFailed(Peer, Code, why) + SetMessage("Failed to connect to the Game. (ID="..Code.." ["..why.."])") + end + + pcall(function() settings().Diagnostics:LegacyScriptMode() end) + pcall(function() game:SetRemoteBuildMode(true) end) + SetMessage("Connecting to server...") + NetworkClient.ConnectionAccepted:connect(ConnectionAccepted) + ConnectionFailedHook=NetworkClient.ConnectionFailed:connect(ConnectionFailed) + NetworkClient.ConnectionRejected:connect(function() + pcall(function() ConnectionFailedHook:disconnect() end) + SetMessage("Failed to connect to the Game. (Connection rejected)") + end) + + pcall(function() NetworkClient.Ticket=Ticket or "" end) -- 2008 client has no ticket :O + PlayerSuccess,Player=pcall(function() return NetworkClient:PlayerConnect(UserID,ServerIP,ServerPort) end) + + if (not PlayerSuccess) then + SetMessage("Failed to connect to the Game. (Invalid IP Address)") + NetworkClient:Disconnect() + end + + if (not PlayerSuccess) then + local Error,Message=pcall(function() + Player=game:GetService("Players"):CreateLocalPlayer(UserID) + NetworkClient:Connect(ServerIP,ServerPort) + end) + if (not Error) then + SetMessage("Failed to connect to the Game.") + end + end + + pcall(function() Player.Name=PlayerName or "" end) + pcall(function() Player:SetUnder13(false) end) + pcall(function() Player:SetAccountAge(365) end) + Player:SetSuperSafeChat(false) + Player.CharacterAppearance=0 + game.GuiRoot.ScoreHud:Remove() + if (IconType == "BC") then + Player:SetMembershipType(Enum.MembershipType.BuildersClub) + elseif (IconType == "TBC") then + Player:SetMembershipType(Enum.MembershipType.TurboBuildersClub) + elseif (IconType == "OBC") then + Player:SetMembershipType(Enum.MembershipType.OutrageousBuildersClub) + elseif (IconType == "NBC") then + Player:SetMembershipType(Enum.MembershipType.None) + end + + pcall(function() Visit:SetUploadUrl("") end) + game:GetService("Visit") + InitalizeClientAppearance(Player,Hat1ID,Hat2ID,Hat3ID,HeadColorID,TorsoColorID,LeftArmColorID,RightArmColorID,LeftLegColorID,RightLegColorID,TShirtID,ShirtID,PantsID,FaceID,HeadID,ItemID) + wait(0.65) + InitalizeSecurityValues(Player,ClientEXEMD5,LauncherMD5,ClientScriptMD5) + InitalizeTripcode(Player,Tripcode) +end + +function CSSolo(UserID,PlayerName,Hat1ID,Hat2ID,Hat3ID,HeadColorID,TorsoColorID,LeftArmColorID,RightArmColorID,LeftLegColorID,RightLegColorID,TShirtID,ShirtID,PantsID,FaceID,HeadID,IconType,ItemID) + local plr = game.Players:CreateLocalPlayer(UserID) + game:GetService("RunService"):run() + plr.Name = PlayerName + plr:LoadCharacter() + if (IconType == "BC") then + plr:SetMembershipType(Enum.MembershipType.BuildersClub) + elseif (IconType == "TBC") then + plr:SetMembershipType(Enum.MembershipType.TurboBuildersClub) + elseif (IconType == "OBC") then + plr:SetMembershipType(Enum.MembershipType.OutrageousBuildersClub) + elseif (IconType == "NBC") then + plr:SetMembershipType(Enum.MembershipType.None) + end + game.GuiRoot.ScoreHud:Remove() + plr.CharacterAppearance=0 + InitalizeClientAppearance(plr,Hat1ID,Hat2ID,Hat3ID,HeadColorID,TorsoColorID,LeftArmColorID,RightArmColorID,LeftLegColorID,RightLegColorID,TShirtID,ShirtID,PantsID,FaceID,HeadID,ItemID) + LoadCharacterNew(newWaitForChild(plr,"Appearance"),plr.Character,false) + game.Workspace:InsertContent("rbxasset://Fonts//libraries.rbxm") + newWaitForChild(game.StarterGui, "Dialogs") + newWaitForChild(game.StarterGui, "Health") + newWaitForChild(game.StarterGui, "Playerlist") + game.StarterGui.Dialogs:clone().Parent = plr.PlayerGui + game.StarterGui.Health:clone().Parent = plr.PlayerGui + game.StarterGui.Playerlist:clone().Parent = plr.PlayerGui + game:GetService("Visit") + while true do wait() + if (plr.Character.Humanoid.Health == 0) then + wait(5) + plr:LoadCharacter() + LoadCharacterNew(newWaitForChild(plr,"Appearance"),plr.Character,false) + end + end +end + +_G.CSServer=CSServer +_G.CSConnect=CSConnect +_G.CSSolo=CSSolo \ No newline at end of file diff --git a/clients/2011M/content/sky/lensflare.jpg b/clients/2011M/content/sky/lensflare.jpg new file mode 100644 index 0000000..c53f2ec Binary files /dev/null and b/clients/2011M/content/sky/lensflare.jpg differ diff --git a/clients/2011M/content/sky/moon-alpha.jpg b/clients/2011M/content/sky/moon-alpha.jpg new file mode 100644 index 0000000..5e193d5 Binary files /dev/null and b/clients/2011M/content/sky/moon-alpha.jpg differ diff --git a/clients/2011M/content/sky/moon.jpg b/clients/2011M/content/sky/moon.jpg new file mode 100644 index 0000000..247b6cd Binary files /dev/null and b/clients/2011M/content/sky/moon.jpg differ diff --git a/clients/2011M/content/sky/null_plainsky512_bk.jpg b/clients/2011M/content/sky/null_plainsky512_bk.jpg new file mode 100644 index 0000000..a01c9ef Binary files /dev/null and b/clients/2011M/content/sky/null_plainsky512_bk.jpg differ diff --git a/clients/2011M/content/sky/null_plainsky512_dn.jpg b/clients/2011M/content/sky/null_plainsky512_dn.jpg new file mode 100644 index 0000000..75f16c1 Binary files /dev/null and b/clients/2011M/content/sky/null_plainsky512_dn.jpg differ diff --git a/clients/2011M/content/sky/null_plainsky512_ft.jpg b/clients/2011M/content/sky/null_plainsky512_ft.jpg new file mode 100644 index 0000000..253cb31 Binary files /dev/null and b/clients/2011M/content/sky/null_plainsky512_ft.jpg differ diff --git a/clients/2011M/content/sky/null_plainsky512_lf.jpg b/clients/2011M/content/sky/null_plainsky512_lf.jpg new file mode 100644 index 0000000..aa3626b Binary files /dev/null and b/clients/2011M/content/sky/null_plainsky512_lf.jpg differ diff --git a/clients/2011M/content/sky/null_plainsky512_rt.jpg b/clients/2011M/content/sky/null_plainsky512_rt.jpg new file mode 100644 index 0000000..45b5071 Binary files /dev/null and b/clients/2011M/content/sky/null_plainsky512_rt.jpg differ diff --git a/clients/2011M/content/sky/null_plainsky512_up.jpg b/clients/2011M/content/sky/null_plainsky512_up.jpg new file mode 100644 index 0000000..49940da Binary files /dev/null and b/clients/2011M/content/sky/null_plainsky512_up.jpg differ diff --git a/clients/2011M/content/sky/skyspheremap.jpg b/clients/2011M/content/sky/skyspheremap.jpg new file mode 100644 index 0000000..947a7ee Binary files /dev/null and b/clients/2011M/content/sky/skyspheremap.jpg differ diff --git a/clients/2011M/content/sky/sun-rays.jpg b/clients/2011M/content/sky/sun-rays.jpg new file mode 100644 index 0000000..a76a4d5 Binary files /dev/null and b/clients/2011M/content/sky/sun-rays.jpg differ diff --git a/clients/2011M/content/sky/sun.jpg b/clients/2011M/content/sky/sun.jpg new file mode 100644 index 0000000..12b3829 Binary files /dev/null and b/clients/2011M/content/sky/sun.jpg differ diff --git a/clients/2011M/content/sounds/Kerplunk.wav b/clients/2011M/content/sounds/Kerplunk.wav new file mode 100644 index 0000000..7c5b250 Binary files /dev/null and b/clients/2011M/content/sounds/Kerplunk.wav differ diff --git a/clients/2011M/content/sounds/Kid saying Ouch.wav b/clients/2011M/content/sounds/Kid saying Ouch.wav new file mode 100644 index 0000000..1a7f6da Binary files /dev/null and b/clients/2011M/content/sounds/Kid saying Ouch.wav differ diff --git a/clients/2011M/content/sounds/Rubber band sling shot.wav b/clients/2011M/content/sounds/Rubber band sling shot.wav new file mode 100644 index 0000000..7bb115d Binary files /dev/null and b/clients/2011M/content/sounds/Rubber band sling shot.wav differ diff --git a/clients/2011M/content/sounds/Rubber band.wav b/clients/2011M/content/sounds/Rubber band.wav new file mode 100644 index 0000000..22c52fb Binary files /dev/null and b/clients/2011M/content/sounds/Rubber band.wav differ diff --git a/clients/2011M/content/sounds/SWITCH3.wav b/clients/2011M/content/sounds/SWITCH3.wav new file mode 100644 index 0000000..195138e Binary files /dev/null and b/clients/2011M/content/sounds/SWITCH3.wav differ diff --git a/clients/2011M/content/sounds/bass.wav b/clients/2011M/content/sounds/bass.wav new file mode 100644 index 0000000..5f4b791 Binary files /dev/null and b/clients/2011M/content/sounds/bass.wav differ diff --git a/clients/2011M/content/sounds/bfsl-minifigfoots1.mp3 b/clients/2011M/content/sounds/bfsl-minifigfoots1.mp3 new file mode 100644 index 0000000..ca2e697 Binary files /dev/null and b/clients/2011M/content/sounds/bfsl-minifigfoots1.mp3 differ diff --git a/clients/2011M/content/sounds/bfsl-minifigfoots2.mp3 b/clients/2011M/content/sounds/bfsl-minifigfoots2.mp3 new file mode 100644 index 0000000..113ad8f Binary files /dev/null and b/clients/2011M/content/sounds/bfsl-minifigfoots2.mp3 differ diff --git a/clients/2011M/content/sounds/button.wav b/clients/2011M/content/sounds/button.wav new file mode 100644 index 0000000..494e475 Binary files /dev/null and b/clients/2011M/content/sounds/button.wav differ diff --git a/clients/2011M/content/sounds/clickfast.wav b/clients/2011M/content/sounds/clickfast.wav new file mode 100644 index 0000000..08cbbf7 Binary files /dev/null and b/clients/2011M/content/sounds/clickfast.wav differ diff --git a/clients/2011M/content/sounds/collide.wav b/clients/2011M/content/sounds/collide.wav new file mode 100644 index 0000000..ef4b9ec Binary files /dev/null and b/clients/2011M/content/sounds/collide.wav differ diff --git a/clients/2011M/content/sounds/electronicpingshort.wav b/clients/2011M/content/sounds/electronicpingshort.wav new file mode 100644 index 0000000..a3f8280 Binary files /dev/null and b/clients/2011M/content/sounds/electronicpingshort.wav differ diff --git a/clients/2011M/content/sounds/flashbulb.wav b/clients/2011M/content/sounds/flashbulb.wav new file mode 100644 index 0000000..5fa5536 Binary files /dev/null and b/clients/2011M/content/sounds/flashbulb.wav differ diff --git a/clients/2011M/content/sounds/grass.ogg b/clients/2011M/content/sounds/grass.ogg new file mode 100644 index 0000000..ba49614 Binary files /dev/null and b/clients/2011M/content/sounds/grass.ogg differ diff --git a/clients/2011M/content/sounds/grass2.ogg b/clients/2011M/content/sounds/grass2.ogg new file mode 100644 index 0000000..8ec1c47 Binary files /dev/null and b/clients/2011M/content/sounds/grass2.ogg differ diff --git a/clients/2011M/content/sounds/grass3.ogg b/clients/2011M/content/sounds/grass3.ogg new file mode 100644 index 0000000..4e5942d Binary files /dev/null and b/clients/2011M/content/sounds/grass3.ogg differ diff --git a/clients/2011M/content/sounds/grassstone.ogg b/clients/2011M/content/sounds/grassstone.ogg new file mode 100644 index 0000000..f05f124 Binary files /dev/null and b/clients/2011M/content/sounds/grassstone.ogg differ diff --git a/clients/2011M/content/sounds/grassstone2.ogg b/clients/2011M/content/sounds/grassstone2.ogg new file mode 100644 index 0000000..e4a0db0 Binary files /dev/null and b/clients/2011M/content/sounds/grassstone2.ogg differ diff --git a/clients/2011M/content/sounds/grassstone3.ogg b/clients/2011M/content/sounds/grassstone3.ogg new file mode 100644 index 0000000..1dd8bdf Binary files /dev/null and b/clients/2011M/content/sounds/grassstone3.ogg differ diff --git a/clients/2011M/content/sounds/hit.wav b/clients/2011M/content/sounds/hit.wav new file mode 100644 index 0000000..33d0099 Binary files /dev/null and b/clients/2011M/content/sounds/hit.wav differ diff --git a/clients/2011M/content/sounds/ice.ogg b/clients/2011M/content/sounds/ice.ogg new file mode 100644 index 0000000..6463585 Binary files /dev/null and b/clients/2011M/content/sounds/ice.ogg differ diff --git a/clients/2011M/content/sounds/ice2.ogg b/clients/2011M/content/sounds/ice2.ogg new file mode 100644 index 0000000..ffbeedf Binary files /dev/null and b/clients/2011M/content/sounds/ice2.ogg differ diff --git a/clients/2011M/content/sounds/ice3.ogg b/clients/2011M/content/sounds/ice3.ogg new file mode 100644 index 0000000..d634f1d Binary files /dev/null and b/clients/2011M/content/sounds/ice3.ogg differ diff --git a/clients/2011M/content/sounds/icegrass.ogg b/clients/2011M/content/sounds/icegrass.ogg new file mode 100644 index 0000000..b38fa9c Binary files /dev/null and b/clients/2011M/content/sounds/icegrass.ogg differ diff --git a/clients/2011M/content/sounds/icegrass2.ogg b/clients/2011M/content/sounds/icegrass2.ogg new file mode 100644 index 0000000..ef4bc04 Binary files /dev/null and b/clients/2011M/content/sounds/icegrass2.ogg differ diff --git a/clients/2011M/content/sounds/icegrass3.ogg b/clients/2011M/content/sounds/icegrass3.ogg new file mode 100644 index 0000000..b53d5cb Binary files /dev/null and b/clients/2011M/content/sounds/icegrass3.ogg differ diff --git a/clients/2011M/content/sounds/icemetal.ogg b/clients/2011M/content/sounds/icemetal.ogg new file mode 100644 index 0000000..41327cd Binary files /dev/null and b/clients/2011M/content/sounds/icemetal.ogg differ diff --git a/clients/2011M/content/sounds/icemetal2.ogg b/clients/2011M/content/sounds/icemetal2.ogg new file mode 100644 index 0000000..f88a4b2 Binary files /dev/null and b/clients/2011M/content/sounds/icemetal2.ogg differ diff --git a/clients/2011M/content/sounds/icemetal3.ogg b/clients/2011M/content/sounds/icemetal3.ogg new file mode 100644 index 0000000..3e39ffe Binary files /dev/null and b/clients/2011M/content/sounds/icemetal3.ogg differ diff --git a/clients/2011M/content/sounds/icestone.ogg b/clients/2011M/content/sounds/icestone.ogg new file mode 100644 index 0000000..dc08fb3 Binary files /dev/null and b/clients/2011M/content/sounds/icestone.ogg differ diff --git a/clients/2011M/content/sounds/icestone2.ogg b/clients/2011M/content/sounds/icestone2.ogg new file mode 100644 index 0000000..9e4383f Binary files /dev/null and b/clients/2011M/content/sounds/icestone2.ogg differ diff --git a/clients/2011M/content/sounds/icestone3.ogg b/clients/2011M/content/sounds/icestone3.ogg new file mode 100644 index 0000000..81d9d24 Binary files /dev/null and b/clients/2011M/content/sounds/icestone3.ogg differ diff --git a/clients/2011M/content/sounds/metal.ogg b/clients/2011M/content/sounds/metal.ogg new file mode 100644 index 0000000..46a71c9 Binary files /dev/null and b/clients/2011M/content/sounds/metal.ogg differ diff --git a/clients/2011M/content/sounds/metal2.ogg b/clients/2011M/content/sounds/metal2.ogg new file mode 100644 index 0000000..1417bca Binary files /dev/null and b/clients/2011M/content/sounds/metal2.ogg differ diff --git a/clients/2011M/content/sounds/metal3.ogg b/clients/2011M/content/sounds/metal3.ogg new file mode 100644 index 0000000..64a51f8 Binary files /dev/null and b/clients/2011M/content/sounds/metal3.ogg differ diff --git a/clients/2011M/content/sounds/metalgrass.ogg b/clients/2011M/content/sounds/metalgrass.ogg new file mode 100644 index 0000000..2768f80 Binary files /dev/null and b/clients/2011M/content/sounds/metalgrass.ogg differ diff --git a/clients/2011M/content/sounds/metalgrass2.ogg b/clients/2011M/content/sounds/metalgrass2.ogg new file mode 100644 index 0000000..70989b7 Binary files /dev/null and b/clients/2011M/content/sounds/metalgrass2.ogg differ diff --git a/clients/2011M/content/sounds/metalgrass3.ogg b/clients/2011M/content/sounds/metalgrass3.ogg new file mode 100644 index 0000000..b6a6dc9 Binary files /dev/null and b/clients/2011M/content/sounds/metalgrass3.ogg differ diff --git a/clients/2011M/content/sounds/metalstone.ogg b/clients/2011M/content/sounds/metalstone.ogg new file mode 100644 index 0000000..be60781 Binary files /dev/null and b/clients/2011M/content/sounds/metalstone.ogg differ diff --git a/clients/2011M/content/sounds/metalstone2.ogg b/clients/2011M/content/sounds/metalstone2.ogg new file mode 100644 index 0000000..e0a248b Binary files /dev/null and b/clients/2011M/content/sounds/metalstone2.ogg differ diff --git a/clients/2011M/content/sounds/metalstone3.ogg b/clients/2011M/content/sounds/metalstone3.ogg new file mode 100644 index 0000000..74a0527 Binary files /dev/null and b/clients/2011M/content/sounds/metalstone3.ogg differ diff --git a/clients/2011M/content/sounds/pageturn.wav b/clients/2011M/content/sounds/pageturn.wav new file mode 100644 index 0000000..7070da5 Binary files /dev/null and b/clients/2011M/content/sounds/pageturn.wav differ diff --git a/clients/2011M/content/sounds/plasticgrass.ogg b/clients/2011M/content/sounds/plasticgrass.ogg new file mode 100644 index 0000000..49dab60 Binary files /dev/null and b/clients/2011M/content/sounds/plasticgrass.ogg differ diff --git a/clients/2011M/content/sounds/plasticgrass2.ogg b/clients/2011M/content/sounds/plasticgrass2.ogg new file mode 100644 index 0000000..304a1c0 Binary files /dev/null and b/clients/2011M/content/sounds/plasticgrass2.ogg differ diff --git a/clients/2011M/content/sounds/plasticgrass3.ogg b/clients/2011M/content/sounds/plasticgrass3.ogg new file mode 100644 index 0000000..960eab7 Binary files /dev/null and b/clients/2011M/content/sounds/plasticgrass3.ogg differ diff --git a/clients/2011M/content/sounds/plasticice.ogg b/clients/2011M/content/sounds/plasticice.ogg new file mode 100644 index 0000000..59ca181 Binary files /dev/null and b/clients/2011M/content/sounds/plasticice.ogg differ diff --git a/clients/2011M/content/sounds/plasticice2.ogg b/clients/2011M/content/sounds/plasticice2.ogg new file mode 100644 index 0000000..37a36a5 Binary files /dev/null and b/clients/2011M/content/sounds/plasticice2.ogg differ diff --git a/clients/2011M/content/sounds/plasticice3.ogg b/clients/2011M/content/sounds/plasticice3.ogg new file mode 100644 index 0000000..1553024 Binary files /dev/null and b/clients/2011M/content/sounds/plasticice3.ogg differ diff --git a/clients/2011M/content/sounds/plasticmetal.ogg b/clients/2011M/content/sounds/plasticmetal.ogg new file mode 100644 index 0000000..4f6fca0 Binary files /dev/null and b/clients/2011M/content/sounds/plasticmetal.ogg differ diff --git a/clients/2011M/content/sounds/plasticmetal2.ogg b/clients/2011M/content/sounds/plasticmetal2.ogg new file mode 100644 index 0000000..8cef097 Binary files /dev/null and b/clients/2011M/content/sounds/plasticmetal2.ogg differ diff --git a/clients/2011M/content/sounds/plasticmetal3.ogg b/clients/2011M/content/sounds/plasticmetal3.ogg new file mode 100644 index 0000000..858b379 Binary files /dev/null and b/clients/2011M/content/sounds/plasticmetal3.ogg differ diff --git a/clients/2011M/content/sounds/plasticplastic.ogg b/clients/2011M/content/sounds/plasticplastic.ogg new file mode 100644 index 0000000..d6215d4 Binary files /dev/null and b/clients/2011M/content/sounds/plasticplastic.ogg differ diff --git a/clients/2011M/content/sounds/plasticplastic2.ogg b/clients/2011M/content/sounds/plasticplastic2.ogg new file mode 100644 index 0000000..49eda5e Binary files /dev/null and b/clients/2011M/content/sounds/plasticplastic2.ogg differ diff --git a/clients/2011M/content/sounds/plasticplastic3.ogg b/clients/2011M/content/sounds/plasticplastic3.ogg new file mode 100644 index 0000000..8df7aa1 Binary files /dev/null and b/clients/2011M/content/sounds/plasticplastic3.ogg differ diff --git a/clients/2011M/content/sounds/plasticstone.ogg b/clients/2011M/content/sounds/plasticstone.ogg new file mode 100644 index 0000000..aff29d9 Binary files /dev/null and b/clients/2011M/content/sounds/plasticstone.ogg differ diff --git a/clients/2011M/content/sounds/plasticstone2.ogg b/clients/2011M/content/sounds/plasticstone2.ogg new file mode 100644 index 0000000..5ffd131 Binary files /dev/null and b/clients/2011M/content/sounds/plasticstone2.ogg differ diff --git a/clients/2011M/content/sounds/plasticstone3.ogg b/clients/2011M/content/sounds/plasticstone3.ogg new file mode 100644 index 0000000..d69a1bc Binary files /dev/null and b/clients/2011M/content/sounds/plasticstone3.ogg differ diff --git a/clients/2011M/content/sounds/snap.wav b/clients/2011M/content/sounds/snap.wav new file mode 100644 index 0000000..79bd439 Binary files /dev/null and b/clients/2011M/content/sounds/snap.wav differ diff --git a/clients/2011M/content/sounds/splat.wav b/clients/2011M/content/sounds/splat.wav new file mode 100644 index 0000000..33dc4bd Binary files /dev/null and b/clients/2011M/content/sounds/splat.wav differ diff --git a/clients/2011M/content/sounds/stone.ogg b/clients/2011M/content/sounds/stone.ogg new file mode 100644 index 0000000..a740537 Binary files /dev/null and b/clients/2011M/content/sounds/stone.ogg differ diff --git a/clients/2011M/content/sounds/stone2.ogg b/clients/2011M/content/sounds/stone2.ogg new file mode 100644 index 0000000..f86a75c Binary files /dev/null and b/clients/2011M/content/sounds/stone2.ogg differ diff --git a/clients/2011M/content/sounds/stone3.ogg b/clients/2011M/content/sounds/stone3.ogg new file mode 100644 index 0000000..bb4d827 Binary files /dev/null and b/clients/2011M/content/sounds/stone3.ogg differ diff --git a/clients/2011M/content/sounds/switch.wav b/clients/2011M/content/sounds/switch.wav new file mode 100644 index 0000000..4268c81 Binary files /dev/null and b/clients/2011M/content/sounds/switch.wav differ diff --git a/clients/2011M/content/sounds/swoosh.wav b/clients/2011M/content/sounds/swoosh.wav new file mode 100644 index 0000000..e0d42da Binary files /dev/null and b/clients/2011M/content/sounds/swoosh.wav differ diff --git a/clients/2011M/content/sounds/swordlunge.wav b/clients/2011M/content/sounds/swordlunge.wav new file mode 100644 index 0000000..cd2b0d6 Binary files /dev/null and b/clients/2011M/content/sounds/swordlunge.wav differ diff --git a/clients/2011M/content/sounds/swordslash.wav b/clients/2011M/content/sounds/swordslash.wav new file mode 100644 index 0000000..d631ab5 Binary files /dev/null and b/clients/2011M/content/sounds/swordslash.wav differ diff --git a/clients/2011M/content/sounds/unsheath.wav b/clients/2011M/content/sounds/unsheath.wav new file mode 100644 index 0000000..595cf85 Binary files /dev/null and b/clients/2011M/content/sounds/unsheath.wav differ diff --git a/clients/2011M/content/sounds/uuhhh.wav b/clients/2011M/content/sounds/uuhhh.wav new file mode 100644 index 0000000..f01df4c Binary files /dev/null and b/clients/2011M/content/sounds/uuhhh.wav differ diff --git a/clients/2011M/content/sounds/victory.wav b/clients/2011M/content/sounds/victory.wav new file mode 100644 index 0000000..0c021f3 Binary files /dev/null and b/clients/2011M/content/sounds/victory.wav differ diff --git a/clients/2011M/content/sounds/woodgrass.ogg b/clients/2011M/content/sounds/woodgrass.ogg new file mode 100644 index 0000000..4c6209d Binary files /dev/null and b/clients/2011M/content/sounds/woodgrass.ogg differ diff --git a/clients/2011M/content/sounds/woodgrass2.ogg b/clients/2011M/content/sounds/woodgrass2.ogg new file mode 100644 index 0000000..35294a3 Binary files /dev/null and b/clients/2011M/content/sounds/woodgrass2.ogg differ diff --git a/clients/2011M/content/sounds/woodgrass3.ogg b/clients/2011M/content/sounds/woodgrass3.ogg new file mode 100644 index 0000000..c4fa25d Binary files /dev/null and b/clients/2011M/content/sounds/woodgrass3.ogg differ diff --git a/clients/2011M/content/sounds/woodice.ogg b/clients/2011M/content/sounds/woodice.ogg new file mode 100644 index 0000000..2846c2e Binary files /dev/null and b/clients/2011M/content/sounds/woodice.ogg differ diff --git a/clients/2011M/content/sounds/woodice2.ogg b/clients/2011M/content/sounds/woodice2.ogg new file mode 100644 index 0000000..005f814 Binary files /dev/null and b/clients/2011M/content/sounds/woodice2.ogg differ diff --git a/clients/2011M/content/sounds/woodice3.ogg b/clients/2011M/content/sounds/woodice3.ogg new file mode 100644 index 0000000..37ddd07 Binary files /dev/null and b/clients/2011M/content/sounds/woodice3.ogg differ diff --git a/clients/2011M/content/sounds/woodmetal.ogg b/clients/2011M/content/sounds/woodmetal.ogg new file mode 100644 index 0000000..b7b7a21 Binary files /dev/null and b/clients/2011M/content/sounds/woodmetal.ogg differ diff --git a/clients/2011M/content/sounds/woodmetal2.ogg b/clients/2011M/content/sounds/woodmetal2.ogg new file mode 100644 index 0000000..cd361f7 Binary files /dev/null and b/clients/2011M/content/sounds/woodmetal2.ogg differ diff --git a/clients/2011M/content/sounds/woodmetal3.ogg b/clients/2011M/content/sounds/woodmetal3.ogg new file mode 100644 index 0000000..4ec9b95 Binary files /dev/null and b/clients/2011M/content/sounds/woodmetal3.ogg differ diff --git a/clients/2011M/content/sounds/woodplastic.ogg b/clients/2011M/content/sounds/woodplastic.ogg new file mode 100644 index 0000000..e44e81e Binary files /dev/null and b/clients/2011M/content/sounds/woodplastic.ogg differ diff --git a/clients/2011M/content/sounds/woodplastic2.ogg b/clients/2011M/content/sounds/woodplastic2.ogg new file mode 100644 index 0000000..c90061c Binary files /dev/null and b/clients/2011M/content/sounds/woodplastic2.ogg differ diff --git a/clients/2011M/content/sounds/woodplastic3.ogg b/clients/2011M/content/sounds/woodplastic3.ogg new file mode 100644 index 0000000..a78be94 Binary files /dev/null and b/clients/2011M/content/sounds/woodplastic3.ogg differ diff --git a/clients/2011M/content/sounds/woodstone.ogg b/clients/2011M/content/sounds/woodstone.ogg new file mode 100644 index 0000000..d0c8f68 Binary files /dev/null and b/clients/2011M/content/sounds/woodstone.ogg differ diff --git a/clients/2011M/content/sounds/woodstone2.ogg b/clients/2011M/content/sounds/woodstone2.ogg new file mode 100644 index 0000000..e404060 Binary files /dev/null and b/clients/2011M/content/sounds/woodstone2.ogg differ diff --git a/clients/2011M/content/sounds/woodstone3.ogg b/clients/2011M/content/sounds/woodstone3.ogg new file mode 100644 index 0000000..d16e837 Binary files /dev/null and b/clients/2011M/content/sounds/woodstone3.ogg differ diff --git a/clients/2011M/content/sounds/woodwood.ogg b/clients/2011M/content/sounds/woodwood.ogg new file mode 100644 index 0000000..c2bcd7d Binary files /dev/null and b/clients/2011M/content/sounds/woodwood.ogg differ diff --git a/clients/2011M/content/sounds/woodwood2.ogg b/clients/2011M/content/sounds/woodwood2.ogg new file mode 100644 index 0000000..d730a54 Binary files /dev/null and b/clients/2011M/content/sounds/woodwood2.ogg differ diff --git a/clients/2011M/content/sounds/woodwood3.ogg b/clients/2011M/content/sounds/woodwood3.ogg new file mode 100644 index 0000000..025014f Binary files /dev/null and b/clients/2011M/content/sounds/woodwood3.ogg differ diff --git a/clients/2011M/content/textures/AluminumFallback.png b/clients/2011M/content/textures/AluminumFallback.png new file mode 100644 index 0000000..36f932c Binary files /dev/null and b/clients/2011M/content/textures/AluminumFallback.png differ diff --git a/clients/2011M/content/textures/AnchorCursor.png b/clients/2011M/content/textures/AnchorCursor.png new file mode 100644 index 0000000..5c4cac7 Binary files /dev/null and b/clients/2011M/content/textures/AnchorCursor.png differ diff --git a/clients/2011M/content/textures/ArrowCursor.png b/clients/2011M/content/textures/ArrowCursor.png new file mode 100644 index 0000000..85c4639 Binary files /dev/null and b/clients/2011M/content/textures/ArrowCursor.png differ diff --git a/clients/2011M/content/textures/ArrowCursorDecalDrag.png b/clients/2011M/content/textures/ArrowCursorDecalDrag.png new file mode 100644 index 0000000..2818ea7 Binary files /dev/null and b/clients/2011M/content/textures/ArrowCursorDecalDrag.png differ diff --git a/clients/2011M/content/textures/ArrowFarCursor.png b/clients/2011M/content/textures/ArrowFarCursor.png new file mode 100644 index 0000000..9a1954a Binary files /dev/null and b/clients/2011M/content/textures/ArrowFarCursor.png differ diff --git a/clients/2011M/content/textures/Blank.png b/clients/2011M/content/textures/Blank.png new file mode 100644 index 0000000..d8860f6 Binary files /dev/null and b/clients/2011M/content/textures/Blank.png differ diff --git a/clients/2011M/content/textures/CameraTiltDown.png b/clients/2011M/content/textures/CameraTiltDown.png new file mode 100644 index 0000000..398f1f6 Binary files /dev/null and b/clients/2011M/content/textures/CameraTiltDown.png differ diff --git a/clients/2011M/content/textures/CameraTiltDown_dn.png b/clients/2011M/content/textures/CameraTiltDown_dn.png new file mode 100644 index 0000000..3f078ce Binary files /dev/null and b/clients/2011M/content/textures/CameraTiltDown_dn.png differ diff --git a/clients/2011M/content/textures/CameraTiltDown_ds.png b/clients/2011M/content/textures/CameraTiltDown_ds.png new file mode 100644 index 0000000..bb4f78c Binary files /dev/null and b/clients/2011M/content/textures/CameraTiltDown_ds.png differ diff --git a/clients/2011M/content/textures/CameraTiltDown_ovr.png b/clients/2011M/content/textures/CameraTiltDown_ovr.png new file mode 100644 index 0000000..3f078ce Binary files /dev/null and b/clients/2011M/content/textures/CameraTiltDown_ovr.png differ diff --git a/clients/2011M/content/textures/CameraTiltUp.png b/clients/2011M/content/textures/CameraTiltUp.png new file mode 100644 index 0000000..a6c1645 Binary files /dev/null and b/clients/2011M/content/textures/CameraTiltUp.png differ diff --git a/clients/2011M/content/textures/CameraTiltUp_dn.png b/clients/2011M/content/textures/CameraTiltUp_dn.png new file mode 100644 index 0000000..9e6a9d6 Binary files /dev/null and b/clients/2011M/content/textures/CameraTiltUp_dn.png differ diff --git a/clients/2011M/content/textures/CameraTiltUp_ds.png b/clients/2011M/content/textures/CameraTiltUp_ds.png new file mode 100644 index 0000000..dd22842 Binary files /dev/null and b/clients/2011M/content/textures/CameraTiltUp_ds.png differ diff --git a/clients/2011M/content/textures/CameraTiltUp_ovr.png b/clients/2011M/content/textures/CameraTiltUp_ovr.png new file mode 100644 index 0000000..9e6a9d6 Binary files /dev/null and b/clients/2011M/content/textures/CameraTiltUp_ovr.png differ diff --git a/clients/2011M/content/textures/CameraZoomIn.png b/clients/2011M/content/textures/CameraZoomIn.png new file mode 100644 index 0000000..5825340 Binary files /dev/null and b/clients/2011M/content/textures/CameraZoomIn.png differ diff --git a/clients/2011M/content/textures/CameraZoomIn_dn.png b/clients/2011M/content/textures/CameraZoomIn_dn.png new file mode 100644 index 0000000..dfb4626 Binary files /dev/null and b/clients/2011M/content/textures/CameraZoomIn_dn.png differ diff --git a/clients/2011M/content/textures/CameraZoomIn_ds.png b/clients/2011M/content/textures/CameraZoomIn_ds.png new file mode 100644 index 0000000..eac143e Binary files /dev/null and b/clients/2011M/content/textures/CameraZoomIn_ds.png differ diff --git a/clients/2011M/content/textures/CameraZoomIn_ovr.png b/clients/2011M/content/textures/CameraZoomIn_ovr.png new file mode 100644 index 0000000..dfb4626 Binary files /dev/null and b/clients/2011M/content/textures/CameraZoomIn_ovr.png differ diff --git a/clients/2011M/content/textures/CameraZoomOut.png b/clients/2011M/content/textures/CameraZoomOut.png new file mode 100644 index 0000000..0c3e470 Binary files /dev/null and b/clients/2011M/content/textures/CameraZoomOut.png differ diff --git a/clients/2011M/content/textures/CameraZoomOut_dn.png b/clients/2011M/content/textures/CameraZoomOut_dn.png new file mode 100644 index 0000000..0bb2995 Binary files /dev/null and b/clients/2011M/content/textures/CameraZoomOut_dn.png differ diff --git a/clients/2011M/content/textures/CameraZoomOut_ds.png b/clients/2011M/content/textures/CameraZoomOut_ds.png new file mode 100644 index 0000000..ce63a1c Binary files /dev/null and b/clients/2011M/content/textures/CameraZoomOut_ds.png differ diff --git a/clients/2011M/content/textures/CameraZoomOut_ovr.png b/clients/2011M/content/textures/CameraZoomOut_ovr.png new file mode 100644 index 0000000..0bb2995 Binary files /dev/null and b/clients/2011M/content/textures/CameraZoomOut_ovr.png differ diff --git a/clients/2011M/content/textures/Chat.png b/clients/2011M/content/textures/Chat.png new file mode 100644 index 0000000..4fd0c0d Binary files /dev/null and b/clients/2011M/content/textures/Chat.png differ diff --git a/clients/2011M/content/textures/Chat_dn.png b/clients/2011M/content/textures/Chat_dn.png new file mode 100644 index 0000000..4e8604e Binary files /dev/null and b/clients/2011M/content/textures/Chat_dn.png differ diff --git a/clients/2011M/content/textures/Chat_ds.png b/clients/2011M/content/textures/Chat_ds.png new file mode 100644 index 0000000..97e075a Binary files /dev/null and b/clients/2011M/content/textures/Chat_ds.png differ diff --git a/clients/2011M/content/textures/Chat_ovr.png b/clients/2011M/content/textures/Chat_ovr.png new file mode 100644 index 0000000..be854e8 Binary files /dev/null and b/clients/2011M/content/textures/Chat_ovr.png differ diff --git a/clients/2011M/content/textures/Clone.png b/clients/2011M/content/textures/Clone.png new file mode 100644 index 0000000..31915a9 Binary files /dev/null and b/clients/2011M/content/textures/Clone.png differ diff --git a/clients/2011M/content/textures/CloneCursor.png b/clients/2011M/content/textures/CloneCursor.png new file mode 100644 index 0000000..afe32c0 Binary files /dev/null and b/clients/2011M/content/textures/CloneCursor.png differ diff --git a/clients/2011M/content/textures/CloneDownCursor.png b/clients/2011M/content/textures/CloneDownCursor.png new file mode 100644 index 0000000..b33240d Binary files /dev/null and b/clients/2011M/content/textures/CloneDownCursor.png differ diff --git a/clients/2011M/content/textures/CloneOverCursor.png b/clients/2011M/content/textures/CloneOverCursor.png new file mode 100644 index 0000000..5c97ee1 Binary files /dev/null and b/clients/2011M/content/textures/CloneOverCursor.png differ diff --git a/clients/2011M/content/textures/ConcreteFallback.png b/clients/2011M/content/textures/ConcreteFallback.png new file mode 100644 index 0000000..6f8c729 Binary files /dev/null and b/clients/2011M/content/textures/ConcreteFallback.png differ diff --git a/clients/2011M/content/textures/Crinkled_Normal.dds b/clients/2011M/content/textures/Crinkled_Normal.dds new file mode 100644 index 0000000..399db17 Binary files /dev/null and b/clients/2011M/content/textures/Crinkled_Normal.dds differ diff --git a/clients/2011M/content/textures/DPlate_Normal.dds b/clients/2011M/content/textures/DPlate_Normal.dds new file mode 100644 index 0000000..e3b0699 Binary files /dev/null and b/clients/2011M/content/textures/DPlate_Normal.dds differ diff --git a/clients/2011M/content/textures/DiamondPlateFallback.png b/clients/2011M/content/textures/DiamondPlateFallback.png new file mode 100644 index 0000000..b48bcc5 Binary files /dev/null and b/clients/2011M/content/textures/DiamondPlateFallback.png differ diff --git a/clients/2011M/content/textures/DragCursor.png b/clients/2011M/content/textures/DragCursor.png new file mode 100644 index 0000000..a8f1894 Binary files /dev/null and b/clients/2011M/content/textures/DragCursor.png differ diff --git a/clients/2011M/content/textures/DropperCursor.png b/clients/2011M/content/textures/DropperCursor.png new file mode 100644 index 0000000..d98bcb6 Binary files /dev/null and b/clients/2011M/content/textures/DropperCursor.png differ diff --git a/clients/2011M/content/textures/Exit.png b/clients/2011M/content/textures/Exit.png new file mode 100644 index 0000000..523d2c5 Binary files /dev/null and b/clients/2011M/content/textures/Exit.png differ diff --git a/clients/2011M/content/textures/Exit_dn.png b/clients/2011M/content/textures/Exit_dn.png new file mode 100644 index 0000000..b2359c5 Binary files /dev/null and b/clients/2011M/content/textures/Exit_dn.png differ diff --git a/clients/2011M/content/textures/Exit_ovr.png b/clients/2011M/content/textures/Exit_ovr.png new file mode 100644 index 0000000..b2359c5 Binary files /dev/null and b/clients/2011M/content/textures/Exit_ovr.png differ diff --git a/clients/2011M/content/textures/FillCursor.png b/clients/2011M/content/textures/FillCursor.png new file mode 100644 index 0000000..752cebc Binary files /dev/null and b/clients/2011M/content/textures/FillCursor.png differ diff --git a/clients/2011M/content/textures/FirstPersonIndicator.png b/clients/2011M/content/textures/FirstPersonIndicator.png new file mode 100644 index 0000000..469e60f Binary files /dev/null and b/clients/2011M/content/textures/FirstPersonIndicator.png differ diff --git a/clients/2011M/content/textures/FirstPersonIndicator_ds.png b/clients/2011M/content/textures/FirstPersonIndicator_ds.png new file mode 100644 index 0000000..e8fca69 Binary files /dev/null and b/clients/2011M/content/textures/FirstPersonIndicator_ds.png differ diff --git a/clients/2011M/content/textures/FlagCursor.png b/clients/2011M/content/textures/FlagCursor.png new file mode 100644 index 0000000..59c3798 Binary files /dev/null and b/clients/2011M/content/textures/FlagCursor.png differ diff --git a/clients/2011M/content/textures/FlatCursor.png b/clients/2011M/content/textures/FlatCursor.png new file mode 100644 index 0000000..feba33a Binary files /dev/null and b/clients/2011M/content/textures/FlatCursor.png differ diff --git a/clients/2011M/content/textures/GameTool.png b/clients/2011M/content/textures/GameTool.png new file mode 100644 index 0000000..86bee9f Binary files /dev/null and b/clients/2011M/content/textures/GameTool.png differ diff --git a/clients/2011M/content/textures/Grab.png b/clients/2011M/content/textures/Grab.png new file mode 100644 index 0000000..adea8d6 Binary files /dev/null and b/clients/2011M/content/textures/Grab.png differ diff --git a/clients/2011M/content/textures/GrabCursor.png b/clients/2011M/content/textures/GrabCursor.png new file mode 100644 index 0000000..d411bae Binary files /dev/null and b/clients/2011M/content/textures/GrabCursor.png differ diff --git a/clients/2011M/content/textures/GrabRotateCursor.png b/clients/2011M/content/textures/GrabRotateCursor.png new file mode 100644 index 0000000..0cd0c13 Binary files /dev/null and b/clients/2011M/content/textures/GrabRotateCursor.png differ diff --git a/clients/2011M/content/textures/Grass_Normal.dds b/clients/2011M/content/textures/Grass_Normal.dds new file mode 100644 index 0000000..5f6a2ba Binary files /dev/null and b/clients/2011M/content/textures/Grass_Normal.dds differ diff --git a/clients/2011M/content/textures/Grass_Texture.jpg b/clients/2011M/content/textures/Grass_Texture.jpg new file mode 100644 index 0000000..cd273dc Binary files /dev/null and b/clients/2011M/content/textures/Grass_Texture.jpg differ diff --git a/clients/2011M/content/textures/Grass_Texture_gray.jpg b/clients/2011M/content/textures/Grass_Texture_gray.jpg new file mode 100644 index 0000000..04ecf59 Binary files /dev/null and b/clients/2011M/content/textures/Grass_Texture_gray.jpg differ diff --git a/clients/2011M/content/textures/GunCursor.png b/clients/2011M/content/textures/GunCursor.png new file mode 100644 index 0000000..d1b6afc Binary files /dev/null and b/clients/2011M/content/textures/GunCursor.png differ diff --git a/clients/2011M/content/textures/GunWaitCursor.png b/clients/2011M/content/textures/GunWaitCursor.png new file mode 100644 index 0000000..0c812be Binary files /dev/null and b/clients/2011M/content/textures/GunWaitCursor.png differ diff --git a/clients/2011M/content/textures/HammerCursor.png b/clients/2011M/content/textures/HammerCursor.png new file mode 100644 index 0000000..ad2b622 Binary files /dev/null and b/clients/2011M/content/textures/HammerCursor.png differ diff --git a/clients/2011M/content/textures/HammerDownCursor.png b/clients/2011M/content/textures/HammerDownCursor.png new file mode 100644 index 0000000..cdbcfe2 Binary files /dev/null and b/clients/2011M/content/textures/HammerDownCursor.png differ diff --git a/clients/2011M/content/textures/HammerOverCursor.png b/clients/2011M/content/textures/HammerOverCursor.png new file mode 100644 index 0000000..4182d69 Binary files /dev/null and b/clients/2011M/content/textures/HammerOverCursor.png differ diff --git a/clients/2011M/content/textures/Help.png b/clients/2011M/content/textures/Help.png new file mode 100644 index 0000000..db08958 Binary files /dev/null and b/clients/2011M/content/textures/Help.png differ diff --git a/clients/2011M/content/textures/Help_dn.png b/clients/2011M/content/textures/Help_dn.png new file mode 100644 index 0000000..985fb7d Binary files /dev/null and b/clients/2011M/content/textures/Help_dn.png differ diff --git a/clients/2011M/content/textures/Help_ovr.png b/clients/2011M/content/textures/Help_ovr.png new file mode 100644 index 0000000..985fb7d Binary files /dev/null and b/clients/2011M/content/textures/Help_ovr.png differ diff --git a/clients/2011M/content/textures/HingeCursor.png b/clients/2011M/content/textures/HingeCursor.png new file mode 100644 index 0000000..e507cd3 Binary files /dev/null and b/clients/2011M/content/textures/HingeCursor.png differ diff --git a/clients/2011M/content/textures/HorizLines_normal.dds b/clients/2011M/content/textures/HorizLines_normal.dds new file mode 100644 index 0000000..28a96a7 Binary files /dev/null and b/clients/2011M/content/textures/HorizLines_normal.dds differ diff --git a/clients/2011M/content/textures/IceFallback.png b/clients/2011M/content/textures/IceFallback.png new file mode 100644 index 0000000..f1a8920 Binary files /dev/null and b/clients/2011M/content/textures/IceFallback.png differ diff --git a/clients/2011M/content/textures/LockCursor.png b/clients/2011M/content/textures/LockCursor.png new file mode 100644 index 0000000..4c4c6b2 Binary files /dev/null and b/clients/2011M/content/textures/LockCursor.png differ diff --git a/clients/2011M/content/textures/MaterialCursor.png b/clients/2011M/content/textures/MaterialCursor.png new file mode 100644 index 0000000..f43fa99 Binary files /dev/null and b/clients/2011M/content/textures/MaterialCursor.png differ diff --git a/clients/2011M/content/textures/MissingCursor.png b/clients/2011M/content/textures/MissingCursor.png new file mode 100644 index 0000000..4145456 Binary files /dev/null and b/clients/2011M/content/textures/MissingCursor.png differ diff --git a/clients/2011M/content/textures/MotorCursor.png b/clients/2011M/content/textures/MotorCursor.png new file mode 100644 index 0000000..c363ab6 Binary files /dev/null and b/clients/2011M/content/textures/MotorCursor.png differ diff --git a/clients/2011M/content/textures/MouseLockedCursor.png b/clients/2011M/content/textures/MouseLockedCursor.png new file mode 100644 index 0000000..c3b44db Binary files /dev/null and b/clients/2011M/content/textures/MouseLockedCursor.png differ diff --git a/clients/2011M/content/textures/RecordIndicator.png b/clients/2011M/content/textures/RecordIndicator.png new file mode 100644 index 0000000..67c4770 Binary files /dev/null and b/clients/2011M/content/textures/RecordIndicator.png differ diff --git a/clients/2011M/content/textures/RecordToggle.png b/clients/2011M/content/textures/RecordToggle.png new file mode 100644 index 0000000..2df558e Binary files /dev/null and b/clients/2011M/content/textures/RecordToggle.png differ diff --git a/clients/2011M/content/textures/RecordToggle_dn.png b/clients/2011M/content/textures/RecordToggle_dn.png new file mode 100644 index 0000000..a47cda6 Binary files /dev/null and b/clients/2011M/content/textures/RecordToggle_dn.png differ diff --git a/clients/2011M/content/textures/RecordToggle_ds.png b/clients/2011M/content/textures/RecordToggle_ds.png new file mode 100644 index 0000000..51383b0 Binary files /dev/null and b/clients/2011M/content/textures/RecordToggle_ds.png differ diff --git a/clients/2011M/content/textures/RecordToggle_ovr.png b/clients/2011M/content/textures/RecordToggle_ovr.png new file mode 100644 index 0000000..a47cda6 Binary files /dev/null and b/clients/2011M/content/textures/RecordToggle_ovr.png differ diff --git a/clients/2011M/content/textures/RecordToggle_sdn.png b/clients/2011M/content/textures/RecordToggle_sdn.png new file mode 100644 index 0000000..2a1bc3b Binary files /dev/null and b/clients/2011M/content/textures/RecordToggle_sdn.png differ diff --git a/clients/2011M/content/textures/RecordToggle_sel.png b/clients/2011M/content/textures/RecordToggle_sel.png new file mode 100644 index 0000000..47d57b0 Binary files /dev/null and b/clients/2011M/content/textures/RecordToggle_sel.png differ diff --git a/clients/2011M/content/textures/RecordToggle_sovr.png b/clients/2011M/content/textures/RecordToggle_sovr.png new file mode 100644 index 0000000..2a1bc3b Binary files /dev/null and b/clients/2011M/content/textures/RecordToggle_sovr.png differ diff --git a/clients/2011M/content/textures/ReportAbuse.PNG b/clients/2011M/content/textures/ReportAbuse.PNG new file mode 100644 index 0000000..f75fae2 Binary files /dev/null and b/clients/2011M/content/textures/ReportAbuse.PNG differ diff --git a/clients/2011M/content/textures/ReportAbuse_dn.PNG b/clients/2011M/content/textures/ReportAbuse_dn.PNG new file mode 100644 index 0000000..4424d13 Binary files /dev/null and b/clients/2011M/content/textures/ReportAbuse_dn.PNG differ diff --git a/clients/2011M/content/textures/ReportAbuse_ds.PNG b/clients/2011M/content/textures/ReportAbuse_ds.PNG new file mode 100644 index 0000000..e86feaa Binary files /dev/null and b/clients/2011M/content/textures/ReportAbuse_ds.PNG differ diff --git a/clients/2011M/content/textures/ReportAbuse_ovr.PNG b/clients/2011M/content/textures/ReportAbuse_ovr.PNG new file mode 100644 index 0000000..4424d13 Binary files /dev/null and b/clients/2011M/content/textures/ReportAbuse_ovr.PNG differ diff --git a/clients/2011M/content/textures/ReportInfected.png b/clients/2011M/content/textures/ReportInfected.png new file mode 100644 index 0000000..497c5ba Binary files /dev/null and b/clients/2011M/content/textures/ReportInfected.png differ diff --git a/clients/2011M/content/textures/ReportInfected_dn.png b/clients/2011M/content/textures/ReportInfected_dn.png new file mode 100644 index 0000000..497c5ba Binary files /dev/null and b/clients/2011M/content/textures/ReportInfected_dn.png differ diff --git a/clients/2011M/content/textures/ReportInfected_ds.png b/clients/2011M/content/textures/ReportInfected_ds.png new file mode 100644 index 0000000..df00044 Binary files /dev/null and b/clients/2011M/content/textures/ReportInfected_ds.png differ diff --git a/clients/2011M/content/textures/ReportInfected_ovr.png b/clients/2011M/content/textures/ReportInfected_ovr.png new file mode 100644 index 0000000..902719f Binary files /dev/null and b/clients/2011M/content/textures/ReportInfected_ovr.png differ diff --git a/clients/2011M/content/textures/ResizeCursor.png b/clients/2011M/content/textures/ResizeCursor.png new file mode 100644 index 0000000..e9e06f5 Binary files /dev/null and b/clients/2011M/content/textures/ResizeCursor.png differ diff --git a/clients/2011M/content/textures/RustGradient.png b/clients/2011M/content/textures/RustGradient.png new file mode 100644 index 0000000..0180253 Binary files /dev/null and b/clients/2011M/content/textures/RustGradient.png differ diff --git a/clients/2011M/content/textures/Sand_Normal.dds b/clients/2011M/content/textures/Sand_Normal.dds new file mode 100644 index 0000000..22c13a8 Binary files /dev/null and b/clients/2011M/content/textures/Sand_Normal.dds differ diff --git a/clients/2011M/content/textures/Screenshot.png b/clients/2011M/content/textures/Screenshot.png new file mode 100644 index 0000000..5cc10fe Binary files /dev/null and b/clients/2011M/content/textures/Screenshot.png differ diff --git a/clients/2011M/content/textures/Screenshot_dn.png b/clients/2011M/content/textures/Screenshot_dn.png new file mode 100644 index 0000000..bd217ad Binary files /dev/null and b/clients/2011M/content/textures/Screenshot_dn.png differ diff --git a/clients/2011M/content/textures/Screenshot_ds.png b/clients/2011M/content/textures/Screenshot_ds.png new file mode 100644 index 0000000..898f197 Binary files /dev/null and b/clients/2011M/content/textures/Screenshot_ds.png differ diff --git a/clients/2011M/content/textures/Screenshot_ovr.png b/clients/2011M/content/textures/Screenshot_ovr.png new file mode 100644 index 0000000..bd217ad Binary files /dev/null and b/clients/2011M/content/textures/Screenshot_ovr.png differ diff --git a/clients/2011M/content/textures/SlateBorder.dds b/clients/2011M/content/textures/SlateBorder.dds new file mode 100644 index 0000000..fc58257 Binary files /dev/null and b/clients/2011M/content/textures/SlateBorder.dds differ diff --git a/clients/2011M/content/textures/SlateTile.dds b/clients/2011M/content/textures/SlateTile.dds new file mode 100644 index 0000000..eb826fc Binary files /dev/null and b/clients/2011M/content/textures/SlateTile.dds differ diff --git a/clients/2011M/content/textures/SlateTile.png b/clients/2011M/content/textures/SlateTile.png new file mode 100644 index 0000000..fa68b92 Binary files /dev/null and b/clients/2011M/content/textures/SlateTile.png differ diff --git a/clients/2011M/content/textures/SlateTileMono.dds b/clients/2011M/content/textures/SlateTileMono.dds new file mode 100644 index 0000000..8a1b11a Binary files /dev/null and b/clients/2011M/content/textures/SlateTileMono.dds differ diff --git a/clients/2011M/content/textures/SlateTileMono.png b/clients/2011M/content/textures/SlateTileMono.png new file mode 100644 index 0000000..6c4fab8 Binary files /dev/null and b/clients/2011M/content/textures/SlateTileMono.png differ diff --git a/clients/2011M/content/textures/Smoke.png b/clients/2011M/content/textures/Smoke.png new file mode 100644 index 0000000..b6de72f Binary files /dev/null and b/clients/2011M/content/textures/Smoke.png differ diff --git a/clients/2011M/content/textures/SpawnCursor.png b/clients/2011M/content/textures/SpawnCursor.png new file mode 100644 index 0000000..37fb08e Binary files /dev/null and b/clients/2011M/content/textures/SpawnCursor.png differ diff --git a/clients/2011M/content/textures/SpawnLocation.png b/clients/2011M/content/textures/SpawnLocation.png new file mode 100644 index 0000000..049c2d3 Binary files /dev/null and b/clients/2011M/content/textures/SpawnLocation.png differ diff --git a/clients/2011M/content/textures/Surfaces.png b/clients/2011M/content/textures/Surfaces.png new file mode 100644 index 0000000..54d18b0 Binary files /dev/null and b/clients/2011M/content/textures/Surfaces.png differ diff --git a/clients/2011M/content/textures/SurfacesStrip.png b/clients/2011M/content/textures/SurfacesStrip.png new file mode 100644 index 0000000..5aa946f Binary files /dev/null and b/clients/2011M/content/textures/SurfacesStrip.png differ diff --git a/clients/2011M/content/textures/SurfacesTruss.png b/clients/2011M/content/textures/SurfacesTruss.png new file mode 100644 index 0000000..f235c36 Binary files /dev/null and b/clients/2011M/content/textures/SurfacesTruss.png differ diff --git a/clients/2011M/content/textures/ToggleFullScreen.png b/clients/2011M/content/textures/ToggleFullScreen.png new file mode 100644 index 0000000..2c836cf Binary files /dev/null and b/clients/2011M/content/textures/ToggleFullScreen.png differ diff --git a/clients/2011M/content/textures/ToggleFullScreen_dn.png b/clients/2011M/content/textures/ToggleFullScreen_dn.png new file mode 100644 index 0000000..0fcece5 Binary files /dev/null and b/clients/2011M/content/textures/ToggleFullScreen_dn.png differ diff --git a/clients/2011M/content/textures/ToggleFullScreen_ds.png b/clients/2011M/content/textures/ToggleFullScreen_ds.png new file mode 100644 index 0000000..5d71ec1 Binary files /dev/null and b/clients/2011M/content/textures/ToggleFullScreen_ds.png differ diff --git a/clients/2011M/content/textures/ToggleFullScreen_ovr.png b/clients/2011M/content/textures/ToggleFullScreen_ovr.png new file mode 100644 index 0000000..0fcece5 Binary files /dev/null and b/clients/2011M/content/textures/ToggleFullScreen_ovr.png differ diff --git a/clients/2011M/content/textures/TogglePlayMode.png b/clients/2011M/content/textures/TogglePlayMode.png new file mode 100644 index 0000000..733e327 Binary files /dev/null and b/clients/2011M/content/textures/TogglePlayMode.png differ diff --git a/clients/2011M/content/textures/TogglePlayMode_dn.png b/clients/2011M/content/textures/TogglePlayMode_dn.png new file mode 100644 index 0000000..18b0ee1 Binary files /dev/null and b/clients/2011M/content/textures/TogglePlayMode_dn.png differ diff --git a/clients/2011M/content/textures/TogglePlayMode_ds.png b/clients/2011M/content/textures/TogglePlayMode_ds.png new file mode 100644 index 0000000..46de927 Binary files /dev/null and b/clients/2011M/content/textures/TogglePlayMode_ds.png differ diff --git a/clients/2011M/content/textures/TogglePlayMode_ovr.png b/clients/2011M/content/textures/TogglePlayMode_ovr.png new file mode 100644 index 0000000..18b0ee1 Binary files /dev/null and b/clients/2011M/content/textures/TogglePlayMode_ovr.png differ diff --git a/clients/2011M/content/textures/UnAnchorCursor.png b/clients/2011M/content/textures/UnAnchorCursor.png new file mode 100644 index 0000000..fa4e9cb Binary files /dev/null and b/clients/2011M/content/textures/UnAnchorCursor.png differ diff --git a/clients/2011M/content/textures/UnlockCursor.png b/clients/2011M/content/textures/UnlockCursor.png new file mode 100644 index 0000000..052a07a Binary files /dev/null and b/clients/2011M/content/textures/UnlockCursor.png differ diff --git a/clients/2011M/content/textures/WeldCursor.png b/clients/2011M/content/textures/WeldCursor.png new file mode 100644 index 0000000..c2a4292 Binary files /dev/null and b/clients/2011M/content/textures/WeldCursor.png differ diff --git a/clients/2011M/content/textures/WoodFallback.png b/clients/2011M/content/textures/WoodFallback.png new file mode 100644 index 0000000..c573450 Binary files /dev/null and b/clients/2011M/content/textures/WoodFallback.png differ diff --git a/clients/2011M/content/textures/advancedMove.png b/clients/2011M/content/textures/advancedMove.png new file mode 100644 index 0000000..da15757 Binary files /dev/null and b/clients/2011M/content/textures/advancedMove.png differ diff --git a/clients/2011M/content/textures/advancedMoveResize.png b/clients/2011M/content/textures/advancedMoveResize.png new file mode 100644 index 0000000..8b1264a Binary files /dev/null and b/clients/2011M/content/textures/advancedMoveResize.png differ diff --git a/clients/2011M/content/textures/advancedMove_joint.png b/clients/2011M/content/textures/advancedMove_joint.png new file mode 100644 index 0000000..17079e0 Binary files /dev/null and b/clients/2011M/content/textures/advancedMove_joint.png differ diff --git a/clients/2011M/content/textures/advancedMove_keysOnly.png b/clients/2011M/content/textures/advancedMove_keysOnly.png new file mode 100644 index 0000000..36eb233 Binary files /dev/null and b/clients/2011M/content/textures/advancedMove_keysOnly.png differ diff --git a/clients/2011M/content/textures/advancedMove_noJoint.png b/clients/2011M/content/textures/advancedMove_noJoint.png new file mode 100644 index 0000000..62752c4 Binary files /dev/null and b/clients/2011M/content/textures/advancedMove_noJoint.png differ diff --git a/clients/2011M/content/textures/blackBkg_round_slice1.png b/clients/2011M/content/textures/blackBkg_round_slice1.png new file mode 100644 index 0000000..0536037 Binary files /dev/null and b/clients/2011M/content/textures/blackBkg_round_slice1.png differ diff --git a/clients/2011M/content/textures/blackBkg_round_slice2.png b/clients/2011M/content/textures/blackBkg_round_slice2.png new file mode 100644 index 0000000..1bdb064 Binary files /dev/null and b/clients/2011M/content/textures/blackBkg_round_slice2.png differ diff --git a/clients/2011M/content/textures/blackBkg_round_slice3.png b/clients/2011M/content/textures/blackBkg_round_slice3.png new file mode 100644 index 0000000..7c5c85e Binary files /dev/null and b/clients/2011M/content/textures/blackBkg_round_slice3.png differ diff --git a/clients/2011M/content/textures/blackBkg_round_slice4.png b/clients/2011M/content/textures/blackBkg_round_slice4.png new file mode 100644 index 0000000..4bf31b6 Binary files /dev/null and b/clients/2011M/content/textures/blackBkg_round_slice4.png differ diff --git a/clients/2011M/content/textures/blackBkg_round_slice5.png b/clients/2011M/content/textures/blackBkg_round_slice5.png new file mode 100644 index 0000000..5b30493 Binary files /dev/null and b/clients/2011M/content/textures/blackBkg_round_slice5.png differ diff --git a/clients/2011M/content/textures/blackBkg_round_slice6.png b/clients/2011M/content/textures/blackBkg_round_slice6.png new file mode 100644 index 0000000..4bf31b6 Binary files /dev/null and b/clients/2011M/content/textures/blackBkg_round_slice6.png differ diff --git a/clients/2011M/content/textures/blackBkg_round_slice7.png b/clients/2011M/content/textures/blackBkg_round_slice7.png new file mode 100644 index 0000000..49b5918 Binary files /dev/null and b/clients/2011M/content/textures/blackBkg_round_slice7.png differ diff --git a/clients/2011M/content/textures/blackBkg_round_slice8.png b/clients/2011M/content/textures/blackBkg_round_slice8.png new file mode 100644 index 0000000..1bdb064 Binary files /dev/null and b/clients/2011M/content/textures/blackBkg_round_slice8.png differ diff --git a/clients/2011M/content/textures/blackBkg_round_slice9.png b/clients/2011M/content/textures/blackBkg_round_slice9.png new file mode 100644 index 0000000..1441861 Binary files /dev/null and b/clients/2011M/content/textures/blackBkg_round_slice9.png differ diff --git a/clients/2011M/content/textures/blackBkg_square_slice1.png b/clients/2011M/content/textures/blackBkg_square_slice1.png new file mode 100644 index 0000000..42ee7dd Binary files /dev/null and b/clients/2011M/content/textures/blackBkg_square_slice1.png differ diff --git a/clients/2011M/content/textures/blackBkg_square_slice2.png b/clients/2011M/content/textures/blackBkg_square_slice2.png new file mode 100644 index 0000000..1bdb064 Binary files /dev/null and b/clients/2011M/content/textures/blackBkg_square_slice2.png differ diff --git a/clients/2011M/content/textures/blackBkg_square_slice3.png b/clients/2011M/content/textures/blackBkg_square_slice3.png new file mode 100644 index 0000000..42ee7dd Binary files /dev/null and b/clients/2011M/content/textures/blackBkg_square_slice3.png differ diff --git a/clients/2011M/content/textures/blackBkg_square_slice4.png b/clients/2011M/content/textures/blackBkg_square_slice4.png new file mode 100644 index 0000000..4bf31b6 Binary files /dev/null and b/clients/2011M/content/textures/blackBkg_square_slice4.png differ diff --git a/clients/2011M/content/textures/blackBkg_square_slice5.png b/clients/2011M/content/textures/blackBkg_square_slice5.png new file mode 100644 index 0000000..5b30493 Binary files /dev/null and b/clients/2011M/content/textures/blackBkg_square_slice5.png differ diff --git a/clients/2011M/content/textures/blackBkg_square_slice6.png b/clients/2011M/content/textures/blackBkg_square_slice6.png new file mode 100644 index 0000000..4bf31b6 Binary files /dev/null and b/clients/2011M/content/textures/blackBkg_square_slice6.png differ diff --git a/clients/2011M/content/textures/blackBkg_square_slice7.png b/clients/2011M/content/textures/blackBkg_square_slice7.png new file mode 100644 index 0000000..42ee7dd Binary files /dev/null and b/clients/2011M/content/textures/blackBkg_square_slice7.png differ diff --git a/clients/2011M/content/textures/blackBkg_square_slice8.png b/clients/2011M/content/textures/blackBkg_square_slice8.png new file mode 100644 index 0000000..1bdb064 Binary files /dev/null and b/clients/2011M/content/textures/blackBkg_square_slice8.png differ diff --git a/clients/2011M/content/textures/blackBkg_square_slice9.png b/clients/2011M/content/textures/blackBkg_square_slice9.png new file mode 100644 index 0000000..42ee7dd Binary files /dev/null and b/clients/2011M/content/textures/blackBkg_square_slice9.png differ diff --git a/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice1.png b/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice1.png new file mode 100644 index 0000000..3a517df Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice1.png differ diff --git a/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice2.png b/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice2.png new file mode 100644 index 0000000..91edce1 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice2.png differ diff --git a/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice3.png b/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice3.png new file mode 100644 index 0000000..ba79476 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice3.png differ diff --git a/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice4.png b/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice4.png new file mode 100644 index 0000000..d0dc3df Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice4.png differ diff --git a/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice5.png b/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice5.png new file mode 100644 index 0000000..8a7c33c Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice5.png differ diff --git a/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice6.png b/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice6.png new file mode 100644 index 0000000..5212909 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice6.png differ diff --git a/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice7.png b/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice7.png new file mode 100644 index 0000000..1f5c6ac Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice7.png differ diff --git a/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice8.png b/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice8.png new file mode 100644 index 0000000..3afa0fc Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice8.png differ diff --git a/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice9.png b/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice9.png new file mode 100644 index 0000000..191a192 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botBlue_bkg_slice9.png differ diff --git a/clients/2011M/content/textures/chatBubble_botBlue_notify_bkg.png b/clients/2011M/content/textures/chatBubble_botBlue_notify_bkg.png new file mode 100644 index 0000000..0b03982 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botBlue_notify_bkg.png differ diff --git a/clients/2011M/content/textures/chatBubble_botBlue_tail.png b/clients/2011M/content/textures/chatBubble_botBlue_tail.png new file mode 100644 index 0000000..316bc9d Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botBlue_tail.png differ diff --git a/clients/2011M/content/textures/chatBubble_botBlue_tailRight.png b/clients/2011M/content/textures/chatBubble_botBlue_tailRight.png new file mode 100644 index 0000000..da047a8 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botBlue_tailRight.png differ diff --git a/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice1.png b/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice1.png new file mode 100644 index 0000000..3fbe960 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice1.png differ diff --git a/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice2.png b/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice2.png new file mode 100644 index 0000000..2ae6f3a Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice2.png differ diff --git a/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice3.png b/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice3.png new file mode 100644 index 0000000..2bd6c7d Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice3.png differ diff --git a/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice4.png b/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice4.png new file mode 100644 index 0000000..de96407 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice4.png differ diff --git a/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice5.png b/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice5.png new file mode 100644 index 0000000..e16fe70 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice5.png differ diff --git a/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice6.png b/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice6.png new file mode 100644 index 0000000..6674ec8 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice6.png differ diff --git a/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice7.png b/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice7.png new file mode 100644 index 0000000..e320ff8 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice7.png differ diff --git a/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice8.png b/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice8.png new file mode 100644 index 0000000..f491bd9 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice8.png differ diff --git a/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice9.png b/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice9.png new file mode 100644 index 0000000..233df27 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botGreen_bkg_slice9.png differ diff --git a/clients/2011M/content/textures/chatBubble_botGreen_notify_bkg.png b/clients/2011M/content/textures/chatBubble_botGreen_notify_bkg.png new file mode 100644 index 0000000..d0a0c47 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botGreen_notify_bkg.png differ diff --git a/clients/2011M/content/textures/chatBubble_botGreen_tail.png b/clients/2011M/content/textures/chatBubble_botGreen_tail.png new file mode 100644 index 0000000..01e6a00 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botGreen_tail.png differ diff --git a/clients/2011M/content/textures/chatBubble_botGreen_tailRight.png b/clients/2011M/content/textures/chatBubble_botGreen_tailRight.png new file mode 100644 index 0000000..8cd6293 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botGreen_tailRight.png differ diff --git a/clients/2011M/content/textures/chatBubble_botRed_bkg_slice1.png b/clients/2011M/content/textures/chatBubble_botRed_bkg_slice1.png new file mode 100644 index 0000000..5333b85 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botRed_bkg_slice1.png differ diff --git a/clients/2011M/content/textures/chatBubble_botRed_bkg_slice2.png b/clients/2011M/content/textures/chatBubble_botRed_bkg_slice2.png new file mode 100644 index 0000000..fe0c20a Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botRed_bkg_slice2.png differ diff --git a/clients/2011M/content/textures/chatBubble_botRed_bkg_slice3.png b/clients/2011M/content/textures/chatBubble_botRed_bkg_slice3.png new file mode 100644 index 0000000..10bf312 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botRed_bkg_slice3.png differ diff --git a/clients/2011M/content/textures/chatBubble_botRed_bkg_slice4.png b/clients/2011M/content/textures/chatBubble_botRed_bkg_slice4.png new file mode 100644 index 0000000..ce2290c Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botRed_bkg_slice4.png differ diff --git a/clients/2011M/content/textures/chatBubble_botRed_bkg_slice5.png b/clients/2011M/content/textures/chatBubble_botRed_bkg_slice5.png new file mode 100644 index 0000000..249820f Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botRed_bkg_slice5.png differ diff --git a/clients/2011M/content/textures/chatBubble_botRed_bkg_slice6.png b/clients/2011M/content/textures/chatBubble_botRed_bkg_slice6.png new file mode 100644 index 0000000..20522ae Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botRed_bkg_slice6.png differ diff --git a/clients/2011M/content/textures/chatBubble_botRed_bkg_slice7.png b/clients/2011M/content/textures/chatBubble_botRed_bkg_slice7.png new file mode 100644 index 0000000..1884ac7 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botRed_bkg_slice7.png differ diff --git a/clients/2011M/content/textures/chatBubble_botRed_bkg_slice8.png b/clients/2011M/content/textures/chatBubble_botRed_bkg_slice8.png new file mode 100644 index 0000000..a076bd9 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botRed_bkg_slice8.png differ diff --git a/clients/2011M/content/textures/chatBubble_botRed_bkg_slice9.png b/clients/2011M/content/textures/chatBubble_botRed_bkg_slice9.png new file mode 100644 index 0000000..1e1d1f8 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botRed_bkg_slice9.png differ diff --git a/clients/2011M/content/textures/chatBubble_botRed_notify_bkg.png b/clients/2011M/content/textures/chatBubble_botRed_notify_bkg.png new file mode 100644 index 0000000..e7376eb Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botRed_notify_bkg.png differ diff --git a/clients/2011M/content/textures/chatBubble_botRed_tail.png b/clients/2011M/content/textures/chatBubble_botRed_tail.png new file mode 100644 index 0000000..b29c2af Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botRed_tail.png differ diff --git a/clients/2011M/content/textures/chatBubble_botRed_tailRight.png b/clients/2011M/content/textures/chatBubble_botRed_tailRight.png new file mode 100644 index 0000000..1e39788 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_botRed_tailRight.png differ diff --git a/clients/2011M/content/textures/chatBubble_bot_notifyGray_dotDotDot.png b/clients/2011M/content/textures/chatBubble_bot_notifyGray_dotDotDot.png new file mode 100644 index 0000000..f5b017d Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_bot_notifyGray_dotDotDot.png differ diff --git a/clients/2011M/content/textures/chatBubble_bot_notify_bang.png b/clients/2011M/content/textures/chatBubble_bot_notify_bang.png new file mode 100644 index 0000000..1ccef6c Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_bot_notify_bang.png differ diff --git a/clients/2011M/content/textures/chatBubble_bot_notify_dotDotDot.png b/clients/2011M/content/textures/chatBubble_bot_notify_dotDotDot.png new file mode 100644 index 0000000..4318458 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_bot_notify_dotDotDot.png differ diff --git a/clients/2011M/content/textures/chatBubble_bot_notify_money.png b/clients/2011M/content/textures/chatBubble_bot_notify_money.png new file mode 100644 index 0000000..54f58c5 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_bot_notify_money.png differ diff --git a/clients/2011M/content/textures/chatBubble_bot_notify_question.png b/clients/2011M/content/textures/chatBubble_bot_notify_question.png new file mode 100644 index 0000000..0a91c4f Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_bot_notify_question.png differ diff --git a/clients/2011M/content/textures/chatBubble_white_bkg_slice1.png b/clients/2011M/content/textures/chatBubble_white_bkg_slice1.png new file mode 100644 index 0000000..4fb0066 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_white_bkg_slice1.png differ diff --git a/clients/2011M/content/textures/chatBubble_white_bkg_slice2.png b/clients/2011M/content/textures/chatBubble_white_bkg_slice2.png new file mode 100644 index 0000000..cde5050 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_white_bkg_slice2.png differ diff --git a/clients/2011M/content/textures/chatBubble_white_bkg_slice3.png b/clients/2011M/content/textures/chatBubble_white_bkg_slice3.png new file mode 100644 index 0000000..239083d Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_white_bkg_slice3.png differ diff --git a/clients/2011M/content/textures/chatBubble_white_bkg_slice4.png b/clients/2011M/content/textures/chatBubble_white_bkg_slice4.png new file mode 100644 index 0000000..e61a535 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_white_bkg_slice4.png differ diff --git a/clients/2011M/content/textures/chatBubble_white_bkg_slice5.png b/clients/2011M/content/textures/chatBubble_white_bkg_slice5.png new file mode 100644 index 0000000..4cf2795 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_white_bkg_slice5.png differ diff --git a/clients/2011M/content/textures/chatBubble_white_bkg_slice6.png b/clients/2011M/content/textures/chatBubble_white_bkg_slice6.png new file mode 100644 index 0000000..c28c9e6 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_white_bkg_slice6.png differ diff --git a/clients/2011M/content/textures/chatBubble_white_bkg_slice7.png b/clients/2011M/content/textures/chatBubble_white_bkg_slice7.png new file mode 100644 index 0000000..85ed1fd Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_white_bkg_slice7.png differ diff --git a/clients/2011M/content/textures/chatBubble_white_bkg_slice8.png b/clients/2011M/content/textures/chatBubble_white_bkg_slice8.png new file mode 100644 index 0000000..3661b4d Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_white_bkg_slice8.png differ diff --git a/clients/2011M/content/textures/chatBubble_white_bkg_slice9.png b/clients/2011M/content/textures/chatBubble_white_bkg_slice9.png new file mode 100644 index 0000000..32b6b96 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_white_bkg_slice9.png differ diff --git a/clients/2011M/content/textures/chatBubble_white_notify_bkg.png b/clients/2011M/content/textures/chatBubble_white_notify_bkg.png new file mode 100644 index 0000000..828e362 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_white_notify_bkg.png differ diff --git a/clients/2011M/content/textures/chatBubble_white_tail.png b/clients/2011M/content/textures/chatBubble_white_tail.png new file mode 100644 index 0000000..77d1bd4 Binary files /dev/null and b/clients/2011M/content/textures/chatBubble_white_tail.png differ diff --git a/clients/2011M/content/textures/dirt.jpg b/clients/2011M/content/textures/dirt.jpg new file mode 100644 index 0000000..05f5c94 Binary files /dev/null and b/clients/2011M/content/textures/dirt.jpg differ diff --git a/clients/2011M/content/textures/explosion.png b/clients/2011M/content/textures/explosion.png new file mode 100644 index 0000000..576724e Binary files /dev/null and b/clients/2011M/content/textures/explosion.png differ diff --git a/clients/2011M/content/textures/face.png b/clients/2011M/content/textures/face.png new file mode 100644 index 0000000..5555669 Binary files /dev/null and b/clients/2011M/content/textures/face.png differ diff --git a/clients/2011M/content/textures/fire_0.png b/clients/2011M/content/textures/fire_0.png new file mode 100644 index 0000000..1ae8d2b Binary files /dev/null and b/clients/2011M/content/textures/fire_0.png differ diff --git a/clients/2011M/content/textures/glow.png b/clients/2011M/content/textures/glow.png new file mode 100644 index 0000000..0f2863f Binary files /dev/null and b/clients/2011M/content/textures/glow.png differ diff --git a/clients/2011M/content/textures/lua.png b/clients/2011M/content/textures/lua.png new file mode 100644 index 0000000..2791c43 Binary files /dev/null and b/clients/2011M/content/textures/lua.png differ diff --git a/clients/2011M/content/textures/noiseL8_32x32x32.dds b/clients/2011M/content/textures/noiseL8_32x32x32.dds new file mode 100644 index 0000000..8b310d8 Binary files /dev/null and b/clients/2011M/content/textures/noiseL8_32x32x32.dds differ diff --git a/clients/2011M/content/textures/nosurfacesAlpha.png b/clients/2011M/content/textures/nosurfacesAlpha.png new file mode 100644 index 0000000..923e4cb Binary files /dev/null and b/clients/2011M/content/textures/nosurfacesAlpha.png differ diff --git a/clients/2011M/content/textures/nosurfacesTruss.png b/clients/2011M/content/textures/nosurfacesTruss.png new file mode 100644 index 0000000..2b9c0ee Binary files /dev/null and b/clients/2011M/content/textures/nosurfacesTruss.png differ diff --git a/clients/2011M/content/textures/nosurfacesTrussAlpha.png b/clients/2011M/content/textures/nosurfacesTrussAlpha.png new file mode 100644 index 0000000..b51220c Binary files /dev/null and b/clients/2011M/content/textures/nosurfacesTrussAlpha.png differ diff --git a/clients/2011M/content/textures/penv.dds b/clients/2011M/content/textures/penv.dds new file mode 100644 index 0000000..a1b79f0 Binary files /dev/null and b/clients/2011M/content/textures/penv.dds differ diff --git a/clients/2011M/content/textures/rust_combined.png b/clients/2011M/content/textures/rust_combined.png new file mode 100644 index 0000000..88eb248 Binary files /dev/null and b/clients/2011M/content/textures/rust_combined.png differ diff --git a/clients/2011M/content/textures/script.png b/clients/2011M/content/textures/script.png new file mode 100644 index 0000000..0f9ed4d Binary files /dev/null and b/clients/2011M/content/textures/script.png differ diff --git a/clients/2011M/content/textures/spark.png b/clients/2011M/content/textures/spark.png new file mode 100644 index 0000000..5c2cd1d Binary files /dev/null and b/clients/2011M/content/textures/spark.png differ diff --git a/clients/2011M/content/textures/sparkle.png b/clients/2011M/content/textures/sparkle.png new file mode 100644 index 0000000..5fa5e2a Binary files /dev/null and b/clients/2011M/content/textures/sparkle.png differ diff --git a/clients/2011M/content/textures/surfacesAlpha.png b/clients/2011M/content/textures/surfacesAlpha.png new file mode 100644 index 0000000..68d4b14 Binary files /dev/null and b/clients/2011M/content/textures/surfacesAlpha.png differ diff --git a/clients/2011M/content/textures/surfacesTrussAlpha.png b/clients/2011M/content/textures/surfacesTrussAlpha.png new file mode 100644 index 0000000..5a336d7 Binary files /dev/null and b/clients/2011M/content/textures/surfacesTrussAlpha.png differ diff --git a/clients/2011M/content/textures/ui/BottomRightControl.png b/clients/2011M/content/textures/ui/BottomRightControl.png new file mode 100644 index 0000000..233ee27 Binary files /dev/null and b/clients/2011M/content/textures/ui/BottomRightControl.png differ diff --git a/clients/2011M/content/textures/ui/BuildToolsFrame.png b/clients/2011M/content/textures/ui/BuildToolsFrame.png new file mode 100644 index 0000000..39ba9c8 Binary files /dev/null and b/clients/2011M/content/textures/ui/BuildToolsFrame.png differ diff --git a/clients/2011M/content/textures/ui/CloneButton.png b/clients/2011M/content/textures/ui/CloneButton.png new file mode 100644 index 0000000..7e24cc6 Binary files /dev/null and b/clients/2011M/content/textures/ui/CloneButton.png differ diff --git a/clients/2011M/content/textures/ui/CloneButton_dn.png b/clients/2011M/content/textures/ui/CloneButton_dn.png new file mode 100644 index 0000000..adbfe60 Binary files /dev/null and b/clients/2011M/content/textures/ui/CloneButton_dn.png differ diff --git a/clients/2011M/content/textures/ui/CloseButton.png b/clients/2011M/content/textures/ui/CloseButton.png new file mode 100644 index 0000000..59d62c0 Binary files /dev/null and b/clients/2011M/content/textures/ui/CloseButton.png differ diff --git a/clients/2011M/content/textures/ui/CloseButton_dn.png b/clients/2011M/content/textures/ui/CloseButton_dn.png new file mode 100644 index 0000000..2a92663 Binary files /dev/null and b/clients/2011M/content/textures/ui/CloseButton_dn.png differ diff --git a/clients/2011M/content/textures/ui/Concrete.png b/clients/2011M/content/textures/ui/Concrete.png new file mode 100644 index 0000000..79ee458 Binary files /dev/null and b/clients/2011M/content/textures/ui/Concrete.png differ diff --git a/clients/2011M/content/textures/ui/CorrodedMetal.png b/clients/2011M/content/textures/ui/CorrodedMetal.png new file mode 100644 index 0000000..76483c7 Binary files /dev/null and b/clients/2011M/content/textures/ui/CorrodedMetal.png differ diff --git a/clients/2011M/content/textures/ui/DeleteButton.png b/clients/2011M/content/textures/ui/DeleteButton.png new file mode 100644 index 0000000..7f5757c Binary files /dev/null and b/clients/2011M/content/textures/ui/DeleteButton.png differ diff --git a/clients/2011M/content/textures/ui/DeleteButton_dn.png b/clients/2011M/content/textures/ui/DeleteButton_dn.png new file mode 100644 index 0000000..184a615 Binary files /dev/null and b/clients/2011M/content/textures/ui/DeleteButton_dn.png differ diff --git a/clients/2011M/content/textures/ui/DiamondPlate.png b/clients/2011M/content/textures/ui/DiamondPlate.png new file mode 100644 index 0000000..ad9d4d0 Binary files /dev/null and b/clients/2011M/content/textures/ui/DiamondPlate.png differ diff --git a/clients/2011M/content/textures/ui/Div.png b/clients/2011M/content/textures/ui/Div.png new file mode 100644 index 0000000..a8352fe Binary files /dev/null and b/clients/2011M/content/textures/ui/Div.png differ diff --git a/clients/2011M/content/textures/ui/Foil.png b/clients/2011M/content/textures/ui/Foil.png new file mode 100644 index 0000000..7cf51fc Binary files /dev/null and b/clients/2011M/content/textures/ui/Foil.png differ diff --git a/clients/2011M/content/textures/ui/Gear.png b/clients/2011M/content/textures/ui/Gear.png new file mode 100644 index 0000000..de60a6a Binary files /dev/null and b/clients/2011M/content/textures/ui/Gear.png differ diff --git a/clients/2011M/content/textures/ui/Gear_dn.png b/clients/2011M/content/textures/ui/Gear_dn.png new file mode 100644 index 0000000..53c8366 Binary files /dev/null and b/clients/2011M/content/textures/ui/Gear_dn.png differ diff --git a/clients/2011M/content/textures/ui/Glue.png b/clients/2011M/content/textures/ui/Glue.png new file mode 100644 index 0000000..3ceed9c Binary files /dev/null and b/clients/2011M/content/textures/ui/Glue.png differ diff --git a/clients/2011M/content/textures/ui/Grass.png b/clients/2011M/content/textures/ui/Grass.png new file mode 100644 index 0000000..fd390c4 Binary files /dev/null and b/clients/2011M/content/textures/ui/Grass.png differ diff --git a/clients/2011M/content/textures/ui/GroupMoveButton.png b/clients/2011M/content/textures/ui/GroupMoveButton.png new file mode 100644 index 0000000..61a48b4 Binary files /dev/null and b/clients/2011M/content/textures/ui/GroupMoveButton.png differ diff --git a/clients/2011M/content/textures/ui/GroupMoveButton_dn.png b/clients/2011M/content/textures/ui/GroupMoveButton_dn.png new file mode 100644 index 0000000..7500d53 Binary files /dev/null and b/clients/2011M/content/textures/ui/GroupMoveButton_dn.png differ diff --git a/clients/2011M/content/textures/ui/Hinge.png b/clients/2011M/content/textures/ui/Hinge.png new file mode 100644 index 0000000..c2ab9c9 Binary files /dev/null and b/clients/2011M/content/textures/ui/Hinge.png differ diff --git a/clients/2011M/content/textures/ui/Ice.png b/clients/2011M/content/textures/ui/Ice.png new file mode 100644 index 0000000..e9d0a32 Binary files /dev/null and b/clients/2011M/content/textures/ui/Ice.png differ diff --git a/clients/2011M/content/textures/ui/Inlets.png b/clients/2011M/content/textures/ui/Inlets.png new file mode 100644 index 0000000..cac89e3 Binary files /dev/null and b/clients/2011M/content/textures/ui/Inlets.png differ diff --git a/clients/2011M/content/textures/ui/InsertButton.png b/clients/2011M/content/textures/ui/InsertButton.png new file mode 100644 index 0000000..4058f36 Binary files /dev/null and b/clients/2011M/content/textures/ui/InsertButton.png differ diff --git a/clients/2011M/content/textures/ui/InsertButton_dn.png b/clients/2011M/content/textures/ui/InsertButton_dn.png new file mode 100644 index 0000000..03e72b2 Binary files /dev/null and b/clients/2011M/content/textures/ui/InsertButton_dn.png differ diff --git a/clients/2011M/content/textures/ui/MaterialButton.png b/clients/2011M/content/textures/ui/MaterialButton.png new file mode 100644 index 0000000..4191aab Binary files /dev/null and b/clients/2011M/content/textures/ui/MaterialButton.png differ diff --git a/clients/2011M/content/textures/ui/MaterialButton_dn.png b/clients/2011M/content/textures/ui/MaterialButton_dn.png new file mode 100644 index 0000000..d61978c Binary files /dev/null and b/clients/2011M/content/textures/ui/MaterialButton_dn.png differ diff --git a/clients/2011M/content/textures/ui/MaterialMenu.png b/clients/2011M/content/textures/ui/MaterialMenu.png new file mode 100644 index 0000000..c4a1c73 Binary files /dev/null and b/clients/2011M/content/textures/ui/MaterialMenu.png differ diff --git a/clients/2011M/content/textures/ui/Motor.png b/clients/2011M/content/textures/ui/Motor.png new file mode 100644 index 0000000..e9b63eb Binary files /dev/null and b/clients/2011M/content/textures/ui/Motor.png differ diff --git a/clients/2011M/content/textures/ui/PaintButton.png b/clients/2011M/content/textures/ui/PaintButton.png new file mode 100644 index 0000000..03b99a7 Binary files /dev/null and b/clients/2011M/content/textures/ui/PaintButton.png differ diff --git a/clients/2011M/content/textures/ui/PaintButton_dn.png b/clients/2011M/content/textures/ui/PaintButton_dn.png new file mode 100644 index 0000000..af4c64d Binary files /dev/null and b/clients/2011M/content/textures/ui/PaintButton_dn.png differ diff --git a/clients/2011M/content/textures/ui/PaintMenu.png b/clients/2011M/content/textures/ui/PaintMenu.png new file mode 100644 index 0000000..1824803 Binary files /dev/null and b/clients/2011M/content/textures/ui/PaintMenu.png differ diff --git a/clients/2011M/content/textures/ui/PartMoveButton.png b/clients/2011M/content/textures/ui/PartMoveButton.png new file mode 100644 index 0000000..a8f8fce Binary files /dev/null and b/clients/2011M/content/textures/ui/PartMoveButton.png differ diff --git a/clients/2011M/content/textures/ui/PartMoveButton_dn.png b/clients/2011M/content/textures/ui/PartMoveButton_dn.png new file mode 100644 index 0000000..3c866db Binary files /dev/null and b/clients/2011M/content/textures/ui/PartMoveButton_dn.png differ diff --git a/clients/2011M/content/textures/ui/Plastic.png b/clients/2011M/content/textures/ui/Plastic.png new file mode 100644 index 0000000..8f8bbf3 Binary files /dev/null and b/clients/2011M/content/textures/ui/Plastic.png differ diff --git a/clients/2011M/content/textures/ui/PlayerListFriendRequestReceivedIcon.png b/clients/2011M/content/textures/ui/PlayerListFriendRequestReceivedIcon.png new file mode 100644 index 0000000..ab292da Binary files /dev/null and b/clients/2011M/content/textures/ui/PlayerListFriendRequestReceivedIcon.png differ diff --git a/clients/2011M/content/textures/ui/PlayerListFriendRequestSentIcon.png b/clients/2011M/content/textures/ui/PlayerListFriendRequestSentIcon.png new file mode 100644 index 0000000..e10634b Binary files /dev/null and b/clients/2011M/content/textures/ui/PlayerListFriendRequestSentIcon.png differ diff --git a/clients/2011M/content/textures/ui/PlayerlistFriendIcon.png b/clients/2011M/content/textures/ui/PlayerlistFriendIcon.png new file mode 100644 index 0000000..21619a5 Binary files /dev/null and b/clients/2011M/content/textures/ui/PlayerlistFriendIcon.png differ diff --git a/clients/2011M/content/textures/ui/PropertyButton.png b/clients/2011M/content/textures/ui/PropertyButton.png new file mode 100644 index 0000000..254e00d Binary files /dev/null and b/clients/2011M/content/textures/ui/PropertyButton.png differ diff --git a/clients/2011M/content/textures/ui/PropertyButton_dn.png b/clients/2011M/content/textures/ui/PropertyButton_dn.png new file mode 100644 index 0000000..c95ec8d Binary files /dev/null and b/clients/2011M/content/textures/ui/PropertyButton_dn.png differ diff --git a/clients/2011M/content/textures/ui/RecordStop.png b/clients/2011M/content/textures/ui/RecordStop.png new file mode 100644 index 0000000..6b86baf Binary files /dev/null and b/clients/2011M/content/textures/ui/RecordStop.png differ diff --git a/clients/2011M/content/textures/ui/ResetIcon.png b/clients/2011M/content/textures/ui/ResetIcon.png new file mode 100644 index 0000000..b9558d4 Binary files /dev/null and b/clients/2011M/content/textures/ui/ResetIcon.png differ diff --git a/clients/2011M/content/textures/ui/ScaleButton.png b/clients/2011M/content/textures/ui/ScaleButton.png new file mode 100644 index 0000000..05ab151 Binary files /dev/null and b/clients/2011M/content/textures/ui/ScaleButton.png differ diff --git a/clients/2011M/content/textures/ui/ScaleButton_dn.png b/clients/2011M/content/textures/ui/ScaleButton_dn.png new file mode 100644 index 0000000..c5010fa Binary files /dev/null and b/clients/2011M/content/textures/ui/ScaleButton_dn.png differ diff --git a/clients/2011M/content/textures/ui/SearchIcon.png b/clients/2011M/content/textures/ui/SearchIcon.png new file mode 100644 index 0000000..d72741c Binary files /dev/null and b/clients/2011M/content/textures/ui/SearchIcon.png differ diff --git a/clients/2011M/content/textures/ui/SettingsButton.png b/clients/2011M/content/textures/ui/SettingsButton.png new file mode 100644 index 0000000..196cf23 Binary files /dev/null and b/clients/2011M/content/textures/ui/SettingsButton.png differ diff --git a/clients/2011M/content/textures/ui/SettingsButton_dn.png b/clients/2011M/content/textures/ui/SettingsButton_dn.png new file mode 100644 index 0000000..e6f4799 Binary files /dev/null and b/clients/2011M/content/textures/ui/SettingsButton_dn.png differ diff --git a/clients/2011M/content/textures/ui/SettingsButton_ds.png b/clients/2011M/content/textures/ui/SettingsButton_ds.png new file mode 100644 index 0000000..2aca460 Binary files /dev/null and b/clients/2011M/content/textures/ui/SettingsButton_ds.png differ diff --git a/clients/2011M/content/textures/ui/SettingsButton_ovr.png b/clients/2011M/content/textures/ui/SettingsButton_ovr.png new file mode 100644 index 0000000..e6f4799 Binary files /dev/null and b/clients/2011M/content/textures/ui/SettingsButton_ovr.png differ diff --git a/clients/2011M/content/textures/ui/SettingsIcon.png b/clients/2011M/content/textures/ui/SettingsIcon.png new file mode 100644 index 0000000..c6cfd20 Binary files /dev/null and b/clients/2011M/content/textures/ui/SettingsIcon.png differ diff --git a/clients/2011M/content/textures/ui/Slate.png b/clients/2011M/content/textures/ui/Slate.png new file mode 100644 index 0000000..4f90fb8 Binary files /dev/null and b/clients/2011M/content/textures/ui/Slate.png differ diff --git a/clients/2011M/content/textures/ui/Slider.png b/clients/2011M/content/textures/ui/Slider.png new file mode 100644 index 0000000..63c4dea Binary files /dev/null and b/clients/2011M/content/textures/ui/Slider.png differ diff --git a/clients/2011M/content/textures/ui/Slider_dn.png b/clients/2011M/content/textures/ui/Slider_dn.png new file mode 100644 index 0000000..d98cb85 Binary files /dev/null and b/clients/2011M/content/textures/ui/Slider_dn.png differ diff --git a/clients/2011M/content/textures/ui/Slider_sel.png b/clients/2011M/content/textures/ui/Slider_sel.png new file mode 100644 index 0000000..d98cb85 Binary files /dev/null and b/clients/2011M/content/textures/ui/Slider_sel.png differ diff --git a/clients/2011M/content/textures/ui/Smooth.png b/clients/2011M/content/textures/ui/Smooth.png new file mode 100644 index 0000000..e4d6c4d Binary files /dev/null and b/clients/2011M/content/textures/ui/Smooth.png differ diff --git a/clients/2011M/content/textures/ui/StampToolButton.png b/clients/2011M/content/textures/ui/StampToolButton.png new file mode 100644 index 0000000..34e7994 Binary files /dev/null and b/clients/2011M/content/textures/ui/StampToolButton.png differ diff --git a/clients/2011M/content/textures/ui/StampToolButton_dn.png b/clients/2011M/content/textures/ui/StampToolButton_dn.png new file mode 100644 index 0000000..affebf4 Binary files /dev/null and b/clients/2011M/content/textures/ui/StampToolButton_dn.png differ diff --git a/clients/2011M/content/textures/ui/Studs.png b/clients/2011M/content/textures/ui/Studs.png new file mode 100644 index 0000000..194a02b Binary files /dev/null and b/clients/2011M/content/textures/ui/Studs.png differ diff --git a/clients/2011M/content/textures/ui/SurfaceButton.png b/clients/2011M/content/textures/ui/SurfaceButton.png new file mode 100644 index 0000000..78c90f0 Binary files /dev/null and b/clients/2011M/content/textures/ui/SurfaceButton.png differ diff --git a/clients/2011M/content/textures/ui/SurfaceButton_dn.png b/clients/2011M/content/textures/ui/SurfaceButton_dn.png new file mode 100644 index 0000000..850e099 Binary files /dev/null and b/clients/2011M/content/textures/ui/SurfaceButton_dn.png differ diff --git a/clients/2011M/content/textures/ui/SurfaceMenu.png b/clients/2011M/content/textures/ui/SurfaceMenu.png new file mode 100644 index 0000000..1582479 Binary files /dev/null and b/clients/2011M/content/textures/ui/SurfaceMenu.png differ diff --git a/clients/2011M/content/textures/ui/TinyBcIcon.png b/clients/2011M/content/textures/ui/TinyBcIcon.png new file mode 100644 index 0000000..1e2c7ef Binary files /dev/null and b/clients/2011M/content/textures/ui/TinyBcIcon.png differ diff --git a/clients/2011M/content/textures/ui/TinyObcIcon.png b/clients/2011M/content/textures/ui/TinyObcIcon.png new file mode 100644 index 0000000..f12104d Binary files /dev/null and b/clients/2011M/content/textures/ui/TinyObcIcon.png differ diff --git a/clients/2011M/content/textures/ui/TinyTbcIcon.png b/clients/2011M/content/textures/ui/TinyTbcIcon.png new file mode 100644 index 0000000..d5c37fe Binary files /dev/null and b/clients/2011M/content/textures/ui/TinyTbcIcon.png differ diff --git a/clients/2011M/content/textures/ui/ToggleFullScreen_ds.png b/clients/2011M/content/textures/ui/ToggleFullScreen_ds.png new file mode 100644 index 0000000..07d7de0 Binary files /dev/null and b/clients/2011M/content/textures/ui/ToggleFullScreen_ds.png differ diff --git a/clients/2011M/content/textures/ui/ToolButton.png b/clients/2011M/content/textures/ui/ToolButton.png new file mode 100644 index 0000000..ca9a395 Binary files /dev/null and b/clients/2011M/content/textures/ui/ToolButton.png differ diff --git a/clients/2011M/content/textures/ui/ToolButton_dn.png b/clients/2011M/content/textures/ui/ToolButton_dn.png new file mode 100644 index 0000000..e53c826 Binary files /dev/null and b/clients/2011M/content/textures/ui/ToolButton_dn.png differ diff --git a/clients/2011M/content/textures/ui/ToolButton_ds.png b/clients/2011M/content/textures/ui/ToolButton_ds.png new file mode 100644 index 0000000..016ae9c Binary files /dev/null and b/clients/2011M/content/textures/ui/ToolButton_ds.png differ diff --git a/clients/2011M/content/textures/ui/Universal.png b/clients/2011M/content/textures/ui/Universal.png new file mode 100644 index 0000000..508fac8 Binary files /dev/null and b/clients/2011M/content/textures/ui/Universal.png differ diff --git a/clients/2011M/content/textures/ui/Weld.png b/clients/2011M/content/textures/ui/Weld.png new file mode 100644 index 0000000..d45375b Binary files /dev/null and b/clients/2011M/content/textures/ui/Weld.png differ diff --git a/clients/2011M/content/textures/ui/Wood.png b/clients/2011M/content/textures/ui/Wood.png new file mode 100644 index 0000000..93898de Binary files /dev/null and b/clients/2011M/content/textures/ui/Wood.png differ diff --git a/clients/2011M/content/textures/ui/backpackButton.png b/clients/2011M/content/textures/ui/backpackButton.png new file mode 100644 index 0000000..d84355c Binary files /dev/null and b/clients/2011M/content/textures/ui/backpackButton.png differ diff --git a/clients/2011M/content/textures/ui/backpackButton_ovr.png b/clients/2011M/content/textures/ui/backpackButton_ovr.png new file mode 100644 index 0000000..2c9c84d Binary files /dev/null and b/clients/2011M/content/textures/ui/backpackButton_ovr.png differ diff --git a/clients/2011M/content/textures/ui/backpackButton_sel.png b/clients/2011M/content/textures/ui/backpackButton_sel.png new file mode 100644 index 0000000..2c9c84d Binary files /dev/null and b/clients/2011M/content/textures/ui/backpackButton_sel.png differ diff --git a/clients/2011M/content/textures/ui/bottomLeftControl.png b/clients/2011M/content/textures/ui/bottomLeftControl.png new file mode 100644 index 0000000..234b854 Binary files /dev/null and b/clients/2011M/content/textures/ui/bottomLeftControl.png differ diff --git a/clients/2011M/content/textures/ui/btn_greyTransp_slice1.png b/clients/2011M/content/textures/ui/btn_greyTransp_slice1.png new file mode 100644 index 0000000..bb29bb6 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_greyTransp_slice1.png differ diff --git a/clients/2011M/content/textures/ui/btn_greyTransp_slice2.png b/clients/2011M/content/textures/ui/btn_greyTransp_slice2.png new file mode 100644 index 0000000..76f2e14 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_greyTransp_slice2.png differ diff --git a/clients/2011M/content/textures/ui/btn_greyTransp_slice3.png b/clients/2011M/content/textures/ui/btn_greyTransp_slice3.png new file mode 100644 index 0000000..d0fc42a Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_greyTransp_slice3.png differ diff --git a/clients/2011M/content/textures/ui/btn_greyTransp_slice4.png b/clients/2011M/content/textures/ui/btn_greyTransp_slice4.png new file mode 100644 index 0000000..5bf89f8 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_greyTransp_slice4.png differ diff --git a/clients/2011M/content/textures/ui/btn_greyTransp_slice5.png b/clients/2011M/content/textures/ui/btn_greyTransp_slice5.png new file mode 100644 index 0000000..c420ca5 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_greyTransp_slice5.png differ diff --git a/clients/2011M/content/textures/ui/btn_greyTransp_slice6.png b/clients/2011M/content/textures/ui/btn_greyTransp_slice6.png new file mode 100644 index 0000000..72b5b28 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_greyTransp_slice6.png differ diff --git a/clients/2011M/content/textures/ui/btn_greyTransp_slice7.png b/clients/2011M/content/textures/ui/btn_greyTransp_slice7.png new file mode 100644 index 0000000..e149e73 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_greyTransp_slice7.png differ diff --git a/clients/2011M/content/textures/ui/btn_greyTransp_slice8.png b/clients/2011M/content/textures/ui/btn_greyTransp_slice8.png new file mode 100644 index 0000000..7f43c9a Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_greyTransp_slice8.png differ diff --git a/clients/2011M/content/textures/ui/btn_greyTransp_slice9.png b/clients/2011M/content/textures/ui/btn_greyTransp_slice9.png new file mode 100644 index 0000000..43623f8 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_greyTransp_slice9.png differ diff --git a/clients/2011M/content/textures/ui/btn_grey_slice1.png b/clients/2011M/content/textures/ui/btn_grey_slice1.png new file mode 100644 index 0000000..5079637 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_grey_slice1.png differ diff --git a/clients/2011M/content/textures/ui/btn_grey_slice2.png b/clients/2011M/content/textures/ui/btn_grey_slice2.png new file mode 100644 index 0000000..53b76ac Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_grey_slice2.png differ diff --git a/clients/2011M/content/textures/ui/btn_grey_slice3.png b/clients/2011M/content/textures/ui/btn_grey_slice3.png new file mode 100644 index 0000000..f274b30 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_grey_slice3.png differ diff --git a/clients/2011M/content/textures/ui/btn_grey_slice4.png b/clients/2011M/content/textures/ui/btn_grey_slice4.png new file mode 100644 index 0000000..2799dab Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_grey_slice4.png differ diff --git a/clients/2011M/content/textures/ui/btn_grey_slice5.png b/clients/2011M/content/textures/ui/btn_grey_slice5.png new file mode 100644 index 0000000..c420ca5 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_grey_slice5.png differ diff --git a/clients/2011M/content/textures/ui/btn_grey_slice6.png b/clients/2011M/content/textures/ui/btn_grey_slice6.png new file mode 100644 index 0000000..fd7dce6 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_grey_slice6.png differ diff --git a/clients/2011M/content/textures/ui/btn_grey_slice7.png b/clients/2011M/content/textures/ui/btn_grey_slice7.png new file mode 100644 index 0000000..ffd489b Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_grey_slice7.png differ diff --git a/clients/2011M/content/textures/ui/btn_grey_slice8.png b/clients/2011M/content/textures/ui/btn_grey_slice8.png new file mode 100644 index 0000000..0001dfb Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_grey_slice8.png differ diff --git a/clients/2011M/content/textures/ui/btn_grey_slice9.png b/clients/2011M/content/textures/ui/btn_grey_slice9.png new file mode 100644 index 0000000..1a99844 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_grey_slice9.png differ diff --git a/clients/2011M/content/textures/ui/btn_redGlow_slice1.png b/clients/2011M/content/textures/ui/btn_redGlow_slice1.png new file mode 100644 index 0000000..1ae9006 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_redGlow_slice1.png differ diff --git a/clients/2011M/content/textures/ui/btn_redGlow_slice2.png b/clients/2011M/content/textures/ui/btn_redGlow_slice2.png new file mode 100644 index 0000000..59c22d0 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_redGlow_slice2.png differ diff --git a/clients/2011M/content/textures/ui/btn_redGlow_slice3.png b/clients/2011M/content/textures/ui/btn_redGlow_slice3.png new file mode 100644 index 0000000..5077298 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_redGlow_slice3.png differ diff --git a/clients/2011M/content/textures/ui/btn_redGlow_slice4.png b/clients/2011M/content/textures/ui/btn_redGlow_slice4.png new file mode 100644 index 0000000..a3b9723 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_redGlow_slice4.png differ diff --git a/clients/2011M/content/textures/ui/btn_redGlow_slice5.png b/clients/2011M/content/textures/ui/btn_redGlow_slice5.png new file mode 100644 index 0000000..c420ca5 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_redGlow_slice5.png differ diff --git a/clients/2011M/content/textures/ui/btn_redGlow_slice6.png b/clients/2011M/content/textures/ui/btn_redGlow_slice6.png new file mode 100644 index 0000000..66e8472 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_redGlow_slice6.png differ diff --git a/clients/2011M/content/textures/ui/btn_redGlow_slice7.png b/clients/2011M/content/textures/ui/btn_redGlow_slice7.png new file mode 100644 index 0000000..936b394 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_redGlow_slice7.png differ diff --git a/clients/2011M/content/textures/ui/btn_redGlow_slice8.png b/clients/2011M/content/textures/ui/btn_redGlow_slice8.png new file mode 100644 index 0000000..1f9d57f Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_redGlow_slice8.png differ diff --git a/clients/2011M/content/textures/ui/btn_redGlow_slice9.png b/clients/2011M/content/textures/ui/btn_redGlow_slice9.png new file mode 100644 index 0000000..9480f09 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_redGlow_slice9.png differ diff --git a/clients/2011M/content/textures/ui/btn_red_slice1.png b/clients/2011M/content/textures/ui/btn_red_slice1.png new file mode 100644 index 0000000..e3e66be Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_red_slice1.png differ diff --git a/clients/2011M/content/textures/ui/btn_red_slice2.png b/clients/2011M/content/textures/ui/btn_red_slice2.png new file mode 100644 index 0000000..c6010ca Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_red_slice2.png differ diff --git a/clients/2011M/content/textures/ui/btn_red_slice3.png b/clients/2011M/content/textures/ui/btn_red_slice3.png new file mode 100644 index 0000000..a4224b9 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_red_slice3.png differ diff --git a/clients/2011M/content/textures/ui/btn_red_slice4.png b/clients/2011M/content/textures/ui/btn_red_slice4.png new file mode 100644 index 0000000..7af2b1b Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_red_slice4.png differ diff --git a/clients/2011M/content/textures/ui/btn_red_slice5.png b/clients/2011M/content/textures/ui/btn_red_slice5.png new file mode 100644 index 0000000..c420ca5 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_red_slice5.png differ diff --git a/clients/2011M/content/textures/ui/btn_red_slice6.png b/clients/2011M/content/textures/ui/btn_red_slice6.png new file mode 100644 index 0000000..de5e8c6 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_red_slice6.png differ diff --git a/clients/2011M/content/textures/ui/btn_red_slice7.png b/clients/2011M/content/textures/ui/btn_red_slice7.png new file mode 100644 index 0000000..6ea6562 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_red_slice7.png differ diff --git a/clients/2011M/content/textures/ui/btn_red_slice8.png b/clients/2011M/content/textures/ui/btn_red_slice8.png new file mode 100644 index 0000000..9ac77e4 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_red_slice8.png differ diff --git a/clients/2011M/content/textures/ui/btn_red_slice9.png b/clients/2011M/content/textures/ui/btn_red_slice9.png new file mode 100644 index 0000000..a55b713 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_red_slice9.png differ diff --git a/clients/2011M/content/textures/ui/btn_white_slice1.png b/clients/2011M/content/textures/ui/btn_white_slice1.png new file mode 100644 index 0000000..870cbdc Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_white_slice1.png differ diff --git a/clients/2011M/content/textures/ui/btn_white_slice2.png b/clients/2011M/content/textures/ui/btn_white_slice2.png new file mode 100644 index 0000000..1d1c73c Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_white_slice2.png differ diff --git a/clients/2011M/content/textures/ui/btn_white_slice3.png b/clients/2011M/content/textures/ui/btn_white_slice3.png new file mode 100644 index 0000000..28632f8 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_white_slice3.png differ diff --git a/clients/2011M/content/textures/ui/btn_white_slice4.png b/clients/2011M/content/textures/ui/btn_white_slice4.png new file mode 100644 index 0000000..2b9b9f9 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_white_slice4.png differ diff --git a/clients/2011M/content/textures/ui/btn_white_slice5.png b/clients/2011M/content/textures/ui/btn_white_slice5.png new file mode 100644 index 0000000..c420ca5 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_white_slice5.png differ diff --git a/clients/2011M/content/textures/ui/btn_white_slice6.png b/clients/2011M/content/textures/ui/btn_white_slice6.png new file mode 100644 index 0000000..c8e9ec7 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_white_slice6.png differ diff --git a/clients/2011M/content/textures/ui/btn_white_slice7.png b/clients/2011M/content/textures/ui/btn_white_slice7.png new file mode 100644 index 0000000..256140f Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_white_slice7.png differ diff --git a/clients/2011M/content/textures/ui/btn_white_slice8.png b/clients/2011M/content/textures/ui/btn_white_slice8.png new file mode 100644 index 0000000..a74ba61 Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_white_slice8.png differ diff --git a/clients/2011M/content/textures/ui/btn_white_slice9.png b/clients/2011M/content/textures/ui/btn_white_slice9.png new file mode 100644 index 0000000..8c2039e Binary files /dev/null and b/clients/2011M/content/textures/ui/btn_white_slice9.png differ diff --git a/clients/2011M/content/textures/ui/mouseLock_off.png b/clients/2011M/content/textures/ui/mouseLock_off.png new file mode 100644 index 0000000..e170d2c Binary files /dev/null and b/clients/2011M/content/textures/ui/mouseLock_off.png differ diff --git a/clients/2011M/content/textures/ui/mouseLock_off_ds.png b/clients/2011M/content/textures/ui/mouseLock_off_ds.png new file mode 100644 index 0000000..85b9a10 Binary files /dev/null and b/clients/2011M/content/textures/ui/mouseLock_off_ds.png differ diff --git a/clients/2011M/content/textures/ui/mouseLock_off_ovr.png b/clients/2011M/content/textures/ui/mouseLock_off_ovr.png new file mode 100644 index 0000000..6c06e1e Binary files /dev/null and b/clients/2011M/content/textures/ui/mouseLock_off_ovr.png differ diff --git a/clients/2011M/content/textures/ui/mouseLock_on.png b/clients/2011M/content/textures/ui/mouseLock_on.png new file mode 100644 index 0000000..caa9d52 Binary files /dev/null and b/clients/2011M/content/textures/ui/mouseLock_on.png differ diff --git a/clients/2011M/content/textures/ui/mouseLock_on_ds.png b/clients/2011M/content/textures/ui/mouseLock_on_ds.png new file mode 100644 index 0000000..0fa160e Binary files /dev/null and b/clients/2011M/content/textures/ui/mouseLock_on_ds.png differ diff --git a/clients/2011M/content/textures/ui/mouseLock_on_ovr.png b/clients/2011M/content/textures/ui/mouseLock_on_ovr.png new file mode 100644 index 0000000..653535f Binary files /dev/null and b/clients/2011M/content/textures/ui/mouseLock_on_ovr.png differ diff --git a/clients/2011M/content/textures/ui/playerlist_big_hide.png b/clients/2011M/content/textures/ui/playerlist_big_hide.png new file mode 100644 index 0000000..005f827 Binary files /dev/null and b/clients/2011M/content/textures/ui/playerlist_big_hide.png differ diff --git a/clients/2011M/content/textures/ui/playerlist_big_hide_dn.png b/clients/2011M/content/textures/ui/playerlist_big_hide_dn.png new file mode 100644 index 0000000..9b739eb Binary files /dev/null and b/clients/2011M/content/textures/ui/playerlist_big_hide_dn.png differ diff --git a/clients/2011M/content/textures/ui/playerlist_big_hide_ovr.png b/clients/2011M/content/textures/ui/playerlist_big_hide_ovr.png new file mode 100644 index 0000000..9b739eb Binary files /dev/null and b/clients/2011M/content/textures/ui/playerlist_big_hide_ovr.png differ diff --git a/clients/2011M/content/textures/ui/playerlist_hidden_maximize.png b/clients/2011M/content/textures/ui/playerlist_hidden_maximize.png new file mode 100644 index 0000000..b00c3bb Binary files /dev/null and b/clients/2011M/content/textures/ui/playerlist_hidden_maximize.png differ diff --git a/clients/2011M/content/textures/ui/playerlist_hidden_maximize_dn.png b/clients/2011M/content/textures/ui/playerlist_hidden_maximize_dn.png new file mode 100644 index 0000000..2a12d9e Binary files /dev/null and b/clients/2011M/content/textures/ui/playerlist_hidden_maximize_dn.png differ diff --git a/clients/2011M/content/textures/ui/playerlist_hidden_maximize_ovr.png b/clients/2011M/content/textures/ui/playerlist_hidden_maximize_ovr.png new file mode 100644 index 0000000..2a12d9e Binary files /dev/null and b/clients/2011M/content/textures/ui/playerlist_hidden_maximize_ovr.png differ diff --git a/clients/2011M/content/textures/ui/playerlist_hidden_small.png b/clients/2011M/content/textures/ui/playerlist_hidden_small.png new file mode 100644 index 0000000..a77dbca Binary files /dev/null and b/clients/2011M/content/textures/ui/playerlist_hidden_small.png differ diff --git a/clients/2011M/content/textures/ui/playerlist_hidden_small_dn.png b/clients/2011M/content/textures/ui/playerlist_hidden_small_dn.png new file mode 100644 index 0000000..ed2a5b3 Binary files /dev/null and b/clients/2011M/content/textures/ui/playerlist_hidden_small_dn.png differ diff --git a/clients/2011M/content/textures/ui/playerlist_hidden_small_ovr.png b/clients/2011M/content/textures/ui/playerlist_hidden_small_ovr.png new file mode 100644 index 0000000..ed2a5b3 Binary files /dev/null and b/clients/2011M/content/textures/ui/playerlist_hidden_small_ovr.png differ diff --git a/clients/2011M/content/textures/ui/playerlist_small_hide.png b/clients/2011M/content/textures/ui/playerlist_small_hide.png new file mode 100644 index 0000000..819925e Binary files /dev/null and b/clients/2011M/content/textures/ui/playerlist_small_hide.png differ diff --git a/clients/2011M/content/textures/ui/playerlist_small_hide_dn.png b/clients/2011M/content/textures/ui/playerlist_small_hide_dn.png new file mode 100644 index 0000000..2045284 Binary files /dev/null and b/clients/2011M/content/textures/ui/playerlist_small_hide_dn.png differ diff --git a/clients/2011M/content/textures/ui/playerlist_small_hide_ovr.png b/clients/2011M/content/textures/ui/playerlist_small_hide_ovr.png new file mode 100644 index 0000000..2045284 Binary files /dev/null and b/clients/2011M/content/textures/ui/playerlist_small_hide_ovr.png differ diff --git a/clients/2011M/content/textures/ui/playerlist_small_maximize.png b/clients/2011M/content/textures/ui/playerlist_small_maximize.png new file mode 100644 index 0000000..23bc9e4 Binary files /dev/null and b/clients/2011M/content/textures/ui/playerlist_small_maximize.png differ diff --git a/clients/2011M/content/textures/ui/playerlist_small_maximize_dn.png b/clients/2011M/content/textures/ui/playerlist_small_maximize_dn.png new file mode 100644 index 0000000..e141f79 Binary files /dev/null and b/clients/2011M/content/textures/ui/playerlist_small_maximize_dn.png differ diff --git a/clients/2011M/content/textures/ui/playerlist_small_maximize_ovr.png b/clients/2011M/content/textures/ui/playerlist_small_maximize_ovr.png new file mode 100644 index 0000000..e141f79 Binary files /dev/null and b/clients/2011M/content/textures/ui/playerlist_small_maximize_ovr.png differ diff --git a/clients/2011M/content/textures/ui/scrollbar.png b/clients/2011M/content/textures/ui/scrollbar.png new file mode 100644 index 0000000..9d7a4ff Binary files /dev/null and b/clients/2011M/content/textures/ui/scrollbar.png differ diff --git a/clients/2011M/content/textures/ui/scrollbuttonDown.png b/clients/2011M/content/textures/ui/scrollbuttonDown.png new file mode 100644 index 0000000..a3e6539 Binary files /dev/null and b/clients/2011M/content/textures/ui/scrollbuttonDown.png differ diff --git a/clients/2011M/content/textures/ui/scrollbuttonDown_dn.png b/clients/2011M/content/textures/ui/scrollbuttonDown_dn.png new file mode 100644 index 0000000..f7002ce Binary files /dev/null and b/clients/2011M/content/textures/ui/scrollbuttonDown_dn.png differ diff --git a/clients/2011M/content/textures/ui/scrollbuttonDown_ds.png b/clients/2011M/content/textures/ui/scrollbuttonDown_ds.png new file mode 100644 index 0000000..eac4eb9 Binary files /dev/null and b/clients/2011M/content/textures/ui/scrollbuttonDown_ds.png differ diff --git a/clients/2011M/content/textures/ui/scrollbuttonDown_ovr.png b/clients/2011M/content/textures/ui/scrollbuttonDown_ovr.png new file mode 100644 index 0000000..f7002ce Binary files /dev/null and b/clients/2011M/content/textures/ui/scrollbuttonDown_ovr.png differ diff --git a/clients/2011M/content/textures/ui/scrollbuttonUp.png b/clients/2011M/content/textures/ui/scrollbuttonUp.png new file mode 100644 index 0000000..5754f55 Binary files /dev/null and b/clients/2011M/content/textures/ui/scrollbuttonUp.png differ diff --git a/clients/2011M/content/textures/ui/scrollbuttonUp_dn.png b/clients/2011M/content/textures/ui/scrollbuttonUp_dn.png new file mode 100644 index 0000000..f12d690 Binary files /dev/null and b/clients/2011M/content/textures/ui/scrollbuttonUp_dn.png differ diff --git a/clients/2011M/content/textures/ui/scrollbuttonUp_ds.png b/clients/2011M/content/textures/ui/scrollbuttonUp_ds.png new file mode 100644 index 0000000..1e1b9db Binary files /dev/null and b/clients/2011M/content/textures/ui/scrollbuttonUp_ds.png differ diff --git a/clients/2011M/content/textures/ui/scrollbuttonUp_ovr.png b/clients/2011M/content/textures/ui/scrollbuttonUp_ovr.png new file mode 100644 index 0000000..f12d690 Binary files /dev/null and b/clients/2011M/content/textures/ui/scrollbuttonUp_ovr.png differ diff --git a/clients/2011M/content/textures/vol_ice_cracked2.dds b/clients/2011M/content/textures/vol_ice_cracked2.dds new file mode 100644 index 0000000..5b93a24 Binary files /dev/null and b/clients/2011M/content/textures/vol_ice_cracked2.dds differ diff --git a/clients/2011M/content/textures/wrench.png b/clients/2011M/content/textures/wrench.png new file mode 100644 index 0000000..5c8213f Binary files /dev/null and b/clients/2011M/content/textures/wrench.png differ