Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local Plugin = PluginManager():CreatePlugin()
- local Button = Plugin:CreateToolbar("Triangle Workshop"):CreateButton("", "Master", "tangle.png")
- local DEB = false;
- local active = false
- local ds = Vector3.new(10,0,10); -- default size
- local preId = "_TRIANGLE_"
- local preIdlen = preId:len()
- local tmodel = Workspace:FindFirstChild("Triangles") or Instance.new("Model", Workspace)
- tmodel.Name = "Triangles"
- local handles = Instance.new("Handles")
- handles.Style = Enum.HandlesStyle.Resize;
- handles.Color = BrickColor.White();
- handles.Parent = Game.CoreGui
- local previncrement;
- local controldown = false;
- local shiftdown = false;
- local cbyte = 50
- local shiftbyte = 48
- local orangehandles = {}
- local triangles = {}
- local newtransparency = 1
- local addconnectoricon = "rbxasset://textures\\CameraZoomIn_ovr.png"
- local mouseoverhandleicon = "rbxasset://textures\\advClosed-hand.png"
- local showninstructions = false
- local connectors = {};
- local increment = 1;
- local lastpress = 1e50;
- pcall(function() game:WaitForChild("CoreGui").MrNicNacTriangles:Destroy() end)
- local _sg = Instance['new']("ScreenGui", game:WaitForChild("CoreGui"));
- _sg.Name = "MrNicNacTriangles";
- local _f = Instance['new']("Frame", _sg);
- _f.Size = UDim2['new'](.3, 0, .175,0);
- _f.Style = "RobloxRound";
- _f.Position = UDim2.new(.5 - (_f.Size.X.Scale/2) ,0, .5 - (_f.Size.Y.Scale/2),0);
- local _tl = Instance['new']("TextLabel", _f)
- _tl.Size = UDim2.new(1,0,.4,0);
- _tl.TextColor3 = Color3.new(1,1,1);
- _tl.TextScaled = true;
- _tl.BackgroundTransparency = 1;
- _tl.Text = "Movement Increment"
- local _tb = Instance['new']("TextBox", _f)
- _tb.Size = UDim2.new(1,0, .6,0)
- _tb.Position = UDim2.new(0,0,.4,0);
- _tb.TextColor3 = Color3.new(1,1,1)
- _tb.BackgroundColor3 = Color3.new(.7,.7,.7);
- _tb.Text = increment;
- _tb.TextScaled = true;
- _f.Visible = false;
- wait(1)
- print("TRIANGLE WORKSHOP: GETTING EXISTING VALUES")
- -- get selection boxes and triangles
- for i,v in pairs(Workspace:GetChildren()) do
- if v.Name == "Triangle" and v:IsA("Model") then
- for k,j in pairs(v:GetChildren()) do
- if j.Name:sub(1,4) == "Side" then
- for x,y in pairs(j:GetChildren()) do
- if y:FindFirstChild("SelectionBox") then
- y.SelectionBox:Destroy()
- end
- if y.Name:sub(1, preIdlen) == preId then
- y.Transparency = .65
- y.BrickColor = BrickColor.new("Deep orange");
- table.insert(orangehandles, y)
- end
- if y.Name:sub(1,1) == "P" then
- table.insert(triangles, y)
- end
- end
- end
- end
- end
- end
- print("VALUES GATHERED");
- Button.Click:connect(function()
- if DEB then return end
- DEB = true;
- if not showninstructions then
- showninstructions = true
- print("------------------------------------------------------------------------")
- print("Press 'n' to create a new triangle plate")
- print("Click on the orange handles to activate dragging.")
- print("Hold Ctrl+Click on the orange handles to select one. Select three of them simultaneously to fill in an area.")
- print("Hold Shift+Click on a triangle surface to delete the triangle plate.")
- print("Press 't' to toggle the orange handles.")
- print("Press 'y' to finalize your work. WARNING: triangles are compiled into one model and orange handles completely destroyed.")
- print("------------------------------------------------------------------------")
- end
- Plugin:Activate(not active);
- Button:SetActive(not active)
- active = not active
- if active then
- local Mouse = Plugin:GetMouse()
- --[[ Icons don't work
- mousemove = Mouse.Move:connect(function()
- local target = Mouse.Target
- if not target then return nil end
- if target.Name:sub(1, preIdlen) == preId and target.Parent.Name:sub(1,4) == "Side" then
- print("over handle")
- Mouse.Icon = mouseoverhandleicon
- else
- Mouse.Icon = ""
- end
- end)]]
- keydown = Mouse.KeyDown:connect(function(key)
- --print("Key down: " .. key:byte())
- if key == "n" then
- local triangle = Instance.new("Model", Workspace)
- triangle.Name = "Triangle"
- local center = Workspace.CurrentCamera.CoordinateFrame.p + (Workspace.CurrentCamera.CoordinateFrame.lookVector * 5) --Vector3.new(0,0,0)
- center = Vector3.new(math.floor(center.x), math.floor(center.y), math.floor(center.z))
- local c1, c2 = (center+Vector3.new(ds.X/2, 0, ds.Z/2)), (center+Vector3.new(-ds.X/2, 0, ds.Z/2))
- local c3, c4 = (center+Vector3.new(ds.X/2, 0, -ds.Z/2)),(center+Vector3.new(-ds.X/2, 0, -ds.Z/2))
- local side1 = draw(c1, c2, c3, 1); side1.Parent = triangle
- local side2 = draw(c4, c3, c2, 2); side2.Parent = triangle
- plothandle(c1, side1, 1)
- plothandle(c2, side1, 2)
- plothandle(c3, side1, 3)
- -- Next side
- plothandle(c4, side2, 1)
- --plothandle(c3, side2, 2)
- --plothandle(c2, side2, 3)
- elseif key:byte() == cbyte then
- controldown = true
- elseif key:byte() == shiftbyte then
- shiftdown = true;
- elseif key == "t" then
- for i,v in pairs(orangehandles) do
- v.Transparency = newtransparency
- end
- if newtransparency == 1 then
- newtransparency = .65
- else
- newtransparency = 1
- end
- elseif key == "y" then
- for i,v in pairs(orangehandles) do
- v:Destroy()
- end
- if not Workspace:FindFirstChild("Triangles") then
- tmodel = Instance.new("Model", Workspace)
- tmodel.Name = "Triangles"
- end
- for i,v in pairs(triangles) do
- if v.Parent then
- v.Parent = tmodel
- end
- end
- triangles = {}
- orangehandles = {}
- for i,v in pairs(Workspace:GetChildren()) do
- if v.Name == "Triangle" and v:IsA("Model") and v:FindFirstChild("Side_1") then
- pcall(function()
- v:Destroy()
- end)
- end
- end
- --[[elseif key == "+" then
- increment = increment + .05
- _tb.Text = increment;]]
- elseif key == "-" then
- if increment > 0 and increment-.05 > 0 then
- _f.Visible = true;
- lastpress = tick();
- increment = increment - .05
- _tb.Text = increment;
- wait(1)
- if tick()-lastpress >= .95 then
- _f.Visible = false;
- end
- end
- end
- end)
- keyup = Mouse.KeyUp:connect(function(key)
- print(key, key:byte());
- if key:byte() == cbyte then
- controldown = false
- DisconnectConnectors();
- elseif key:byte() == shiftbyte then
- shiftdown = false
- elseif key == "=" then
- _f.Visible = true;
- lastpress = tick();
- increment = increment + .05
- _tb.Text = increment;
- wait(1)
- if tick()-lastpress >= .95 then
- _f.Visible = false;
- end
- end
- end)
- button1down = Mouse.Button1Down:connect(function()
- local target = Mouse.Target
- if not target then handles.Adornee = nil return nil end
- if target.Name:sub(1, preIdlen) == preId and target.Parent.Name:sub(1,4) == "Side" then
- if not controldown then
- handles.Adornee = target
- elseif controldown then
- handles.Adornee = nil
- if #connectors < 3 then
- if not TableFind(connectors, target) then
- local s = Instance.new("Sparkles", target)
- s.Name = "Sparkles"
- connectors[#connectors+1] = target
- if #connectors == 3 then
- -- draw filling triangle
- local triangle = Instance.new("Model", Workspace)
- triangle.Name = "Triangle"
- local side1 = draw(connectors[1].Position,connectors[2].Position,connectors[3].Position,1); side1.Parent = triangle
- --local side2 = draw(connectors[4].Position,connectors[3].Position,connectors[2].Position,2); side2.Parent = triangle
- plothandle(connectors[1].Position, side1, 1)
- plothandle(connectors[2].Position, side1, 2)
- plothandle(connectors[3].Position, side1, 3)
- DisconnectConnectors()
- end
- end
- end
- end
- elseif (target.Name == "P0" or target.Name == "P1") and (target.Parent.Name:sub(1,4) == "Side") then
- if shiftdown then
- target.Parent.Parent:Destroy()
- end
- else
- handles.Adornee = nil
- end
- end)
- mousedrag = handles.MouseDrag:connect(function(normalid, angle, radius)
- local direction = handles.Adornee.CFrame:vectorToWorldSpace(Vector3.FromNormalId(normalid))
- if not previncrement then
- if angle >= 1 then
- previncrement = angle
- handles.Adornee.CFrame = handles.Adornee.CFrame * CFrame.new(direction * (tonumber(increment) and tonumber(increment) or 1))
- RedrawSide(handles.Adornee.Parent)
- elseif angle <= -1 then
- previncrement = angle
- handles.Adornee.CFrame = handles.Adornee.CFrame * CFrame.new(direction * -(tonumber(increment) and tonumber(increment) or 1))
- RedrawSide(handles.Adornee.Parent)
- end
- else
- if angle - previncrement >= 1 then
- previncrement = angle
- handles.Adornee.CFrame = handles.Adornee.CFrame * CFrame.new(direction * (tonumber(increment) and tonumber(increment) or 1))
- RedrawSide(handles.Adornee.Parent)
- elseif angle - previncrement <= -1 then
- previncrement = angle
- handles.Adornee.CFrame = handles.Adornee.CFrame * CFrame.new(direction * -(tonumber(increment) and tonumber(increment) or 1))
- RedrawSide(handles.Adornee.Parent)
- end
- end
- end)
- handlesbutton1down = handles.MouseButton1Down:connect(function()
- previncrement = nil;
- end)
- end
- end)
- Plugin.Deactivation:connect(function()
- DEB = false;
- Plugin:Activate(false);
- Button:SetActive(false)
- active = false
- -- cleanup
- previnvrement = nil
- handles.Adornee = nil
- pcall(function()
- keydown:disconnect()
- mousedrag:disconnect()
- button1down:disconnect()
- handlesbutton1down:disconnect()
- end)
- end)
- function TableFind(t, v)
- for i,k in pairs(t) do
- if k == v then
- return true
- end
- end
- end
- function DisconnectConnectors()
- for i,v in pairs(connectors) do
- if v:FindFirstChild("Sparkles") then
- v.Sparkles:Destroy()
- end
- end
- connectors = {}
- end
- function RedrawSide(side)
- local handles = GetHandles(side, "Side_1")
- local parts = GetSides(side, "Side_1")
- redraw(parts['P0'], parts['P1'], handles['c1'], handles['c2'], handles['c3']);
- if side.Parent:FindFirstChild("Side_2") then
- local handle4 = GetHandles(side, "Side_2")
- local parts = GetSides(side, "Side_2")
- redraw(parts['P0'], parts['P1'], handle4, handles['c3'], handles['c2']);
- end
- end
- function GetHandles(side, name)
- local plots = {}
- if name == "Side_1" then
- for i,v in pairs(side.Parent[name]:GetChildren()) do
- if v.Name:sub(1, preIdlen) == preId then
- plots['c' .. v.Name:sub(preIdlen+1,preIdlen+1)] = v.Position
- end
- end
- return plots
- else
- return side.Parent.Side_2[preId .. "1"].Position
- end
- end
- function GetSides(side, name)
- local plots = {}
- for i,v in pairs(side.Parent[name]:GetChildren()) do
- if v.Name:sub(1,1) == "P" then
- plots['P' .. v.Name:sub(2,2)] = v
- end
- end
- return plots
- end
- function plothandle(point, triangle, id)
- local part = Instance.new("Part", triangle)
- part.Name = preId .. id
- part.FormFactor = "Symmetric"
- part.Size = Vector3.new(1,1,1)
- part.Transparency = newtransparency == 1 and 0.65 or 1
- part.CanCollide = false
- part.CFrame = CFrame.new(point)
- part.BrickColor = BrickColor.new("Deep orange");
- table.insert(orangehandles, part)
- end
- --[[ * DrawTriangle:
- -- Created by Stravant
- -- Made to use WedgeParts by nccvoyager
- -- Scaling sizing, and physical attributes corrected by MrNicNac]]
- local ply = Instance.new("WedgePart")
- ply.formFactor = "Custom"
- ply.TopSurface = 0
- ply.BottomSurface = 0
- ply.Anchored = true
- ply.Size = Vector3.new(0.2,7,7)
- local msh = Instance.new("SpecialMesh")
- msh.MeshType = 2
- msh.Parent = ply
- function ParaD(a, b, c)
- local dot = (b-a).x*(c-a).x + (b-a).y*(c-a).y + (b-a).z*(c-a).z
- return dot / (a-b).magnitude
- end
- function PerpD(a, b, c)
- local par = ParaD(a, b, c)
- return math.sqrt((c-a).magnitude^2 - par^2)
- end
- local _P0, _P1 = nil, nil
- function draw(vec1, vec2, vec3, id)
- local A, B, C = nil, nil, nil
- local p0, p1 = ply:clone(), ply:clone()
- local rmodel = Instance.new("Model")
- rmodel.Name = "Side_" .. id
- _P0 = p0
- _P1 = p1
- local s1 = (vec1 - vec2).magnitude
- s2 = (vec2 - vec3).magnitude
- s3 = (vec3 - vec1).magnitude
- local smax = math.max(s1, s2, s3)
- if (vec1 - vec2).magnitude == smax then
- A = vec1
- B = vec2
- C = vec3
- elseif (vec2 - vec3).magnitude == smax then
- A = vec2
- B = vec3
- C = vec1
- elseif (vec3 - vec1).magnitude == smax then
- A = vec3
- B = vec1
- C = vec2
- end
- local perp = PerpD(A, B, C)
- local para = ParaD(A, B, C)
- local dif_para = (A-B).magnitude - para
- local ambig = false
- p0.Mesh.Scale = Vector3.new(0.1, 1,1)
- p0.Size = Vector3.new(.2, perp, para)
- p0.CFrame = CFrame.new(B, A)
- local Top_Look = (p0.CFrame * CFrame.Angles(math.pi/2, 0, 0)).lookVector
- local Mid_Point = A + CFrame.new(A, B).lookVector * para
- local Needed_Look = CFrame.new(Mid_Point, C).lookVector
- local dot = (Top_Look.x * Needed_Look.x) + (Top_Look.y * Needed_Look.y) + (Top_Look.z * Needed_Look.z)
- p0.CFrame = p0.CFrame * CFrame.Angles(0, 0, math.acos(dot))
- if ((p0.CFrame * CFrame.Angles(math.pi/2, 0, 0)).lookVector - Needed_Look).magnitude > 0.01 then
- p0.CFrame = p0.CFrame * CFrame.Angles(0, 0, -2*math.acos(dot))
- ambig = true
- end
- p0.CFrame = p0.CFrame * CFrame.new(0, perp/2, -(dif_para + para/2))
- p0.Parent = rmodel
- p0.Name = "P0"
- p1.Mesh.Scale = Vector3.new(0, 1,1)
- p1.Size = Vector3.new(.2, perp, dif_para)
- p1.CFrame = CFrame.new(B, A) * CFrame.Angles(0, 0, math.acos(dot)) * CFrame.Angles(0, math.pi, 0)
- if ((p1.CFrame * CFrame.Angles(math.pi/2, 0, 0)).lookVector - Needed_Look).magnitude > 0.01 then
- p1.CFrame = p1.CFrame * CFrame.Angles(0, 0, 2*math.acos(dot))
- ambig = true
- end
- p1.CFrame = p1.CFrame * CFrame.new(0, perp/2, dif_para/2)
- p1.Parent = rmodel
- p1.Name = "P1"
- table.insert(triangles, p0)
- table.insert(triangles, p1)
- --p1.BrickColor = BrickColor.Green()
- --p0.BrickColor = BrickColor.Green()
- return rmodel
- end
- ---------------------------------------------------------
- function redraw(p0, p1, vec1, vec2, vec3)
- local A, B, C = nil, nil, nil
- _P0 = p0
- _P1 = p1
- local s1 = (vec1 - vec2).magnitude
- s2 = (vec2 - vec3).magnitude
- s3 = (vec3 - vec1).magnitude
- local smax = math.max(s1, s2, s3)
- if (vec1 - vec2).magnitude == smax then
- A = vec1
- B = vec2
- C = vec3
- elseif (vec2 - vec3).magnitude == smax then
- A = vec2
- B = vec3
- C = vec1
- elseif (vec3 - vec1).magnitude == smax then
- A = vec3
- B = vec1
- C = vec2
- end
- local perp = PerpD(A, B, C)
- local para = ParaD(A, B, C)
- local dif_para = (A-B).magnitude - para
- local ambig = false
- --print(perp, para);
- p0.Mesh.Scale = Vector3.new(0.1, 1,1)
- p0.Size = Vector3.new(.2, perp, para)
- p0.CFrame = CFrame.new(B, A)
- local Top_Look = (p0.CFrame * CFrame.Angles(math.pi/2, 0, 0)).lookVector
- local Mid_Point = A + CFrame.new(A, B).lookVector * para
- local Needed_Look = CFrame.new(Mid_Point, C).lookVector
- local dot = (Top_Look.x * Needed_Look.x) + (Top_Look.y * Needed_Look.y) + (Top_Look.z * Needed_Look.z)
- p0.CFrame = p0.CFrame * CFrame.Angles(0, 0, math.acos(dot))
- if ((p0.CFrame * CFrame.Angles(math.pi/2, 0, 0)).lookVector - Needed_Look).magnitude > 0.01 then
- p0.CFrame = p0.CFrame * CFrame.Angles(0, 0, -2*math.acos(dot))
- ambig = true
- end
- p0.CFrame = p0.CFrame * CFrame.new(0, perp/2, -(dif_para + para/2))
- p1.Mesh.Scale = Vector3.new(0, 1,1)
- p1.Size = Vector3.new(.2, perp, dif_para)
- p1.CFrame = CFrame.new(B, A) * CFrame.Angles(0, 0, math.acos(dot)) * CFrame.Angles(0, math.pi, 0)
- if ((p1.CFrame * CFrame.Angles(math.pi/2, 0, 0)).lookVector - Needed_Look).magnitude > 0.01 then
- p1.CFrame = p1.CFrame * CFrame.Angles(0, 0, 2*math.acos(dot))
- ambig = true
- end
- p1.CFrame = p1.CFrame * CFrame.new(0, perp/2, dif_para/2)
- --p1.BrickColor = BrickColor.Green()
- --p0.BrickColor = BrickColor.Green()
- return rmodel
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement