Advertisement
StefanBashkir

dl Library V 0.5

Nov 17th, 2014
223
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 20.68 KB | None | 0 0
  1. --[[
  2.     dl library V0.5
  3.     MrNicNac/StefanBashkir/DrMathematica
  4.    
  5.     -- Raw log:
  6.    
  7.     **************** DetermineROBLOXType ****************
  8.         :: Parameters ::
  9.             *UnknownType (?)   
  10.      => Determines the 'type' of the value given. If it's a Lua type, it returns type(UnknownType).
  11.         Else, it will determine if it is a Lua type. Only distinguishable checks are available.
  12.             ||| Object,CFrame,Vector3,Vector2,BrickColor,Color3 |||
  13.            
  14.     RETURNS: string
  15.            
  16.     **************** ConcatTable ****************
  17.         :: Parameters ::
  18.             *Table (table)
  19.             ToAppend (string/number/bool)
  20.             Func (function)
  21.      => Works similar to table.concat. However, allows yout pass a function to evaluate the concatenation before it happens.
  22.         It has this form
  23.         Func(index,value, lengthOfOriginalTable)
  24.             ::::: Where index is the position of the current value becing concatenated, and value is that actual value.
  25.         If you use Func, you should input "" for ToAppend.
  26.        
  27.     RETURNS: string
  28.        
  29.     **************** GetDescendants ****************
  30.         :: Parameters ::
  31.             *Instance (object)
  32.      => Returns a table of all children and descendants (literally everything inside) Instance.
  33.    
  34.     RETURNS: table
  35.    
  36.     **************** FindValueInTable ****************
  37.         :: Parameters ::
  38.             *Table (table)
  39.             *Value (lua data)
  40.             Recurse (bool)
  41.      => Searches through a table to find a value. Will return true or false. If Recurse is set to true, will search inside
  42.         all tables included in Table as well as inside their tables, and their tables, and so on..
  43.        
  44.     RETURNS: bool
  45.        
  46.     **************** GetByClass ****************
  47.         :: Parameters ::
  48.             *SearchInObject (object)
  49.             *ClassName (string)
  50.             AllowSuperClasses (bool)
  51.             ExcludedNames (table)
  52.             ExcludedClasses (table)
  53.      => Searches through the entire SearchInObject (descendants as well) for the needed ClassName. If AllowSuperClasses is
  54.         true, it will use IsA instead of .ClassName. If either of the last two parameters are set, it will exclude the given
  55.         values of either names or classes in the tables.
  56.        
  57.     RETURNS: table
  58.        
  59.     **************** FormatRegion3 ****************
  60.         :: Parameters ::
  61.             *V31 (vector3)
  62.             *V32 (vector3)
  63.      => Returns a correctly-formatted Region3 value. Normally, you'd have to find the max and min x/y/z values of each v3
  64.         and build a Region3 afterwards.
  65.        
  66.     **************** GetSurfaceClosestToPoint ****************
  67.         :: Parameters ::
  68.             *Part (object)
  69.             *Point (vector3)
  70.      => Uses simple relational math to find which surface on the given part the given point is closest to (or on).
  71.    
  72.     RETURNS: enum
  73.    
  74.     **************** GetFaceDirections ****************
  75.         :: Parameters ::
  76.             *Part (object)
  77.     => Returns directions similar to how lookVector works on a part's CFrame. However, gives you ease of access to all
  78.         'directional' vectors of a part. DOES NOT HANDLE CASE OF ODD SHAPES (i.e. wedge) Gives up,down,left,right,front,
  79.         back vectors.
  80.        
  81.     RETURNS: table
  82.    
  83.     **************** SearchCuboidArea ****************
  84.         :: Parameters ::
  85.             *Center (vector3)
  86.             *CubicRadius (scalar number)
  87.             IgnoreObjects (table)[of userdata]
  88.             IgnoreNames (table)[of strings]
  89.             IgnoreClasses (table)[of strings]
  90.             VisuallyShowCubicSearchArea (bool)
  91.     => Searches a cube area for any objects. Will correctly ignore any provided object userdata, names, or classes.
  92.        
  93.     RETURNS: table
  94.    
  95.     **************** InstantWeld ****************
  96.         :: Parameters ::
  97.             *MainPart (object)
  98.             *LegacyPart (object)
  99.     => Welds two parts together at their location exactly at the time of the function call. Basically, they will stay in the
  100.         same place they were before the call, but will now be welded through a 'Weld' joint. Will return the weld that it
  101.         creates.
  102.        
  103.     RETURNS: object
  104.    
  105.     **************** ForEach ****************
  106.         :: Parameters ::
  107.             *SearchableItem (object/table/string);
  108.             FunctionToExecute (func)
  109.     => Will loop through the object or table given and fire 'FunctionToExecute' on each one with the i,v arguments (index/value).
  110.         If given a string, it will loop through each character of that string and fire 'FunctionToExecute' with i,v arguments.
  111.         The 'i' when using a string indicates the position of the character, and 'v' is the literal character.
  112.        
  113.     RETURNS: 0
  114.    
  115.     **************** Tokenize ****************
  116.         :: Parameters ::
  117.             *String (string/object)
  118.             *Token (string)
  119.     => Splits a string into parts using the token as a delimiter. Returns a table of the split string.
  120.        
  121.     RETURNS: table
  122.    
  123.     **************** AngleBetweenVectors ****************
  124.         :: Parameters ::
  125.             *v1 (vector3/vector2)
  126.             *v2 (vector3/vector2)
  127.     => Returns the angle (in radians) between the given two vectors.
  128.        
  129.     RETURNS: number (radians)
  130.    
  131.     **************** PointDesiredAngleAt ****************
  132.         :: Parameters ::
  133.             *Motor (object)
  134.             *LookAt (vector3/object)
  135.             DoNotAutomaticallySetAngle (bool)
  136.     => Sets the DesiredAngle property of the given motor to the correct angle in order to be facing the LookAt argument.
  137.         In addition, will return the angle. If DoNotAutomaticallySetAngle is set, will not set the angle for you; it will just
  138.         return the angle to satisfy the angle looking at LookAt.
  139.        
  140.         Keep in mind that, if you are testing this, you must remove the Animate script from your character.
  141.        
  142.     RETURNS: number (radians)
  143.    
  144.     **************** Shuffle ****************
  145.         :: Parameters ::
  146.             *Table (table)
  147.     => Randomizes the order of the elements in the table. Returns the shuffled table.
  148.  
  149.     RETURNS: table
  150. --]]
  151.  
  152. dl = { -- Do not make local, or else it cannot reference itself from within
  153.     ['TestValue'] = true;
  154.     ['DetermineROBLOXType'] = function(UnknownType)
  155.         if (type(UnknownType) == "userdata") then
  156.             -- If it's a userdata, we have a loose-typed value and it must be determined using tests.
  157.             -- Get the value of the return from __tostring metamethod
  158.             local Food = tostring(UnknownType)
  159.             -- First test if it is an object
  160.             if (pcall(function() local X = UnknownType.GetFullName end)) then
  161.                 -- It passed the first test of being an object
  162.                 -- Next is to test it against Lua data type (which, in ROBLOX, return nil for indexing this)
  163.                 if (UnknownType.GetFullName ~= nil)then
  164.                     return "object"
  165.                 end
  166.             else
  167.                 -- This 'Food' is not an object
  168.                 -- It must be another ROBLOX datatype
  169.                 if (Food:find(".-,.-,.-,.-,.-,.-,.-,.-,.-,.-,.-,.-")) then
  170.                     return "cframe"
  171.                 elseif (Food:find(".-,.-,.-")) then
  172.                     -- Only a Vector3 has this format
  173.                     return "vector3"
  174.                 elseif (Food:find(".-,.-")) then
  175.                     -- A Vector3 and Vector2 have this format, but we checked for a Vector3 first. So if this format occurs
  176.                     -- after the Vector3 check, then it is a Vector2
  177.                     return "vector2"
  178.                 elseif (pcall(function() local X = UnknownType.Color end)) then
  179.                     return "brickcolor";
  180.                 elseif (pcall(function() local X = UnknownType.r end)) and (pcall(function() local X = UnknownType.g end)) then
  181.                     return "color3";
  182.                 else
  183.                     return "userdata", "unknown";
  184.                     --error("dl: Unsupported Data Type");
  185.                 end
  186.             end
  187.         else
  188.             return type(UnknownType);
  189.         end
  190.     end;
  191.     ['ConcatTable'] = function(TableToConcat, append, Func)
  192.         -- Calls tostring, unlike table.concat.  'Func' passes the string being concatenated and the index that the string is
  193.             -- from the given table.
  194.         -- However, table.concat is always going to be faster
  195.         if (type(TableToConcat) ~= "table") then
  196.             error("dl: ConcatTable requires a table as first argument. Received: " .. type(TableToConcat));
  197.         end
  198.         local _ = "";
  199.         if not (append) then
  200.             append = "";
  201.         end
  202.         for i,v in pairs(TableToConcat) do
  203.             local V = tostring(v)
  204.             local ToAppend;
  205.             if (Func) then
  206.                 if (type(Func) == "function") then
  207.                     ToAppend = Func(i, V, #TableToConcat);
  208.                     _ = _ .. ToAppend
  209.                 else
  210.                     error("dl: Third argument to concat must be a function or nil");
  211.                 end
  212.             else
  213.                 _ = _ .. V .. (i < #TableToConcat and append or "")
  214.             end
  215.         end
  216.         return _;
  217.     end;
  218.     ['GetDescendants'] = function(instance)
  219.         local All = {}
  220.         if (dl.DetermineROBLOXType(instance) ~= "object") then
  221.             error("dl: getdescendants requires an object");
  222.         end
  223.         local function Get(parent)
  224.             for i,v in pairs(parent:GetChildren()) do
  225.                 if (#v:GetChildren() > 0) then
  226.                     Get(v);
  227.                 end
  228.                 table.insert(All, v)
  229.             end
  230.         end
  231.         Get(instance);
  232.         return All;
  233.     end;
  234.     ['FindValueInTable'] = function(Table, Value, Recurse)
  235.         if not (Recurse) then
  236.             Recurse = false;
  237.         end
  238.         if (type(Recurse) ~= "boolean") then
  239.             error("dl: third argument of FindValueInTable must be a boolean. Received: " .. type(Recurse));
  240.         end
  241.         local Recurse = (Recurse ~= nil) and Recurse or false;
  242.         local item;
  243.         local function Search(_t)
  244.             for i,v in pairs(_t) do
  245.                 if (item) then break end
  246.                 if (type(v) == "table") and (Recurse) and (v ~= Value) then
  247.                     Search(v)
  248.                 elseif (v == Value) then
  249.                     item = v;
  250.                 end
  251.             end
  252.         end
  253.         Search(Table)
  254.         if (item) then
  255.             return true;
  256.         end
  257.         return false;
  258.     end;
  259.     ['GetByClass'] = function(Parent, className, AllowSuperClass, ExcludedNames, ExcludedClasses)
  260.         -- This function is expensive as hell
  261.         if not (Parent) then
  262.             error("dl: GetByClass's first argument must not be nil.")
  263.         end
  264.         if (dl.DetermineROBLOXType(Parent) ~= "object") then
  265.             error("dl: GetByClass's first argument must be an object.")
  266.         end
  267.         if not (ExcludedNames) then
  268.             ExcludedNames = {};
  269.         end
  270.         if not (ExcludedClasses) then
  271.             ExcludedClasses = {};
  272.         end
  273.         if (type(ExcludedNames) ~= "table") then
  274.             error("dl: GetByClass requires its fourth argument to be a table or nil");
  275.         end
  276.         if (type(ExcludedClasses) ~= "table") then
  277.             error("dl: GetByClass requires its fifth argument to be a table or nil");
  278.         end
  279.         local Collection = {};
  280.         local GameObjects = dl.GetDescendants(Parent);
  281.         for i,v in pairs(GameObjects) do
  282.             if (AllowSuperClass) then
  283.                 if v:IsA(className) then
  284.                     if not (dl.FindValueInTable(ExcludedNames, v.Name)) and not (dl.FindValueInTable(ExcludedClasses, v.className)) then
  285.                         table.insert(Collection, v)
  286.                     end
  287.                 end
  288.             else
  289.                 if (v.className == className) then
  290.                     if not (dl.FindValueInTable(ExcludedNames, v.Name)) and not (dl.FindValueInTable(ExcludedClasses, v.className)) then
  291.                         table.insert(Collection, v)
  292.                     end
  293.                 end
  294.             end
  295.         end
  296.         return Collection;
  297.     end;
  298.     ['FormatRegion3'] = function(v3,_v3)
  299.         if (v3.x == _v3.x) or (v3.y == _v3.y) or (v3.z == _v3.z) then
  300.             error("GetFormattedRegion3 cannot format a Region3 given these coordinates. One or more of the x,y or z values is equal to that of the opposite argument.");
  301.         end
  302.         return Region3.new(
  303.             Vector3.new(
  304.                 math.min(v3.x, _v3.x),
  305.                 math.min(v3.y,_v3.y),
  306.                 math.min(v3.z,_v3.z)
  307.             ),
  308.             Vector3.new(
  309.                 math.max(v3.x, _v3.x),
  310.                 math.max(v3.y,_v3.y),
  311.                 math.max(v3.z,_v3.z)
  312.             )
  313.         )
  314.     end;
  315.     ['GetSurfaceClosestToPoint'] = function(part, pos)
  316.         if (dl.DetermineROBLOXType(part) ~= "object") then
  317.                 error("dl: GetSurfaceClosestToPoint requires an object.");
  318.         end
  319.         local _, count = tostring(pos):gsub(",",",");
  320.         if (dl.DetermineROBLOXType(part) ~= "vector3") then
  321.                 error("dl: Argument 2 for GetSurfaceClosestToPoint must be a Vector3.");
  322.         end
  323.         local rel = part.CFrame:pointToObjectSpace(pos)
  324.         if (math.abs(rel.Z) > math.abs(rel.Y)) and (math.abs(rel.Z) > math.abs(rel.X)) then
  325.                 if (rel.Z > 0) then
  326.                         return Enum.NormalId.Back
  327.                 else
  328.                         return Enum.NormalId.Front
  329.                 end
  330.         elseif (math.abs(rel.Y) > math.abs(rel.Z)) and (math.abs(rel.Y) > math.abs(rel.X)) then
  331.                 if (rel.Y > 0) then
  332.                         return Enum.NormalId.Top
  333.                 else
  334.                         return Enum.NormalId.Bottom
  335.                 end    
  336.         elseif (math.abs(rel.X) > math.abs(rel.Z) and math.abs(rel.X) > math.abs(rel.Y)) then
  337.                 if (rel.X > 0) then
  338.                         return Enum.NormalId.Right
  339.                 else
  340.                         return Enum.NormalId.Left
  341.                 end    
  342.         end
  343.     end;
  344.     ['GetFaceDirections'] = function(instance)
  345.         local directions = {};
  346.         if (dl.DetermineROBLOXType(instance) ~= "object") then
  347.                 error("dl: GetFaceDirections requires an object.");
  348.         end
  349.         local matrix = instance.CFrame;
  350.         directions['up'] =
  351.                 matrix:vectorToWorldSpace( Vector3.new(0,1,0) );
  352.         directions['down'] =
  353.                 matrix:vectorToWorldSpace( Vector3.new(0,-1,0) );
  354.         directions['left'] =
  355.                 matrix:vectorToWorldSpace( Vector3.new(-1,0,0) );
  356.         directions['right'] =
  357.                 matrix:vectorToWorldSpace( Vector3.new(1,0,0) );
  358.         directions['front'] =
  359.                 matrix.lookVector;
  360.         directions['back'] =
  361.                 -matrix.lookVector;
  362.         return directions;
  363.     end;
  364.     ['SearchCuboidArea'] = function(Center, CubicRadius, IgnoreObjects, IgnoreNames, IgnoreClasses, Visualize)
  365.         if (dl.DetermineROBLOXType(Center) ~= "vector3") then
  366.             error("dl: First argument of SearchCuboidArea must be a Vector3.");
  367.         end
  368.         if (type(CubicRadius) ~= "number") then
  369.             error("dl: Second argument of SearchCuboidArea must be a number.");
  370.         end
  371.         if not (IgnoreObjects) then
  372.             IgnoreObjects = {};
  373.         end
  374.         if not (IgnoreNames) then
  375.             IgnoreNames = {};
  376.         end
  377.         if not (IgnoreClasses) then
  378.             IgnoreClasses = {};
  379.         end
  380.         if (not type(IgnoreObjects)=="table") or (not type(IgnoreNames)=="table") or (not type(IgnoreClasses)=="table") then
  381.             error("dl: All ignore tables of SearchCuboidArea must either be nil or of type 'table'");
  382.         end
  383.         local SearchVolume = ((CubicRadius*2)^3);
  384.         if (SearchVolume > 99999) then
  385.             print("dl: SearchCuboidArea was given a CubicRadius that exceeds the maximum volume for Region3 set by ROBLOX. Automatically downsizing to fit under 100,000");
  386.             CubicRadius = 23.20775;
  387.         end
  388.         local Corner1 = Center + Vector3.new(CubicRadius,CubicRadius,CubicRadius);
  389.         local Corner2 = Center - Vector3.new(CubicRadius,CubicRadius,CubicRadius);
  390.         local Region3 = dl.FormatRegion3(
  391.             Corner1, Corner2
  392.         )
  393.        
  394.         local FinalCollection = {}
  395.         local Parts = workspace:FindPartsInRegion3WithIgnoreList(Region3, IgnoreObjects);
  396.         -- Check for parts with ignored names or classes
  397.         for i,v in pairs(Parts) do
  398.             if (not dl.FindValueInTable(IgnoreNames, v.Name)) and (not dl.FindValueInTable(IgnoreClasses, v.ClassName)) then
  399.                 table.insert(FinalCollection, v);
  400.             end
  401.         end
  402.         if (Visualize) then
  403.             local Template = Instance.new("Part");
  404.             Template.FormFactor = "Custom";
  405.             Template.Size = Vector3.new(0.01,0.01,CubicRadius * 2);
  406.             Template.Anchored = true;
  407.             Template.Name = "dl_Library:::VisualStrut";
  408.             Template.BrickColor = BrickColor.Yellow();
  409.            
  410.             local Template2 = Template:Clone();
  411.             Template2.Size = Vector3.new(CubicRadius*2, 0.01,0.01);
  412.            
  413.             local Template3 = Template:Clone();
  414.             Template3.Size = Vector3.new(0.01, CubicRadius*2,0.01);
  415.            
  416.             -- Do X sides first
  417.             local X1 = Template:Clone();
  418.             X1.Position = Center + Vector3.new(CubicRadius,CubicRadius,0);
  419.             X1.Parent = workspace
  420.             local X2 = Template:Clone();
  421.             X2.Position = Center + Vector3.new(-CubicRadius,CubicRadius,0);
  422.             X2.Parent = workspace
  423.             local X3 = Template:Clone();
  424.             X3.Position = Center + Vector3.new(-CubicRadius,-CubicRadius,0);
  425.             X3.Parent = workspace
  426.             local X4 = Template:Clone();
  427.             X4.Position = Center + Vector3.new(CubicRadius,-CubicRadius,0);
  428.             X4.Parent = workspace
  429.            
  430.             -- Do Z sides second
  431.             local X1 = Template2:Clone();
  432.             X1.Position = Center + Vector3.new(0,CubicRadius,CubicRadius);
  433.             X1.Parent = workspace
  434.             local X2 = Template2:Clone();
  435.             X2.Position = Center + Vector3.new(0,CubicRadius,-CubicRadius);
  436.             X2.Parent = workspace
  437.             local X3 = Template2:Clone();
  438.             X3.Position = Center + Vector3.new(0,-CubicRadius,-CubicRadius);
  439.             X3.Parent = workspace
  440.             local X4 = Template2:Clone();
  441.             X4.Position = Center + Vector3.new(0,-CubicRadius,CubicRadius);
  442.             X4.Parent = workspace
  443.            
  444.             -- Do Y sides Last
  445.             local X1 = Template3:Clone();
  446.             X1.Position = Center + Vector3.new(CubicRadius,0,CubicRadius);
  447.             X1.Parent = workspace
  448.             local X2 = Template3:Clone();
  449.             X2.Position = Center + Vector3.new(CubicRadius,0,-CubicRadius);
  450.             X2.Parent = workspace
  451.             local X3 = Template3:Clone();
  452.             X3.Position = Center + Vector3.new(-CubicRadius,0,-CubicRadius);
  453.             X3.Parent = workspace
  454.             local X4 = Template3:Clone();
  455.             X4.Position = Center + Vector3.new(-CubicRadius,0,CubicRadius);
  456.             X4.Parent = workspace
  457.            
  458.             local X1,X2,X3,X4 = nil,nil,nil,nil
  459.            
  460.         end
  461.         return FinalCollection;
  462.     end;
  463.     ['InstantWeld'] = function(Part1, Part2)
  464.         if (dl.DetermineROBLOXType(Part1) ~= "object") and (dl.DetermineROBLOXType(Part2) ~= "object") then
  465.             error("dl: InstantWeld's two arguments must both be objects.");
  466.         end
  467.         local W = Instance.new("Weld")
  468.         W.C1 = Part2.CFrame:toObjectSpace(Part1.CFrame);
  469.         W.Part0 = Part1;
  470.         W.Part1 = Part2;
  471.         W.Parent = game.JointsService;
  472.         return W
  473.     end;
  474.     ['ForEach'] = function(Parent, Exe)
  475.         local SearchTable = {};
  476.         local Option = 0;
  477.         if (dl.DetermineROBLOXType(Parent) == "object") then
  478.             SearchTable = Parent:GetChildren()
  479.             Option = 1;
  480.         elseif (dl.DetermineROBLOXType(Parent) == "table") then
  481.             SearchTable = Parent;
  482.             Option = 1;
  483.         elseif (dl.DetermineROBLOXType(Parent) == "string") then
  484.             Option = 2;
  485.         else
  486.             error("dl: ForEach requires its argument to be a ROBLOX object, table, or string.");
  487.         end
  488.         if (Option == 1) then
  489.             for i,v in pairs(SearchTable) do
  490.                 Exe(i,v);
  491.             end
  492.         elseif (Option == 2) then
  493.             for position, character in Parent:gmatch("()(.)") do
  494.                 Exe(position, character);
  495.             end
  496.         end
  497.         return 0;
  498.     end;
  499.     ['Tokenize'] = function(String, Token)
  500.         local Collection = {};
  501.         local IS = ""; -- holds current string after each tokenizing. Used to return the last string with no tokens.
  502.         if (dl.DetermineROBLOXType(String) ~= "string") and (dl.DetermineROBLOXType(String) ~= "object") then
  503.             error("dl Tokenize's first argument expects a string or object. Given: " .. dl.DetermineROBLOXType(String));
  504.         end
  505.         local String = tostring(String); -- handle case of ROBLOX object
  506.         if (dl.DetermineROBLOXType(Token) ~= "string") then
  507.             error("dl: Tokenize's second argument must be a string.");
  508.         end
  509.         IS = String;
  510.         local OriginalString = String;
  511.         for Group, Position in String:gmatch("(.-)" .. Token .. "()") do
  512.             table.insert(Collection, Group);
  513.             String = OriginalString:sub(Position);
  514.         end
  515.         if (String:len() > 0) then
  516.             table.insert(Collection, String);
  517.         end
  518.         return Collection;
  519.     end;
  520.     ['AngleBetweenVectors'] = function(v1,v2)
  521.         local Type1,Type2 = dl.DetermineROBLOXType(v1), dl.DetermineROBLOXType(v2)
  522.         if (Type1 ~= "vector3") or (Type2 ~= "vector3") then
  523.             if (Type1 ~= "vector2") or (Type2 ~= "vector2") then
  524.                 error("dl: AngleBetweenVectors requires both arguments to be a Vector3 or Vector2");
  525.             end
  526.         end
  527.         if (Type1 ~= Type2) then
  528.             error("dl: AngleBetweenVectors requires that both arguments be the same type of vector.");
  529.         end
  530.         local DotProduct;
  531.         if (Type1 == "vector3") then
  532.             DotProduct = v1:Dot(v2);
  533.         else
  534.             -- Vector2 doesn't have the .Dot function for some reason :|
  535.             DotProduct = ( v1.x * v2.x + v1.y * v2.y );
  536.         end
  537.         return math.acos(DotProduct/(v1.magnitude*v2.magnitude));
  538.     end;
  539.     ['PointDesiredAngleAt'] = function(Motor, LookAt, DoNotLiveAdjustJoint)
  540.         if (dl.DetermineROBLOXType(Motor) ~= "object") or not (pcall(function() local X = Motor.DesiredAngle end)) then
  541.             error("dl: PointDesiredAngleAt requires the first argument be an object with a DesiredAngle property.");
  542.         end
  543.         if (dl.DetermineROBLOXType(LookAt) ~= "object") and (dl.DetermineROBLOXType(LookAt) ~= "vector3") then
  544.             error("dl: PointDesiredAngleAt requires the second argument to be an object or a vector3");
  545.         end
  546.         if (dl.DetermineROBLOXType(LookAt) == "object") then
  547.             LookAt = LookAt.Position;
  548.         end
  549.         local Variance = (LookAt - Motor.Part0.Position)['unit'];
  550.         local Variance_Delimiter = Vector3.new(Variance.X,Variance.Y,0);
  551.         local Theta = dl['AngleBetweenVectors'](Vector3.new(0,-1,0), Variance_Delimiter);
  552.         if (not DoNotLiveAdjustJoint) then
  553.             Motor.DesiredAngle = Theta;
  554.         end
  555.         return Theta;
  556.     end;
  557.     ['Shuffle'] = function(Table)
  558.         -- Uses Yates shuffling algorithm
  559.         math.random(); math.randomseed(tick()); math.random();
  560.         local n, order, res = #Table, {}, {};
  561.         for i=1,n do
  562.             order[i] = { rnd = math.random(), idx = i }
  563.         end
  564.         table.sort(order, function(a,b) return a.rnd < b.rnd end)
  565.         for i=1,n do
  566.             res[i] = Table[order[i].idx]
  567.         end
  568.         return res
  569.     end;
  570.     -- Ray cast 360 degrees from a point?
  571.     -- Ray cast in an arc for cone of sight?
  572. }
  573.  
  574. return dl
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement