Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <External>null</External>
- <External>nil</External>
- <Item class="Script" referent="RBXC31DDC25848247ADBFDBECCDD7CCE851">
- <Properties>
- <bool name="Disabled">false</bool>
- <Content name="LinkedSource"><null></null></Content>
- <string name="kaioo12345k">Import from Building Tools by F3X</string>
- <string name="ScriptGuid">{CE3F9297-3A87-4589-BC1C-50DBC6CB8472}</string>
- <ProtectedString name="Source"><![CDATA[------------------------------------------
- -- Make references to important items
- ------------------------------------------
- Services = {
- HttpService = Game:GetService( 'HttpService' );
- Workspace = Game:GetService( 'Workspace' );
- ContentProvider = Game:GetService( 'ContentProvider' );
- CoreGui = Game:GetService( 'CoreGui' );
- Selection = Game:GetService( 'Selection' );
- Players = Game:GetService 'Players';
- };
- bt_logo = 'http://www.roblox.com/asset/?id=129747824';
- plugin_icon = 'http://www.roblox.com/asset/?id=144549739';
- export_base_url = 'http://www.f3xteam.com/bt/export/%s';
- -- Create the plugin
- Plugin = plugin;
- Toolbar = Plugin:CreateToolbar( 'Building Tools by F3X' );
- Launcher = Toolbar:CreateButton( '', 'Import from Building Tools by F3X', plugin_icon );
- local GUI;
- ------------------------------------------
- -- Load external dependencies
- ------------------------------------------
- RbxUtility = LoadLibrary( 'RbxUtility' );
- Services.ContentProvider:Preload( bt_logo );
- SerializationV2 = require(script.SerializationModule2);
- SerializationV3 = require(script.SerializationModule3);
- ------------------------------------------
- -- Define functions that are depended-upon
- ------------------------------------------
- function _findTableOccurrences( haystack, needle )
- -- Returns the positions of instances of `needle` in table `haystack`
- local positions = {};
- -- Add any indexes from `haystack` that have `needle`
- for index, value in pairs( haystack ) do
- if value == needle then
- table.insert( positions, index );
- end;
- end;
- return positions;
- end;
- ------------------------------------------
- -- Provide actual functionality
- ------------------------------------------
- function showGUI( message, ok_text )
- -- Make sure the UI isn't already open
- if GUI then
- hideGUI();
- end;
- local Create = RbxUtility.Create;
- GUI = Create 'ScreenGui' {
- Name = 'BTImportUI';
- Parent = Services.CoreGui;
- };
- local Container = Create 'Frame' {
- Name = 'Container';
- Parent = GUI;
- BackgroundTransparency = 1;
- Size = UDim2.new( 1, 0, 0, 0 );
- BorderSizePixel = 0;
- ClipsDescendants = true;
- };
- local Highlight = Create 'Frame' {
- Name = 'Highlight';
- Parent = Container;
- ZIndex = 2;
- BackgroundColor3 = Color3.new( 1, 1, 1 );
- BackgroundTransparency = 0.95;
- BorderSizePixel = 0;
- Position = UDim2.new( 0, 0, 0, 270 );
- Size = UDim2.new( 1, 0, 0, 180 );
- ZIndex = 2;
- };
- if message then
- local OkButton = Create 'TextButton' {
- Name = 'OkButton';
- Parent = Highlight;
- BackgroundColor3 = Color3.new( 1, 162 / 255, 47 / 255 );
- BorderSizePixel = 0;
- Position = UDim2.new( 0.3, 0, 1, -60 );
- Size = UDim2.new( 0.4, 0, 0, 40 );
- ZIndex = 2;
- Font = Enum.Font.SourceSansBold;
- FontSize = Enum.FontSize.Size24;
- Text = ok_text;
- TextColor3 = Color3.new( 1, 1, 1 );
- TextStrokeColor3 = Color3.new( 0, 0, 0 );
- TextStrokeTransparency = 0.85;
- TextWrapped = true;
- [Create.E 'MouseButton1Up'] = function ()
- hideGUI();
- end;
- };
- Create 'Frame' {
- Name = 'Bevel';
- Parent = OkButton;
- BorderSizePixel = 0;
- BackgroundColor3 = Color3.new( 184 / 255, 116 / 255, 33 / 255 );
- Position = UDim2.new( 0, 0, 1, -2 );
- Size = UDim2.new( 1, 0, 0, 2 );
- ZIndex = 2;
- };
- local Message = Create 'TextLabel' {
- Name = 'Message';
- Parent = Highlight;
- BackgroundTransparency = 1;
- BorderSizePixel = 0;
- Position = UDim2.new( 0.1, 0, 0, 0 );
- Size = UDim2.new( 0.8, 0, 1, -30 );
- Font = Enum.Font.Arial;
- FontSize = Enum.FontSize.Size24;
- Text = message;
- TextColor3 = Color3.new( 1, 1, 1 );
- TextWrapped = true;
- };
- end;
- local Interface = Create 'Frame' {
- Name = 'Interface';
- Parent = Container;
- ZIndex = 2;
- Size = UDim2.new( 0.6, 0, 0, 110 );
- Position = UDim2.new( 0.2, 0, 0, 300 );
- BorderSizePixel = 0;
- BackgroundTransparency = 1;
- Visible = not message;
- };
- local CreationID = Create 'Frame' {
- Name = 'CreationID';
- Parent = Interface;
- BackgroundTransparency = 1;
- BorderSizePixel = 0;
- Position = UDim2.new( 0, 0, 0, 10 );
- Size = UDim2.new( 1, 0, 0, 30 );
- ZIndex = 2;
- };
- Create 'Frame' {
- Name = 'BottomBorder';
- Parent = CreationID;
- BorderSizePixel = 0;
- BackgroundColor3 = Color3.new( 1, 162 / 255, 47 / 255 );
- Position = UDim2.new( 0, 0, 1, -1 );
- Size = UDim2.new( 1, 0, 0, 1 );
- ZIndex = 2;
- };
- Create 'Frame' {
- Name = 'LeftBorder';
- Parent = CreationID;
- BorderSizePixel = 0;
- BackgroundColor3 = Color3.new( 1, 162 / 255, 47 / 255 );
- Position = UDim2.new( 0, 0, 0.8, 0 );
- Size = UDim2.new( 0, 1, 0.2, 0 );
- ZIndex = 2;
- };
- Create 'Frame' {
- Name = 'RightBorder';
- Parent = CreationID;
- BorderSizePixel = 0;
- BackgroundColor3 = Color3.new( 1, 162 / 255, 47 / 255 );
- Position = UDim2.new( 1, -1, 0.8, 0 );
- Size = UDim2.new( 0, 1, 0.2, 0 );
- ZIndex = 2;
- };
- local TextBox;
- TextBox = Create 'TextBox' {
- Parent = CreationID;
- BackgroundTransparency = 1;
- BorderSizePixel = 0;
- ClearTextOnFocus = true;
- Position = UDim2.new( 0, 10, 0, -10 );
- Size = UDim2.new( 1, -10, 1, 10 );
- ZIndex = 2;
- Font = Enum.Font.SourceSans;
- FontSize = Enum.FontSize.Size24;
- Text = "What's your creation's ID?";
- TextColor3 = Color3.new( 1, 1, 1 );
- TextTransparency = 0.3;
- TextXAlignment = Enum.TextXAlignment.Left;
- [Create.E 'FocusLost'] = function ( enter_pressed )
- if not enter_pressed then
- return;
- end;
- import( TextBox.Text:lower() );
- end;
- };
- local CancelButton = Create 'TextButton' {
- Parent = Interface;
- BackgroundColor3 = Color3.new( 1, 162 / 255, 47 / 255 );
- BackgroundTransparency = 0.3;
- BorderSizePixel = 0;
- Name = 'CancelButton';
- Position = UDim2.new( 0.55, 0, 0, 65 );
- Size = UDim2.new( 0.45, 0, 0, 40 );
- ZIndex = 2;
- Font = Enum.Font.SourceSansBold;
- FontSize = Enum.FontSize.Size24;
- Text = 'Cancel';
- TextColor3 = Color3.new( 1, 1, 1 );
- TextStrokeColor3 = Color3.new( 0, 0, 0 );
- TextStrokeTransparency = 0.85;
- TextTransparency = 0.3;
- [Create.E 'MouseButton1Up'] = function ()
- hideGUI();
- end;
- };
- Create 'Frame' {
- Parent = CancelButton;
- BackgroundColor3 = Color3.new( 131 / 255, 83 / 255, 23 / 255 );
- BorderSizePixel = 0;
- Name = 'Bevel';
- Position = UDim2.new( 0, 0, 1, -2 );
- Size = UDim2.new( 1, 0, 0, 2 );
- ZIndex = 2;
- };
- local ImportButton = Create 'TextButton' {
- Parent = Interface;
- BackgroundColor3 = Color3.new( 1, 162 / 255, 47 / 255 );
- BorderSizePixel = 0;
- Name = 'ImportButton';
- Position = UDim2.new( 0, 0, 0, 65 );
- Size = UDim2.new( 0.45, 0, 0, 40 );
- ZIndex = 2;
- Font = Enum.Font.SourceSansBold;
- FontSize = Enum.FontSize.Size24;
- Text = 'Import';
- TextColor3 = Color3.new( 1, 1, 1 );
- TextStrokeColor3 = Color3.new( 0, 0, 0 );
- TextStrokeTransparency = 0.85;
- [Create.E 'MouseButton1Up'] = function ()
- import( TextBox.Text:lower() );
- end;
- };
- Create 'Frame' {
- Parent = ImportButton;
- BackgroundColor3 = Color3.new( 204 / 255, 129 / 255, 37 / 255 );
- BorderSizePixel = 0;
- Name = 'Bevel';
- Position = UDim2.new( 0, 0, 1, -2 );
- Size = UDim2.new( 1, 0, 0, 2 );
- ZIndex = 2;
- };
- Create 'Frame' {
- Name = 'Overlay';
- Parent = Container;
- BackgroundColor3 = Color3.new( 0, 0, 0 );
- BackgroundTransparency = 0.25;
- BorderSizePixel = 0;
- Size = UDim2.new( 1, 0, 1, 0 );
- };
- local Logo = Create 'ImageLabel' {
- Name = 'Logo';
- Parent = Container;
- BackgroundTransparency = 1;
- BorderSizePixel = 0;
- Image = bt_logo;
- Position = UDim2.new( 0, GUI.AbsoluteSize.x / 2 - 128, 0, 0 );
- Size = UDim2.new( 0, 256, 0, 256 );
- ZIndex = 2;
- };
- GUI.Changed:connect( function ( property )
- if property == 'AbsoluteSize' then
- Logo.Position = UDim2.new( 0, GUI.AbsoluteSize.x / 2 - 128, 0, 0 );
- end;
- end );
- Container:TweenSize( UDim2.new( 1, 0, 1, 0 ), Enum.EasingDirection.Out, Enum.EasingStyle.Bounce, 0.5, true );
- end;
- function hideGUI()
- -- Hide the current GUI
- if GUI then
- GUI:Destroy();
- end;
- end;
- Launcher.Click:connect( function ()
- if SoloMode then
- showGUI( 'Use regular Studio to import.', 'Sure' );
- else
- showGUI();
- end;
- end );
- function import( creation_id )
- hideGUI();
- -- Try to download the creation
- local creation_data;
- local download_attempt, download_error = ypcall( function ()
- creation_data = Services.HttpService:GetAsync( export_base_url:format( creation_id ) );
- end );
- -- Fail graciously
- if not download_attempt and download_error == 'Http requests are not enabled' then
- print 'Import from Building Tools by F3X: Please enable HTTP requests (see http://wiki.roblox.com/index.php?title=Sending_HTTP_requests#Http_requests_are_not_enabled)';
- showGUI( 'Please enable HTTP requests (see Output)', 'Got it' );
- return false;
- end;
- if not download_attempt then
- print( 'Import from Building Tools by F3X (download request error): ' .. tostring( download_error ) );
- showGUI( "We couldn't get your creation", 'Oh' );
- return false;
- end;
- if not ( creation_data and type( creation_data ) == 'string' and creation_data:len() > 0 ) then
- showGUI( "We couldn't get your creation", ':(' );
- return false;
- end;
- if not pcall( function () creation_data = Services.HttpService:JSONDecode( creation_data ); end ) then
- showGUI( "We couldn't get your creation", ":'(" );
- return false;
- end;
- -- Create a container to hold the creation
- local Container = Instance.new( 'Model', Services.Workspace );
- Container.Name = 'BTExport';
- if creation_data.version == 1 then
- local objects = {};
- for part_id, part_data in pairs( creation_data.parts ) do
- local Part;
- local part_type = part_data[1];
- if part_type == 1 then
- Part = Instance.new( "Part" );
- elseif part_type == 2 then
- Part = Instance.new( "TrussPart" );
- elseif part_type == 3 then
- Part = Instance.new( "WedgePart" );
- elseif part_type == 4 then
- Part = Instance.new( "CornerWedgePart" );
- elseif part_type == 5 then
- Part = Instance.new( "Part" );
- Part.Shape = "Cylinder";
- elseif part_type == 6 then
- Part = Instance.new( "Part" );
- Part.Shape = "Ball";
- elseif part_type == 7 then
- Part = Instance.new( "Seat" );
- elseif part_type == 8 then
- Part = Instance.new( "VehicleSeat" );
- elseif part_type == 9 then
- Part = Instance.new( "SpawnLocation" );
- end;
- objects[part_id] = Part;
- Part.Size = Vector3.new( unpack( part_data[2] ) );
- Part.CFrame = CFrame.new( unpack( part_data[3] ) );
- Part.BrickColor = BrickColor.new( part_data[4] );
- Part.Material = part_data[5];
- Part.Anchored = part_data[6];
- Part.CanCollide = part_data[7];
- Part.Reflectance = part_data[8];
- Part.Transparency = part_data[9];
- Part.TopSurface = part_data[10];
- Part.BottomSurface = part_data[11];
- Part.LeftSurface = part_data[12];
- Part.RightSurface = part_data[13];
- Part.FrontSurface = part_data[14];
- Part.BackSurface = part_data[15];
- Part.Parent = Container;
- -- Add the part ID if it's referenced somewhere else
- if creation_data.welds then
- for _, Weld in pairs( creation_data.welds ) do
- if Weld[1] == part_id or Weld[2] == part_id then
- RbxUtility.Create 'StringValue' {
- Name = 'BTID';
- Parent = Part;
- Value = part_id;
- };
- break;
- end;
- end;
- end;
- end;
- if creation_data.welds then
- local weld_count = 0;
- for _, __ in pairs( creation_data.welds ) do
- weld_count = weld_count + 1;
- end;
- if weld_count > 0 then
- local WeldScript = Instance.new( 'Script' );
- WeldScript.Name = 'BTWelder';
- WeldScript.Source = [[-- This script creates the welds between parts imported by the Building Tools by F3X plugin.
- local BeforeAnchored = {};
- for _, Part in pairs(script.Parent:GetChildren()) do
- if Part:IsA 'BasePart' then
- BeforeAnchored[Part] = Part.Anchored;
- Part.Anchored = true;
- end;
- end;
- local create = LoadLibrary( 'RbxUtility' ).Create;
- function _getAllDescendants( Parent )
- -- Recursively gets all the descendants of `Parent` and returns them
- local descendants = {};
- for _, Child in pairs( Parent:GetChildren() ) do
- -- Add the direct descendants of `Parent`
- table.insert( descendants, Child );
- -- Add the descendants of each child
- for _, Subchild in pairs( _getAllDescendants( Child ) ) do
- table.insert( descendants, Subchild );
- end;
- end;
- return descendants;
- end;
- function findExportedPart( part_id )
- for _, Object in pairs( _getAllDescendants( script.Parent ) ) do
- if Object:IsA( 'StringValue' ) then
- if Object.Name == 'BTID' and Object.Value == part_id then
- return Object.Parent;
- end;
- end;
- end;
- end;
- ]];
- for weld_id, weld_data in pairs( creation_data.welds ) do
- WeldScript.Source = WeldScript.Source .. [[
- ( function ()
- local Part0 = findExportedPart( ']] .. weld_data[1] .. [[' );
- local Part1 = findExportedPart( ']] .. weld_data[2] .. [[' );
- if not Part0 or not Part1 then
- return;
- end;
- create 'Weld' {
- Name = 'BTWeld';
- Parent = Game.JointsService;
- Archivable = false;
- Part0 = Part0;
- Part1 = Part1;
- C1 = CFrame.new( ]] .. table.concat( weld_data[3], ', ' ) .. [[ );
- };
- end )();
- ]];
- end;
- WeldScript.Source = WeldScript.Source .. [[
- for Part, Anchored in pairs(BeforeAnchored) do
- Part.Anchored = Anchored;
- end;]];
- WeldScript.Parent = Container;
- end;
- end;
- if creation_data.meshes then
- for mesh_id, mesh_data in pairs( creation_data.meshes ) do
- -- Create, place, and register the mesh
- local Mesh = Instance.new( "SpecialMesh", objects[mesh_data[1]] );
- objects[mesh_id] = Mesh;
- -- Set the mesh's properties
- Mesh.MeshType = mesh_data[2];
- Mesh.Scale = Vector3.new( unpack( mesh_data[3] ) );
- Mesh.MeshId = mesh_data[4];
- Mesh.TextureId = mesh_data[5];
- Mesh.VertexColor = Vector3.new( unpack( mesh_data[6] ) );
- end;
- end;
- if creation_data.textures then
- for texture_id, texture_data in pairs( creation_data.textures ) do
- -- Create, place, and register the texture
- local texture_class;
- if texture_data[2] == 1 then
- texture_class = 'Decal';
- elseif texture_data[2] == 2 then
- texture_class = 'Texture';
- end;
- local Texture = Instance.new( texture_class, objects[texture_data[1]] );
- objects[texture_id] = Texture;
- -- Set the texture's properties
- Texture.Face = texture_data[3];
- Texture.Texture = texture_data[4];
- Texture.Transparency = texture_data[5];
- if Texture:IsA( "Texture" ) then
- Texture.StudsPerTileU = texture_data[6];
- Texture.StudsPerTileV = texture_data[7];
- end;
- end;
- end;
- if creation_data.lights then
- for light_id, light_data in pairs( creation_data.lights ) do
- -- Create, place, and register the light
- local light_class;
- if light_data[2] == 1 then
- light_class = 'PointLight';
- elseif light_data[2] == 2 then
- light_class = 'SpotLight';
- end;
- local Light = Instance.new( light_class, objects[light_data[1]] )
- objects[light_id] = Light;
- -- Set the light's properties
- Light.Color = Color3.new( unpack( light_data[3] ) );
- Light.Brightness = light_data[4];
- Light.Range = light_data[5];
- Light.Shadows = light_data[6];
- if Light:IsA( 'SpotLight' ) then
- Light.Angle = light_data[7];
- Light.Face = light_data[8];
- end;
- end;
- end;
- if creation_data.decorations then
- for decoration_id, decoration_data in pairs( creation_data.decorations ) do
- -- Create and register the decoration
- if decoration_data[2] == 1 then
- local Smoke = RbxUtility.Create 'Smoke' {
- Parent = objects[decoration_data[1]];
- Color = Color3.new( unpack( decoration_data[3] ) );
- Opacity = decoration_data[4];
- RiseVelocity = decoration_data[5];
- Size = decoration_data[6];
- };
- objects[decoration_id] = Smoke;
- elseif decoration_data[2] == 2 then
- local Fire = RbxUtility.Create 'Fire' {
- Parent = objects[decoration_data[1]];
- Color = Color3.new( unpack( decoration_data[3] ) );
- SecondaryColor = Color3.new( unpack( decoration_data[4] ) );
- Heat = decoration_data[5];
- Size = decoration_data[6];
- };
- objects[decoration_id] = Fire;
- elseif decoration_data[2] == 3 then
- local Sparkles = RbxUtility.Create 'Sparkles' {
- Parent = objects[decoration_data[1]];
- SparkleColor = Color3.new( unpack( decoration_data[3] ) );
- };
- objects[decoration_id] = Sparkles;
- end;
- end;
- end;
- Container:MakeJoints();
- Services.Selection:Set( { Container } );
- -- Parse builds with serialization format version 2
- elseif creation_data.Version == 2 then
- -- Inflate the build data
- local Parts = SerializationV2.InflateBuildData(creation_data);
- -- Parent the build into the export container
- for _, Part in pairs(Parts) do
- Part.Parent = Container;
- end;
- -- Finalize the import
- Container:MakeJoints();
- Services.Selection:Set { Container };
- -- Parse builds with serialization format version 3
- elseif creation_data.Version == 3 then
- -- Inflate the build data
- local Parts = SerializationV3.InflateBuildData(creation_data);
- -- Parent the build into the export container
- for _, Part in pairs(Parts) do
- Part.Parent = Container;
- end;
- -- Finalize the import
- Container:MakeJoints();
- Services.Selection:Set { Container };
- end;
- end;]]></ProtectedString>
- </Properties>
- <Item class="ModuleScript" referent="RBX7DE39C6EBF52434597B33516946E415B">
- <Properties>
- <Content name="LinkedSource"><null></null></Content>
- <string name="Name">SerializationModule2</string>
- <string name="ScriptGuid">{175547C9-C6CE-443E-8ED2-EE4F26AB5DF8}</string>
- <ProtectedString name="Source"><![CDATA[Serialization = {};
- -- Import services
- Support = require(script.Parent.SupportLibrary);
- Support.ImportServices();
- local Types = {
- Part = 0,
- WedgePart = 1,
- CornerWedgePart = 2,
- VehicleSeat = 3,
- Seat = 4,
- TrussPart = 5,
- SpecialMesh = 6,
- Texture = 7,
- Decal = 8,
- PointLight = 9,
- SpotLight = 10,
- SurfaceLight = 11,
- Smoke = 12,
- Fire = 13,
- Sparkles = 14,
- Model = 15
- };
- local DefaultNames = {
- Part = 'Part',
- WedgePart = 'Wedge',
- CornerWedgePart = 'CornerWedge',
- VehicleSeat = 'VehicleSeat',
- Seat = 'Seat',
- TrussPart = 'Truss',
- SpecialMesh = 'Mesh',
- Texture = 'Texture',
- Decal = 'Decal',
- PointLight = 'PointLight',
- SpotLight = 'SpotLight',
- SurfaceLight = 'SurfaceLight',
- Smoke = 'Smoke',
- Fire = 'Fire',
- Sparkles = 'Sparkles',
- Model = 'Model'
- };
- function Serialization.SerializeModel(Items)
- -- Returns a serialized version of the given model
- -- Filter out non-serializable items in `Items`
- local SerializableItems = {};
- for Index, Item in ipairs(Items) do
- table.insert(SerializableItems, Types[Item.ClassName] and Item or nil);
- end;
- Items = SerializableItems;
- -- Get a snapshot of the content
- local Keys = Support.FlipTable(Items);
- local Data = {};
- Data.Version = 2;
- Data.Items = {};
- -- Serialize each item in the model
- for Index, Item in pairs(Items) do
- if Item:IsA 'BasePart' then
- local Datum = {};
- Datum[1] = Types[Item.ClassName];
- Datum[2] = Keys[Item.Parent] or 0;
- Datum[3] = Item.Name == DefaultNames[Item.ClassName] and '' or Item.Name;
- Datum[4] = Item.Size.X;
- Datum[5] = Item.Size.Y;
- Datum[6] = Item.Size.Z;
- Support.ConcatTable(Datum, { Item.CFrame:components() });
- Datum[19] = Item.BrickColor.Number;
- Datum[20] = Item.Material.Value;
- Datum[21] = Item.Anchored and 1 or 0;
- Datum[22] = Item.CanCollide and 1 or 0;
- Datum[23] = Item.Reflectance;
- Datum[24] = Item.Transparency;
- Datum[25] = Item.TopSurface.Value;
- Datum[26] = Item.BottomSurface.Value;
- Datum[27] = Item.FrontSurface.Value;
- Datum[28] = Item.BackSurface.Value;
- Datum[29] = Item.LeftSurface.Value;
- Datum[30] = Item.RightSurface.Value;
- Data.Items[Index] = Datum;
- end;
- if Item.ClassName == 'Part' then
- local Datum = Data.Items[Index];
- Datum[31] = Item.Shape.Value;
- end;
- if Item.ClassName == 'VehicleSeat' then
- local Datum = Data.Items[Index];
- Datum[31] = Item.MaxSpeed;
- Datum[32] = Item.Torque;
- Datum[33] = Item.TurnSpeed;
- end;
- if Item.ClassName == 'TrussPart' then
- local Datum = Data.Items[Index];
- Datum[31] = Item.Style.Value;
- end;
- if Item.ClassName == 'SpecialMesh' then
- local Datum = {};
- Datum[1] = Types[Item.ClassName];
- Datum[2] = Keys[Item.Parent] or 0;
- Datum[3] = Item.Name == DefaultNames[Item.ClassName] and '' or Item.Name;
- Datum[4] = Item.MeshType.Value;
- Datum[5] = Item.MeshId;
- Datum[6] = Item.TextureId;
- Datum[7] = Item.Offset.X;
- Datum[8] = Item.Offset.Y;
- Datum[9] = Item.Offset.Z;
- Datum[10] = Item.Scale.X;
- Datum[11] = Item.Scale.Y;
- Datum[12] = Item.Scale.Z;
- Datum[13] = Item.VertexColor.X;
- Datum[14] = Item.VertexColor.Y;
- Datum[15] = Item.VertexColor.Z;
- Data.Items[Index] = Datum;
- end;
- if Item:IsA 'Decal' then
- local Datum = {};
- Datum[1] = Types[Item.ClassName];
- Datum[2] = Keys[Item.Parent] or 0;
- Datum[3] = Item.Name == DefaultNames[Item.ClassName] and '' or Item.Name;
- Datum[4] = Item.Texture;
- Datum[5] = Item.Transparency;
- Datum[6] = Item.Face.Value;
- Data.Items[Index] = Datum;
- end;
- if Item.ClassName == 'Texture' then
- local Datum = Data.Items[Index];
- Datum[7] = Item.StudsPerTileU;
- Datum[8] = Item.StudsPerTileV;
- end;
- if Item:IsA 'Light' then
- local Datum = {};
- Datum[1] = Types[Item.ClassName];
- Datum[2] = Keys[Item.Parent] or 0;
- Datum[3] = Item.Name == DefaultNames[Item.ClassName] and '' or Item.Name;
- Datum[4] = Item.Brightness;
- Datum[5] = Item.Color.r;
- Datum[6] = Item.Color.g;
- Datum[7] = Item.Color.b;
- Datum[8] = Item.Enabled and 1 or 0;
- Datum[9] = Item.Shadows and 1 or 0;
- Data.Items[Index] = Datum;
- end;
- if Item.ClassName == 'PointLight' then
- local Datum = Data.Items[Index];
- Datum[10] = Item.Range;
- end;
- if Item.ClassName == 'SpotLight' then
- local Datum = Data.Items[Index];
- Datum[10] = Item.Range;
- Datum[11] = Item.Angle;
- Datum[12] = Item.Face.Value;
- end;
- if Item.ClassName == 'SurfaceLight' then
- local Datum = Data.Items[Index];
- Datum[10] = Item.Range;
- Datum[11] = Item.Angle;
- Datum[12] = Item.Face.Value;
- end;
- if Item.ClassName == 'Smoke' then
- local Datum = {};
- Datum[1] = Types[Item.ClassName];
- Datum[2] = Keys[Item.Parent] or 0;
- Datum[3] = Item.Name == DefaultNames[Item.ClassName] and '' or Item.Name;
- Datum[4] = Item.Enabled and 1 or 0;
- Datum[5] = Item.Color.r;
- Datum[6] = Item.Color.g;
- Datum[7] = Item.Color.b;
- Datum[8] = Item.Size;
- Datum[9] = Item.RiseVelocity;
- Datum[10] = Item.Opacity;
- Data.Items[Index] = Datum;
- end;
- if Item.ClassName == 'Fire' then
- local Datum = {};
- Datum[1] = Types[Item.ClassName];
- Datum[2] = Keys[Item.Parent] or 0;
- Datum[3] = Item.Name == DefaultNames[Item.ClassName] and '' or Item.Name;
- Datum[4] = Item.Enabled and 1 or 0;
- Datum[5] = Item.Color.r;
- Datum[6] = Item.Color.g;
- Datum[7] = Item.Color.b;
- Datum[8] = Item.SecondaryColor.r;
- Datum[9] = Item.SecondaryColor.g;
- Datum[10] = Item.SecondaryColor.b;
- Datum[11] = Item.Heat;
- Datum[12] = Item.Size;
- Data.Items[Index] = Datum;
- end;
- if Item.ClassName == 'Sparkles' then
- local Datum = {};
- Datum[1] = Types[Item.ClassName];
- Datum[2] = Keys[Item.Parent] or 0;
- Datum[3] = Item.Name == DefaultNames[Item.ClassName] and '' or Item.Name;
- Datum[4] = Item.Enabled and 1 or 0;
- Datum[5] = Item.SparkleColor.r;
- Datum[6] = Item.SparkleColor.g;
- Datum[7] = Item.SparkleColor.b;
- Data.Items[Index] = Datum;
- end;
- if Item.ClassName == 'Model' then
- local Datum = {};
- Datum[1] = Types[Item.ClassName];
- Datum[2] = Keys[Item.Parent] or 0;
- Datum[3] = Item.Name == DefaultNames[Item.ClassName] and '' or Item.Name;
- Datum[4] = Item.PrimaryPart and Keys[Item.PrimaryPart] or 0;
- Data.Items[Index] = Datum;
- end;
- -- Spread the workload over time to avoid locking up the CPU
- if Index % 100 == 0 then
- wait(0.01);
- end;
- end;
- -- Return the serialized data
- return HttpService:JSONEncode(Data);
- end;
- function Serialization.InflateBuildData(Data)
- -- Returns an inflated version of the given build data
- local Build = {};
- local Instances = {};
- -- Create each instance
- for Index, Datum in ipairs(Data.Items) do
- -- Inflate BaseParts
- if Datum[1] == Types.Part
- or Datum[1] == Types.WedgePart
- or Datum[1] == Types.CornerWedgePart
- or Datum[1] == Types.VehicleSeat
- or Datum[1] == Types.Seat
- or Datum[1] == Types.TrussPart
- then
- local Item = Instance.new(Support.FindTableOccurrence(Types, Datum[1]));
- Item.Size = Vector3.new(unpack(Support.Slice(Datum, 4, 6)));
- Item.CFrame = CFrame.new(unpack(Support.Slice(Datum, 7, 18)));
- Item.BrickColor = BrickColor.new(Datum[19]);
- Item.Material = Datum[20];
- Item.Anchored = Datum[21] == 1;
- Item.CanCollide = Datum[22] == 1;
- Item.Reflectance = Datum[23];
- Item.Transparency = Datum[24];
- Item.TopSurface = Datum[25];
- Item.BottomSurface = Datum[26];
- Item.FrontSurface = Datum[27];
- Item.BackSurface = Datum[28];
- Item.LeftSurface = Datum[29];
- Item.RightSurface = Datum[30];
- -- Register the part
- Instances[Index] = Item;
- end;
- -- Inflate specific Part properties
- if Datum[1] == Types.Part then
- local Item = Instances[Index];
- Item.Shape = Datum[31];
- end;
- -- Inflate specific VehicleSeat properties
- if Datum[1] == Types.VehicleSeat then
- local Item = Instances[Index];
- Item.MaxSpeed = Datum[31];
- Item.Torque = Datum[32];
- Item.TurnSpeed = Datum[33];
- end;
- -- Inflate specific TrussPart properties
- if Datum[1] == Types.TrussPart then
- local Item = Instances[Index];
- Item.Style = Datum[31];
- end;
- -- Inflate SpecialMesh instances
- if Datum[1] == Types.SpecialMesh then
- local Item = Instance.new('SpecialMesh');
- Item.MeshType = Datum[4];
- Item.MeshId = Datum[5];
- Item.TextureId = Datum[6];
- Item.Offset = Vector3.new(unpack(Support.Slice(Datum, 7, 9)));
- Item.Scale = Vector3.new(unpack(Support.Slice(Datum, 10, 12)));
- Item.VertexColor = Vector3.new(unpack(Support.Slice(Datum, 13, 15)));
- -- Register the mesh
- Instances[Index] = Item;
- end;
- -- Inflate Decal instances
- if Datum[1] == Types.Decal or Datum[1] == Types.Texture then
- local Item = Instance.new(Support.FindTableOccurrence(Types, Datum[1]));
- Item.Texture = Datum[4];
- Item.Transparency = Datum[5];
- Item.Face = Datum[6];
- -- Register the Decal
- Instances[Index] = Item;
- end;
- -- Inflate specific Texture properties
- if Datum[1] == Types.Texture then
- local Item = Instances[Index];
- Item.StudsPerTileU = Datum[7];
- Item.StudsPerTileV = Datum[8];
- end;
- -- Inflate Light instances
- if Datum[1] == Types.PointLight
- or Datum[1] == Types.SpotLight
- or Datum[1] == Types.SurfaceLight
- then
- local Item = Instance.new(Support.FindTableOccurrence(Types, Datum[1]));
- Item.Brightness = Datum[4];
- Item.Color = Color3.new(unpack(Support.Slice(Datum, 5, 7)));
- Item.Enabled = Datum[8] == 1;
- Item.Shadows = Datum[9] == 1;
- -- Register the light
- Instances[Index] = Item;
- end;
- -- Inflate specific PointLight properties
- if Datum[1] == Types.PointLight then
- local Item = Instances[Index];
- Item.Range = Datum[10];
- end;
- -- Inflate specific SpotLight properties
- if Datum[1] == Types.SpotLight then
- local Item = Instances[Index];
- Item.Range = Datum[10];
- Item.Angle = Datum[11];
- Item.Face = Datum[12];
- end;
- -- Inflate specific SurfaceLight properties
- if Datum[1] == Types.SurfaceLight then
- local Item = Instances[Index];
- Item.Range = Datum[10];
- Item.Angle = Datum[11];
- Item.Face = Datum[12];
- end;
- -- Inflate Smoke instances
- if Datum[1] == Types.Smoke then
- local Item = Instance.new('Smoke');
- Item.Enabled = Datum[4] == 1;
- Item.Color = Color3.new(unpack(Support.Slice(Datum, 5, 7)));
- Item.Size = Datum[8];
- Item.RiseVelocity = Datum[9];
- Item.Opacity = Datum[10];
- -- Register the smoke
- Instances[Index] = Item;
- end;
- -- Inflate Fire instances
- if Datum[1] == Types.Fire then
- local Item = Instance.new('Fire');
- Item.Enabled = Datum[4] == 1;
- Item.Color = Color3.new(unpack(Support.Slice(Datum, 5, 7)));
- Item.SecondaryColor = Color3.new(unpack(Support.Slice(Datum, 8, 10)));
- Item.Heat = Datum[11];
- Item.Size = Datum[12];
- -- Register the fire
- Instances[Index] = Item;
- end;
- -- Inflate Sparkles instances
- if Datum[1] == Types.Sparkles then
- local Item = Instance.new('Sparkles');
- Item.Enabled = Datum[4] == 1;
- Item.SparkleColor = Color3.new(unpack(Support.Slice(Datum, 5, 7)));
- -- Register the instance
- Instances[Index] = Item;
- end;
- -- Inflate Model instances
- if Datum[1] == Types.Model then
- local Item = Instance.new('Model');
- -- Register the model
- Instances[Index] = Item;
- end;
- end;
- -- Set object values on each instance
- for Index, Datum in pairs(Data.Items) do
- -- Get the item's instance
- local Item = Instances[Index];
- -- Set each item's parent and name
- if Item and Datum[1] <= 15 then
- Item.Name = (Datum[3] == '') and DefaultNames[Item.ClassName] or Datum[3];
- if Datum[2] == 0 then
- table.insert(Build, Item);
- else
- Item.Parent = Instances[Datum[2]];
- end;
- end;
- -- Set model primary parts
- if Item and Datum[1] == 15 then
- Item.PrimaryPart = (Datum[4] ~= 0) and Instances[Datum[4]] or nil;
- end;
- end;
- -- Return the model
- return Build;
- end;
- -- Return the API
- return Serialization;]]></ProtectedString>
- </Properties>
- </Item>
- <Item class="ModuleScript" referent="RBXAAAC7DD1E3E04685B790375DBC0CAFA3">
- <Properties>
- <Content name="LinkedSource"><null></null></Content>
- <string name="Name">SupportLibrary</string>
- <string name="ScriptGuid">{B34CAB38-2088-42A7-9DD7-D0A6D6989372}</string>
- <ProtectedString name="Source"><![CDATA[SupportLibrary = {};
- function SupportLibrary.FindTableOccurrences(Haystack, Needle)
- -- Returns the positions of instances of `needle` in table `haystack`
- local Positions = {};
- -- Add any indexes from `Haystack` that are `Needle`
- for Index, Value in pairs(Haystack) do
- if Value == Needle then
- table.insert(Positions, Index);
- end;
- end;
- return Positions;
- end;
- function SupportLibrary.FindTableOccurrence(Haystack, Needle)
- -- Returns one occurrence of `Needle` in `Haystack`
- -- Search for the first instance of `Needle` found and return it
- for Index, Value in pairs(Haystack) do
- if Value == Needle then
- return Index;
- end;
- end;
- -- If no occurrences exist, return `nil`
- return nil;
- end;
- function SupportLibrary.IsInTable(Haystack, Needle)
- -- Returns whether the given `Needle` can be found within table `Haystack`
- -- Go through every value in `Haystack` and return whether `Needle` is found
- for _, Value in pairs(Haystack) do
- if Value == Needle then
- return true;
- end;
- end;
- -- If no instances were found, return false
- return false;
- end;
- function SupportLibrary.DoTablesMatch(A, B)
- -- Returns whether the values of tables A and B are the same
- -- Check B table differences
- for Index in pairs(A) do
- if A[Index] ~= B[Index] then
- return false;
- end;
- end;
- -- Check A table differences
- for Index in pairs(B) do
- if B[Index] ~= A[Index] then
- return false;
- end;
- end;
- -- Return true if no differences
- return true;
- end;
- function SupportLibrary.Round(Number, Places)
- -- Returns `Number` rounded to the given number of decimal places (from lua-users)
- -- Ensure that `Number` is a number
- if type(Number) ~= 'number' then
- return;
- end;
- -- Round the number
- local Multiplier = 10 ^ (Places or 0);
- local RoundedNumber = math.floor(Number * Multiplier + 0.5) / Multiplier;
- -- Return the rounded number
- return RoundedNumber;
- end;
- function SupportLibrary.CloneTable(Table)
- -- Returns a copy of `Table`
- local ClonedTable = {};
- -- Copy all values into `ClonedTable`
- for Key, Value in pairs(Table) do
- ClonedTable[Key] = Value;
- end;
- -- Return the clone
- return ClonedTable;
- end;
- function SupportLibrary.GetAllDescendants(Parent)
- -- Recursively gets all the descendants of `Parent` and returns them
- local Descendants = {};
- for _, Child in pairs(Parent:GetChildren()) do
- -- Add the direct descendants of `Parent`
- table.insert(Descendants, Child);
- -- Add the descendants of each child
- for _, Subchild in pairs(SupportLibrary.GetAllDescendants(Child)) do
- table.insert(Descendants, Subchild);
- end;
- end;
- return Descendants;
- end;
- function SupportLibrary.GetDescendantCount(Parent)
- -- Recursively gets a count of all the descendants of `Parent` and returns them
- local Count = 0;
- for _, Child in pairs(Parent:GetChildren()) do
- -- Count the direct descendants of `Parent`
- Count = Count + 1;
- -- Count and add the descendants of each child
- Count = Count + SupportLibrary.GetDescendantCount(Child);
- end;
- return Count;
- end;
- function SupportLibrary.CloneParts(Parts)
- -- Returns a table of cloned `Parts`
- local Clones = {};
- -- Copy the parts into `Clones`
- for Index, Part in pairs(Parts) do
- Clones[Index] = Part:Clone();
- end;
- return Clones;
- end;
- function SupportLibrary.SplitString(String, Delimiter)
- -- Returns a table of string `String` split by pattern `Delimiter`
- local StringParts = {};
- local Pattern = ('([^%s]+)'):format(Delimiter);
- -- Capture each separated part
- String:gsub(Pattern, function (Part)
- table.insert(StringParts, Part);
- end);
- return StringParts;
- end;
- function SupportLibrary.GetChildOfClass(Parent, ClassName, Inherit)
- -- Returns the first child of `Parent` that is of class `ClassName`
- -- or nil if it couldn't find any
- -- Look for a child of `Parent` of class `ClassName` and return it
- if not Inherit then
- for _, Child in pairs(Parent:GetChildren()) do
- if Child.ClassName == ClassName then
- return Child;
- end;
- end;
- else
- for _, Child in pairs(Parent:GetChildren()) do
- if Child:IsA(ClassName) then
- return Child;
- end;
- end;
- end;
- return nil;
- end;
- function SupportLibrary.GetChildrenOfClass(Parent, ClassName, Inherit)
- -- Returns a table containing the children of `Parent` that are
- -- of class `ClassName`
- local Matches = {};
- if not Inherit then
- for _, Child in pairs(Parent:GetChildren()) do
- if Child.ClassName == ClassName then
- table.insert(Matches, Child);
- end;
- end;
- else
- for _, Child in pairs(Parent:GetChildren()) do
- if Child:IsA(ClassName) then
- table.insert(Matches, Child);
- end;
- end;
- end;
- return Matches;
- end;
- function SupportLibrary.HSVToRGB(Hue, Saturation, Value)
- -- Returns the RGB equivalent of the given HSV-defined color
- -- (adapted from some code found around the web)
- -- If it's achromatic, just return the value
- if Saturation == 0 then
- return Value;
- end;
- -- Get the hue sector
- local HueSector = math.floor(Hue / 60);
- local HueSectorOffset = (Hue / 60) - HueSector;
- local P = Value * (1 - Saturation);
- local Q = Value * (1 - Saturation * HueSectorOffset);
- local T = Value * (1 - Saturation * (1 - HueSectorOffset));
- if HueSector == 0 then
- return Value, T, P;
- elseif HueSector == 1 then
- return Q, Value, P;
- elseif HueSector == 2 then
- return P, Value, T;
- elseif HueSector == 3 then
- return P, Q, Value;
- elseif HueSector == 4 then
- return T, P, Value;
- elseif HueSector == 5 then
- return Value, P, Q;
- end;
- end;
- function SupportLibrary.RGBToHSV(Red, Green, Blue)
- -- Returns the HSV equivalent of the given RGB-defined color
- -- (adapted from some code found around the web)
- local Hue, Saturation, Value;
- local MinValue = math.min(Red, Green, Blue);
- local MaxValue = math.max(Red, Green, Blue);
- Value = MaxValue;
- local ValueDelta = MaxValue - MinValue;
- -- If the color is not black
- if MaxValue ~= 0 then
- Saturation = ValueDelta / MaxValue;
- -- If the color is purely black
- else
- Saturation = 0;
- Hue = -1;
- return Hue, Saturation, Value;
- end;
- if Red == MaxValue then
- Hue = (Green - Blue) / ValueDelta;
- elseif Green == MaxValue then
- Hue = 2 + (Blue - Red) / ValueDelta;
- else
- Hue = 4 + (Red - Green) / ValueDelta;
- end;
- Hue = Hue * 60;
- if Hue < 0 then
- Hue = Hue + 360;
- end;
- return Hue, Saturation, Value;
- end;
- function SupportLibrary.IdentifyCommonItem(Items)
- -- Returns the common item in table `Items`, or `nil` if
- -- they vary
- local CommonItem = nil;
- for ItemIndex, Item in pairs(Items) do
- -- Set the initial item to compare against
- if ItemIndex == 1 then
- CommonItem = Item;
- -- Check if this item is the same as the rest
- else
- -- If it isn't the same, there is no common item, so just stop right here
- if Item ~= CommonItem then
- return nil;
- end;
- end;
- end;
- -- Return the common item
- return CommonItem;
- end;
- function SupportLibrary.IdentifyCommonProperty(Items, Property)
- -- Returns the common `Property` value in the instances given in `Items`
- local PropertyVariations = {};
- -- Capture all the variations of the property value
- for _, Item in pairs(Items) do
- table.insert(PropertyVariations, Item[Property]);
- end;
- -- Return the common property value
- return SupportLibrary.IdentifyCommonItem(PropertyVariations);
- end;
- function SupportLibrary.CreateSignal()
- -- Returns a ROBLOX-like signal for connections (RbxUtility's is buggy)
- local Signal = {
- Connections = {};
- -- Provide a function to connect an event handler
- Connect = function (Signal, Handler)
- -- Register the handler
- table.insert(Signal.Connections, Handler);
- -- Return a controller for this connection
- local ConnectionController = {
- -- Include a reference to the connection's handler
- Handler = Handler;
- -- Provide a way to disconnect this connection
- Disconnect = function (Connection)
- local ConnectionSearch = SupportLibrary.FindTableOccurrences(Signal.Connections, Connection.Handler);
- if #ConnectionSearch > 0 then
- local ConnectionIndex = ConnectionSearch[1];
- table.remove(Signal.Connections, ConnectionIndex);
- end;
- end;
- };
- -- Add compatibility aliases
- ConnectionController.disconnect = ConnectionController.Disconnect;
- -- Return the connection's controller
- return ConnectionController;
- end;
- -- Provide a function to trigger any connections' handlers
- Fire = function (Signal, ...)
- for _, Connection in pairs(Signal.Connections) do
- Connection(...);
- end;
- end;
- };
- -- Add compatibility aliases
- Signal.connect = Signal.Connect;
- Signal.fire = Signal.Fire;
- return Signal;
- end;
- function SupportLibrary.GetPartCorners(Part)
- -- Returns a table of the given part's corners' CFrames
- -- Make references to functions called a lot for efficiency
- local Insert = table.insert;
- local ToWorldSpace = CFrame.new().toWorldSpace;
- local NewCFrame = CFrame.new;
- -- Get info about the part
- local PartCFrame = Part.CFrame;
- local SizeX, SizeY, SizeZ = Part.Size.x / 2, Part.Size.y / 2, Part.Size.z / 2;
- -- Get each corner
- local Corners = {};
- Insert(Corners, ToWorldSpace(PartCFrame, NewCFrame(SizeX, SizeY, SizeZ)));
- Insert(Corners, ToWorldSpace(PartCFrame, NewCFrame(-SizeX, SizeY, SizeZ)));
- Insert(Corners, ToWorldSpace(PartCFrame, NewCFrame(SizeX, -SizeY, SizeZ)));
- Insert(Corners, ToWorldSpace(PartCFrame, NewCFrame(SizeX, SizeY, -SizeZ)));
- Insert(Corners, ToWorldSpace(PartCFrame, NewCFrame(-SizeX, SizeY, -SizeZ)));
- Insert(Corners, ToWorldSpace(PartCFrame, NewCFrame(-SizeX, -SizeY, SizeZ)));
- Insert(Corners, ToWorldSpace(PartCFrame, NewCFrame(SizeX, -SizeY, -SizeZ)));
- Insert(Corners, ToWorldSpace(PartCFrame, NewCFrame(-SizeX, -SizeY, -SizeZ)));
- return Corners;
- end;
- function SupportLibrary.CreatePart(PartType)
- -- Creates and returns new part based on `PartType` with sensible defaults
- local NewPart;
- if PartType == 'Normal' then
- NewPart = Instance.new('Part');
- NewPart.Size = Vector3.new(4, 1, 2);
- elseif PartType == 'Truss' then
- NewPart = Instance.new('TrussPart');
- elseif PartType == 'Wedge' then
- NewPart = Instance.new('WedgePart');
- NewPart.Size = Vector3.new(4, 1, 2);
- elseif PartType == 'Corner' then
- NewPart = Instance.new('CornerWedgePart');
- elseif PartType == 'Cylinder' then
- NewPart = Instance.new('Part');
- NewPart.Shape = 'Cylinder';
- NewPart.TopSurface = Enum.SurfaceType.Smooth;
- NewPart.BottomSurface = Enum.SurfaceType.Smooth;
- NewPart.Size = Vector3.new(2, 2, 2);
- elseif PartType == 'Ball' then
- NewPart = Instance.new('Part');
- NewPart.Shape = 'Ball';
- NewPart.TopSurface = Enum.SurfaceType.Smooth;
- NewPart.BottomSurface = Enum.SurfaceType.Smooth;
- elseif PartType == 'Seat' then
- NewPart = Instance.new('Seat');
- NewPart.Size = Vector3.new(4, 1, 2);
- elseif PartType == 'Vehicle Seat' then
- NewPart = Instance.new('VehicleSeat');
- NewPart.Size = Vector3.new(4, 1, 2);
- elseif PartType == 'Spawn' then
- NewPart = Instance.new('SpawnLocation');
- NewPart.Size = Vector3.new(4, 1, 2);
- end;
- -- Make sure the part is anchored
- NewPart.Anchored = true;
- return NewPart;
- end;
- function SupportLibrary.ImportServices()
- -- Adds references to common services into the calling environment
- -- Get the calling environment
- local CallingEnvironment = getfenv(2);
- -- Add the services
- CallingEnvironment.Workspace = Game:GetService 'Workspace';
- CallingEnvironment.Players = Game:GetService 'Players';
- CallingEnvironment.MarketplaceService = Game:GetService 'MarketplaceService';
- CallingEnvironment.ContentProvider = Game:GetService 'ContentProvider';
- CallingEnvironment.SoundService = Game:GetService 'SoundService';
- CallingEnvironment.UserInputService = Game:GetService 'UserInputService';
- CallingEnvironment.SelectionService = Game:GetService 'Selection';
- CallingEnvironment.CoreGui = Game:GetService 'CoreGui';
- CallingEnvironment.HttpService = Game:GetService 'HttpService';
- CallingEnvironment.ChangeHistoryService = Game:GetService 'ChangeHistoryService';
- CallingEnvironment.ReplicatedStorage = Game:GetService 'ReplicatedStorage';
- CallingEnvironment.GroupService = Game:GetService 'GroupService';
- CallingEnvironment.ServerScriptService = Game:GetService 'ServerScriptService';
- CallingEnvironment.ServerStorage = Game:GetService 'ServerStorage';
- CallingEnvironment.StarterGui = Game:GetService 'StarterGui';
- CallingEnvironment.RunService = Game:GetService 'RunService';
- end;
- function SupportLibrary.GetListMembers(List, MemberName)
- -- Gets the given member for each object in the given list table
- local Members = {};
- -- Collect the member values for each item in the list
- for _, Item in pairs(List) do
- table.insert(Members, Item[MemberName]);
- end;
- -- Return the members
- return Members;
- end;
- function SupportLibrary.AddUserInputListener(InputState, InputType, CatchAll, Callback)
- -- Connects to the given user input event and takes care of standard boilerplate code
- -- Turn the given `InputType` string into a proper enum
- local InputType = Enum.UserInputType[InputType];
- -- Create a UserInputService listener based on the given `InputState`
- return Game:GetService('UserInputService')['Input' .. InputState]:connect(function (Input, GameProcessedEvent)
- -- Make sure this input was not captured by the client (unless `CatchAll` is enabled)
- if GameProcessedEvent and not CatchAll then
- return;
- end;
- -- Make sure this is the right input type
- if Input.UserInputType ~= InputType then
- return;
- end;
- -- Make sure any key input did not occur while typing into a UI
- if InputType == Enum.UserInputType.Keyboard and Game:GetService('UserInputService'):GetFocusedTextBox() then
- return;
- end;
- -- Call back upon passing all conditions
- Callback(Input);
- end);
- end;
- function SupportLibrary.AddGuiInputListener(Gui, InputState, InputType, CatchAll, Callback)
- -- Connects to the given GUI user input event and takes care of standard boilerplate code
- -- Turn the given `InputType` string into a proper enum
- local InputType = Enum.UserInputType[InputType];
- -- Create a UserInputService listener based on the given `InputState`
- return Gui['Input' .. InputState]:connect(function (Input, GameProcessedEvent)
- -- Make sure this input was not captured by the client (unless `CatchAll` is enabled)
- if GameProcessedEvent and not CatchAll then
- return;
- end;
- -- Make sure this is the right input type
- if Input.UserInputType ~= InputType then
- return;
- end;
- -- Call back upon passing all conditions
- Callback(Input);
- end);
- end;
- function SupportLibrary.AreKeysPressed(...)
- -- Returns whether the given keys are pressed
- local RequestedKeysPressed = 0;
- -- Get currently pressed keys
- local PressedKeys = SupportLibrary.GetListMembers(Game:GetService('UserInputService'):GetKeysPressed(), 'KeyCode');
- -- Go through each requested key
- for _, Key in pairs({ ... }) do
- -- Count requested keys that are pressed
- if SupportLibrary.IsInTable(PressedKeys, Key) then
- RequestedKeysPressed = RequestedKeysPressed + 1;
- end;
- end;
- -- Return whether all the requested keys are pressed or not
- return RequestedKeysPressed == #{...};
- end;
- function SupportLibrary.ConcatTable(DestinationTable, SourceTable)
- -- Inserts all values of SourceTable into DestinationTable
- -- Add each value from `SourceTable` into `DestinationTable`
- for _, Value in ipairs(SourceTable) do
- table.insert(DestinationTable, Value);
- end;
- -- Return the destination table
- return DestinationTable;
- end;
- function SupportLibrary.ClearTable(Table)
- -- Clears out every value in `Table`
- -- Clear each index
- for Index in pairs(Table) do
- Table[Index] = nil;
- end;
- -- Return the given table
- return Table;
- end;
- function SupportLibrary.Values(Table)
- -- Returns all the values in the given table
- local Values = {};
- -- Go through each key and get each value
- for _, Value in pairs(Table) do
- table.insert(Values, Value);
- end;
- -- Return the values
- return Values;
- end;
- function SupportLibrary.Keys(Table)
- -- Returns all the keys in the given table
- local Keys = {};
- -- Go through each key and get each value
- for Key in pairs(Table) do
- table.insert(Keys, Key);
- end;
- -- Return the values
- return Keys;
- end;
- function SupportLibrary.Call(Function, ...)
- -- Returns a callback to `Function` with the given arguments
- local Args = { ... };
- return function (...)
- return Function(unpack(
- SupportLibrary.ConcatTable(SupportLibrary.CloneTable(Args), { ... })
- ));
- end;
- end;
- function SupportLibrary.Trim(String)
- -- Returns a trimmed version of `String` (adapted from code from lua-users)
- return (String:gsub("^%s*(.-)%s*$", "%1"));
- end
- function SupportLibrary.ChainCall(...)
- -- Returns function that passes arguments through given functions and returns the final result
- -- Get the given chain of functions
- local Chain = { ... };
- -- Return the chaining function
- return function (...)
- -- Get arguments
- local Arguments = { ... };
- -- Go through each function and store the returned data to reuse in the next function's arguments
- for _, Function in ipairs(Chain) do
- Arguments = { Function(unpack(Arguments)) };
- end;
- -- Return the final returned data
- return unpack(Arguments);
- end;
- end;
- function SupportLibrary.CountKeys(Table)
- -- Returns the number of keys in `Table`
- local Count = 0;
- -- Count each key
- for _ in pairs(Table) do
- Count = Count + 1;
- end;
- -- Return the count
- return Count;
- end;
- function SupportLibrary.Slice(Table, Start, End)
- -- Returns values from `Start` to `End` in `Table`
- local Slice = {};
- -- Go through the given indices
- for Index = Start, End do
- table.insert(Slice, Table[Index]);
- end;
- -- Return the slice
- return Slice;
- end;
- function SupportLibrary.FlipTable(Table)
- -- Returns a table with keys and values in `Table` swapped
- local FlippedTable = {};
- -- Flip each key and value
- for Key, Value in pairs(Table) do
- FlippedTable[Value] = Key;
- end;
- -- Return the flipped table
- return FlippedTable;
- end;
- function SupportLibrary.ScheduleRecurringTask(TaskFunction, Interval)
- -- Repeats `Task` every `Interval` seconds until stopped
- -- Create a task object
- local Task = {
- -- A switch determining if it's running or not
- Running = true;
- -- A function to stop this task
- Stop = function (Task)
- Task.Running = false;
- end;
- -- References to the task function and set interval
- TaskFunction = TaskFunction;
- Interval = Interval;
- };
- coroutine.wrap(function (Task)
- -- Repeat the task
- while wait(Task.Interval) and Task.Running do
- Task.TaskFunction();
- end;
- end)(Task);
- -- Return the task object
- return Task;
- end;
- function SupportLibrary.Clamp(Number, Minimum, Maximum)
- -- Returns the given number, clamped according to the provided min/max
- -- Clamp the number
- if Minimum and Number < Minimum then
- Number = Minimum;
- elseif Maximum and Number > Maximum then
- Number = Maximum;
- end;
- -- Return the clamped number
- return Number;
- end;
- function SupportLibrary.ReverseTable(Table)
- -- Returns a new table with values in the opposite order
- local ReversedTable = {};
- -- Copy each value at the opposite key
- for Index, Value in ipairs(Table) do
- ReversedTable[#Table - Index + 1] = Value;
- end;
- -- Return the reversed table
- return ReversedTable;
- end;
- return SupportLibrary;]]></ProtectedString>
- </Properties>
- </Item>
- <Item class="ModuleScript" referent="RBXF8091488FF32432C99021E3C16DA36CB">
- <Properties>
- <Content name="LinkedSource"><null></null></Content>
- <string name="Name">SerializationModule3</string>
- <string name="ScriptGuid">{4BA70DF3-3280-41FA-A236-E3606FBDDA4B}</string>
- <ProtectedString name="Source"><![CDATA[Serialization = {};
- -- Import services
- Support = require(script.Parent.SupportLibrary);
- Support.ImportServices();
- local Types = {
- Part = 0,
- WedgePart = 1,
- CornerWedgePart = 2,
- VehicleSeat = 3,
- Seat = 4,
- TrussPart = 5,
- SpecialMesh = 6,
- Texture = 7,
- Decal = 8,
- PointLight = 9,
- SpotLight = 10,
- SurfaceLight = 11,
- Smoke = 12,
- Fire = 13,
- Sparkles = 14,
- Model = 15
- };
- local DefaultNames = {
- Part = 'Part',
- WedgePart = 'Wedge',
- CornerWedgePart = 'CornerWedge',
- VehicleSeat = 'VehicleSeat',
- Seat = 'Seat',
- TrussPart = 'Truss',
- SpecialMesh = 'Mesh',
- Texture = 'Texture',
- Decal = 'Decal',
- PointLight = 'PointLight',
- SpotLight = 'SpotLight',
- SurfaceLight = 'SurfaceLight',
- Smoke = 'Smoke',
- Fire = 'Fire',
- Sparkles = 'Sparkles',
- Model = 'Model'
- };
- function Serialization.SerializeModel(Items)
- -- Returns a serialized version of the given model
- -- Filter out non-serializable items in `Items`
- local SerializableItems = {};
- for Index, Item in ipairs(Items) do
- table.insert(SerializableItems, Types[Item.ClassName] and Item or nil);
- end;
- Items = SerializableItems;
- -- Get a snapshot of the content
- local Keys = Support.FlipTable(Items);
- local Data = {};
- Data.Version = 3;
- Data.Items = {};
- -- Serialize each item in the model
- for Index, Item in pairs(Items) do
- if Item:IsA 'BasePart' then
- local Datum = {};
- Datum[1] = Types[Item.ClassName];
- Datum[2] = Keys[Item.Parent] or 0;
- Datum[3] = Item.Name == DefaultNames[Item.ClassName] and '' or Item.Name;
- Datum[4] = Item.Size.X;
- Datum[5] = Item.Size.Y;
- Datum[6] = Item.Size.Z;
- Support.ConcatTable(Datum, { Item.CFrame:components() });
- Datum[19] = Item.Color.r;
- Datum[20] = Item.Color.g;
- Datum[21] = Item.Color.b;
- Datum[22] = Item.Material.Value;
- Datum[23] = Item.Anchored and 1 or 0;
- Datum[24] = Item.CanCollide and 1 or 0;
- Datum[25] = Item.Reflectance;
- Datum[26] = Item.Transparency;
- Datum[27] = Item.TopSurface.Value;
- Datum[28] = Item.BottomSurface.Value;
- Datum[29] = Item.FrontSurface.Value;
- Datum[30] = Item.BackSurface.Value;
- Datum[31] = Item.LeftSurface.Value;
- Datum[32] = Item.RightSurface.Value;
- Data.Items[Index] = Datum;
- end;
- if Item.ClassName == 'Part' then
- local Datum = Data.Items[Index];
- Datum[33] = Item.Shape.Value;
- end;
- if Item.ClassName == 'VehicleSeat' then
- local Datum = Data.Items[Index];
- Datum[33] = Item.MaxSpeed;
- Datum[34] = Item.Torque;
- Datum[35] = Item.TurnSpeed;
- end;
- if Item.ClassName == 'TrussPart' then
- local Datum = Data.Items[Index];
- Datum[33] = Item.Style.Value;
- end;
- if Item.ClassName == 'SpecialMesh' then
- local Datum = {};
- Datum[1] = Types[Item.ClassName];
- Datum[2] = Keys[Item.Parent] or 0;
- Datum[3] = Item.Name == DefaultNames[Item.ClassName] and '' or Item.Name;
- Datum[4] = Item.MeshType.Value;
- Datum[5] = Item.MeshId;
- Datum[6] = Item.TextureId;
- Datum[7] = Item.Offset.X;
- Datum[8] = Item.Offset.Y;
- Datum[9] = Item.Offset.Z;
- Datum[10] = Item.Scale.X;
- Datum[11] = Item.Scale.Y;
- Datum[12] = Item.Scale.Z;
- Datum[13] = Item.VertexColor.X;
- Datum[14] = Item.VertexColor.Y;
- Datum[15] = Item.VertexColor.Z;
- Data.Items[Index] = Datum;
- end;
- if Item:IsA 'Decal' then
- local Datum = {};
- Datum[1] = Types[Item.ClassName];
- Datum[2] = Keys[Item.Parent] or 0;
- Datum[3] = Item.Name == DefaultNames[Item.ClassName] and '' or Item.Name;
- Datum[4] = Item.Texture;
- Datum[5] = Item.Transparency;
- Datum[6] = Item.Face.Value;
- Data.Items[Index] = Datum;
- end;
- if Item.ClassName == 'Texture' then
- local Datum = Data.Items[Index];
- Datum[7] = Item.StudsPerTileU;
- Datum[8] = Item.StudsPerTileV;
- end;
- if Item:IsA 'Light' then
- local Datum = {};
- Datum[1] = Types[Item.ClassName];
- Datum[2] = Keys[Item.Parent] or 0;
- Datum[3] = Item.Name == DefaultNames[Item.ClassName] and '' or Item.Name;
- Datum[4] = Item.Brightness;
- Datum[5] = Item.Color.r;
- Datum[6] = Item.Color.g;
- Datum[7] = Item.Color.b;
- Datum[8] = Item.Enabled and 1 or 0;
- Datum[9] = Item.Shadows and 1 or 0;
- Data.Items[Index] = Datum;
- end;
- if Item.ClassName == 'PointLight' then
- local Datum = Data.Items[Index];
- Datum[10] = Item.Range;
- end;
- if Item.ClassName == 'SpotLight' then
- local Datum = Data.Items[Index];
- Datum[10] = Item.Range;
- Datum[11] = Item.Angle;
- Datum[12] = Item.Face.Value;
- end;
- if Item.ClassName == 'SurfaceLight' then
- local Datum = Data.Items[Index];
- Datum[10] = Item.Range;
- Datum[11] = Item.Angle;
- Datum[12] = Item.Face.Value;
- end;
- if Item.ClassName == 'Smoke' then
- local Datum = {};
- Datum[1] = Types[Item.ClassName];
- Datum[2] = Keys[Item.Parent] or 0;
- Datum[3] = Item.Name == DefaultNames[Item.ClassName] and '' or Item.Name;
- Datum[4] = Item.Enabled and 1 or 0;
- Datum[5] = Item.Color.r;
- Datum[6] = Item.Color.g;
- Datum[7] = Item.Color.b;
- Datum[8] = Item.Size;
- Datum[9] = Item.RiseVelocity;
- Datum[10] = Item.Opacity;
- Data.Items[Index] = Datum;
- end;
- if Item.ClassName == 'Fire' then
- local Datum = {};
- Datum[1] = Types[Item.ClassName];
- Datum[2] = Keys[Item.Parent] or 0;
- Datum[3] = Item.Name == DefaultNames[Item.ClassName] and '' or Item.Name;
- Datum[4] = Item.Enabled and 1 or 0;
- Datum[5] = Item.Color.r;
- Datum[6] = Item.Color.g;
- Datum[7] = Item.Color.b;
- Datum[8] = Item.SecondaryColor.r;
- Datum[9] = Item.SecondaryColor.g;
- Datum[10] = Item.SecondaryColor.b;
- Datum[11] = Item.Heat;
- Datum[12] = Item.Size;
- Data.Items[Index] = Datum;
- end;
- if Item.ClassName == 'Sparkles' then
- local Datum = {};
- Datum[1] = Types[Item.ClassName];
- Datum[2] = Keys[Item.Parent] or 0;
- Datum[3] = Item.Name == DefaultNames[Item.ClassName] and '' or Item.Name;
- Datum[4] = Item.Enabled and 1 or 0;
- Datum[5] = Item.SparkleColor.r;
- Datum[6] = Item.SparkleColor.g;
- Datum[7] = Item.SparkleColor.b;
- Data.Items[Index] = Datum;
- end;
- if Item.ClassName == 'Model' then
- local Datum = {};
- Datum[1] = Types[Item.ClassName];
- Datum[2] = Keys[Item.Parent] or 0;
- Datum[3] = Item.Name == DefaultNames[Item.ClassName] and '' or Item.Name;
- Datum[4] = Item.PrimaryPart and Keys[Item.PrimaryPart] or 0;
- Data.Items[Index] = Datum;
- end;
- -- Spread the workload over time to avoid locking up the CPU
- if Index % 100 == 0 then
- wait(0.01);
- end;
- end;
- -- Return the serialized data
- return HttpService:JSONEncode(Data);
- end;
- function Serialization.InflateBuildData(Data)
- -- Returns an inflated version of the given build data
- local Build = {};
- local Instances = {};
- -- Create each instance
- for Index, Datum in ipairs(Data.Items) do
- -- Inflate BaseParts
- if Datum[1] == Types.Part
- or Datum[1] == Types.WedgePart
- or Datum[1] == Types.CornerWedgePart
- or Datum[1] == Types.VehicleSeat
- or Datum[1] == Types.Seat
- or Datum[1] == Types.TrussPart
- then
- local Item = Instance.new(Support.FindTableOccurrence(Types, Datum[1]));
- Item.Size = Vector3.new(unpack(Support.Slice(Datum, 4, 6)));
- Item.CFrame = CFrame.new(unpack(Support.Slice(Datum, 7, 18)));
- Item.Color = Color3.new(Datum[19], Datum[20], Datum[21]);
- Item.Material = Datum[22];
- Item.Anchored = Datum[23] == 1;
- Item.CanCollide = Datum[24] == 1;
- Item.Reflectance = Datum[25];
- Item.Transparency = Datum[26];
- Item.TopSurface = Datum[27];
- Item.BottomSurface = Datum[28];
- Item.FrontSurface = Datum[29];
- Item.BackSurface = Datum[30];
- Item.LeftSurface = Datum[31];
- Item.RightSurface = Datum[32];
- -- Register the part
- Instances[Index] = Item;
- end;
- -- Inflate specific Part properties
- if Datum[1] == Types.Part then
- local Item = Instances[Index];
- Item.Shape = Datum[33];
- end;
- -- Inflate specific VehicleSeat properties
- if Datum[1] == Types.VehicleSeat then
- local Item = Instances[Index];
- Item.MaxSpeed = Datum[33];
- Item.Torque = Datum[34];
- Item.TurnSpeed = Datum[35];
- end;
- -- Inflate specific TrussPart properties
- if Datum[1] == Types.TrussPart then
- local Item = Instances[Index];
- Item.Style = Datum[33];
- end;
- -- Inflate SpecialMesh instances
- if Datum[1] == Types.SpecialMesh then
- local Item = Instance.new('SpecialMesh');
- Item.MeshType = Datum[4];
- Item.MeshId = Datum[5];
- Item.TextureId = Datum[6];
- Item.Offset = Vector3.new(unpack(Support.Slice(Datum, 7, 9)));
- Item.Scale = Vector3.new(unpack(Support.Slice(Datum, 10, 12)));
- Item.VertexColor = Vector3.new(unpack(Support.Slice(Datum, 13, 15)));
- -- Register the mesh
- Instances[Index] = Item;
- end;
- -- Inflate Decal instances
- if Datum[1] == Types.Decal or Datum[1] == Types.Texture then
- local Item = Instance.new(Support.FindTableOccurrence(Types, Datum[1]));
- Item.Texture = Datum[4];
- Item.Transparency = Datum[5];
- Item.Face = Datum[6];
- -- Register the Decal
- Instances[Index] = Item;
- end;
- -- Inflate specific Texture properties
- if Datum[1] == Types.Texture then
- local Item = Instances[Index];
- Item.StudsPerTileU = Datum[7];
- Item.StudsPerTileV = Datum[8];
- end;
- -- Inflate Light instances
- if Datum[1] == Types.PointLight
- or Datum[1] == Types.SpotLight
- or Datum[1] == Types.SurfaceLight
- then
- local Item = Instance.new(Support.FindTableOccurrence(Types, Datum[1]));
- Item.Brightness = Datum[4];
- Item.Color = Color3.new(unpack(Support.Slice(Datum, 5, 7)));
- Item.Enabled = Datum[8] == 1;
- Item.Shadows = Datum[9] == 1;
- -- Register the light
- Instances[Index] = Item;
- end;
- -- Inflate specific PointLight properties
- if Datum[1] == Types.PointLight then
- local Item = Instances[Index];
- Item.Range = Datum[10];
- end;
- -- Inflate specific SpotLight properties
- if Datum[1] == Types.SpotLight then
- local Item = Instances[Index];
- Item.Range = Datum[10];
- Item.Angle = Datum[11];
- Item.Face = Datum[12];
- end;
- -- Inflate specific SurfaceLight properties
- if Datum[1] == Types.SurfaceLight then
- local Item = Instances[Index];
- Item.Range = Datum[10];
- Item.Angle = Datum[11];
- Item.Face = Datum[12];
- end;
- -- Inflate Smoke instances
- if Datum[1] == Types.Smoke then
- local Item = Instance.new('Smoke');
- Item.Enabled = Datum[4] == 1;
- Item.Color = Color3.new(unpack(Support.Slice(Datum, 5, 7)));
- Item.Size = Datum[8];
- Item.RiseVelocity = Datum[9];
- Item.Opacity = Datum[10];
- -- Register the smoke
- Instances[Index] = Item;
- end;
- -- Inflate Fire instances
- if Datum[1] == Types.Fire then
- local Item = Instance.new('Fire');
- Item.Enabled = Datum[4] == 1;
- Item.Color = Color3.new(unpack(Support.Slice(Datum, 5, 7)));
- Item.SecondaryColor = Color3.new(unpack(Support.Slice(Datum, 8, 10)));
- Item.Heat = Datum[11];
- Item.Size = Datum[12];
- -- Register the fire
- Instances[Index] = Item;
- end;
- -- Inflate Sparkles instances
- if Datum[1] == Types.Sparkles then
- local Item = Instance.new('Sparkles');
- Item.Enabled = Datum[4] == 1;
- Item.SparkleColor = Color3.new(unpack(Support.Slice(Datum, 5, 7)));
- -- Register the instance
- Instances[Index] = Item;
- end;
- -- Inflate Model instances
- if Datum[1] == Types.Model then
- local Item = Instance.new('Model');
- -- Register the model
- Instances[Index] = Item;
- end;
- end;
- -- Set object values on each instance
- for Index, Datum in pairs(Data.Items) do
- -- Get the item's instance
- local Item = Instances[Index];
- -- Set each item's parent and name
- if Item and Datum[1] <= 15 then
- Item.Name = (Datum[3] == '') and DefaultNames[Item.ClassName] or Datum[3];
- if Datum[2] == 0 then
- table.insert(Build, Item);
- else
- Item.Parent = Instances[Datum[2]];
- end;
- end;
- -- Set model primary parts
- if Item and Datum[1] == 15 then
- Item.PrimaryPart = (Datum[4] ~= 0) and Instances[Datum[4]] or nil;
- end;
- end;
- -- Return the model
- return Build;
- end;
- -- Return the API
- return Serialization;]]></ProtectedString>
- </Properties>
- </Item>
- </Item>
- </roblox>
Advertisement
Add Comment
Please, Sign In to add comment