Quick actions

cmd+k|ctrl+k

Navigation

Languages

Piano10

Snippet info

Language

Lua

Visibility

public

Author

playvoider

Created

2020-06-26T19:05:59Z

Updated

2020-06-26T19:05:59Z

--[[	Piano Script by Mokiros
		Original by NickPatella
		Model and GUI converted with the help of my plugin:
		https://www.roblox.com/library/1961888973/MtS
]]
local Part_Classes = {"Part","WedgePart","CornerWedgePart"}
local Part_Shapes = {"Brick","Cylinder","Sphere","Torso","Wedge"}
function DecodeUnion(t)
	local r = function()return table.remove(t,1) end
	local split = function(str,sep)
       local fields = {}
       str:gsub(("([^%s]+)"):format(sep or ','),function(c)fields[#fields+1]=c end)
       return fields
	end
	local m = Instance.new("Folder")
	m.Name = "UnionCache ["..tostring(math.random(1,9999)).."]"
	m.Archivable = false
	m.Parent = game:GetService("ServerStorage")
	local Union,Subtract = {},{}
	repeat
		local isNegate = false
		local class = r()
		if class=='-' then
			isNegate = true
			class = r()
		end
		if class=='n' then
			local d = {}
			local a = r()
			repeat
				table.insert(d,a)
				a = r()
			until a=='p'
			local u = DecodeUnion(d)
			if u then
				table.insert(isNegate and Subtract or Union,u)
			end
		else
			local size,pos,rot = Vector3.new(unpack(split(r()))),Vector3.new(unpack(split(r()))),Vector3.new(unpack(split(r())))
			local part = Instance.new(Part_Classes[tonumber(class)])
			part.Size = size
			part.Position = pos
			part.Orientation = rot
			if r()=="+" then
				local m,ms,of = r(),Vector3.new(unpack(split(r()))),Vector3.new(unpack(split(r())))
				if tonumber(m)==6 then
					part.Shape = Enum.PartType.Cylinder
				elseif tonumber(m)==7 then
					part.Shape = Enum.PartType.Ball
				else
					local mesh = Instance.new(tonumber(m)==8 and "CylinderMesh" or "SpecialMesh")
					if tonumber(m)~=8 then
						mesh.MeshType = Enum.MeshType[Part_Shapes[tonumber(m)]]
					end
					mesh.Scale = ms
					mesh.Offset = of
					mesh.Parent = part
				end
			end
			table.insert(isNegate and Subtract or Union,part)
		end
	until #t<=0
	local first = Union[1]
	first.Parent = m
	if #Union>1 then
		first = first:UnionAsync(Union)
		first.Parent = m
	end
	if #Subtract>0 then
		first = first:SubtractAsync(Subtract)
		first.Parent = m
	end
	first.Parent = nil
	m:Destroy()
	return first
end
function Decode(str,t,props,classes,values,ICList,Model,CurPar,LastIns,split,RemoveAndSplit,InstanceList)
    local tonum,table_remove,inst,parnt,comma,table_foreach = tonumber,table.remove,Instance.new,"Parent",",",
	function(t,f)
		for a,b in pairs(t) do
			f(a,b)
		end
	end
	local Types = {
		Color3 = Color3.new,
		Vector3 = Vector3.new,
		Vector2 = Vector2.new,
		UDim = UDim.new,
		UDim2 = UDim2.new,
		CFrame = CFrame.new,
		Rect = Rect.new,
		NumberRange = NumberRange.new,
		BrickColor = BrickColor.new,
		PhysicalProperties = PhysicalProperties.new,
		NumberSequence = function(...)
			local a = {...}
			local t = {}
			repeat
				t[#t+1] = NumberSequenceKeypoint.new(table_remove(a,1),table_remove(a,1),table_remove(a,1))
			until #a==0
			return NumberSequence.new(t)
		end,
		ColorSequence = function(...)
			local a = {...}
			local t = {}
			repeat
				t[#t+1] = ColorSequenceKeypoint.new(table_remove(a,1),Color3.new(table_remove(a,1),table_remove(a,1),table_remove(a,1)))
			until #a==0
			return ColorSequence.new(t)
		end,
		number = tonumber,
		boolean = function(a)
			return a=="1"
		end
	}
    split = function(str,sep)
		if not str then return end
		local fields = {}
		local ConcatNext = false
		str:gsub(("([^%s]+)"):format(sep),function(c)
			if ConcatNext == true then
				fields[#fields] = fields[#fields]..sep..c
				ConcatNext = false
			else
				fields[#fields+1] = c
			end
			if c:sub(#c)=="\\" then
				c = fields[#fields]
				fields[#fields] = c:sub(1,#c-1)
				ConcatNext = true
			end
		end)
		return fields
    end
 	RemoveAndSplit = function(t)
		return split(table_remove(t,1),comma)
	end
    t = split(str,";")
    props = RemoveAndSplit(t)
    classes = RemoveAndSplit(t)
	values = split(table_remove(t,1),'|')
	ICList = RemoveAndSplit(t)
	InstanceList = {}
    Model = inst"Model"
    CurPar = Model
    table_foreach(t,function(ct,c)
        if c=="n" or c=="p" then
            CurPar = c=="n" and LastIns or CurPar[parnt]
        else
            ct = split(c,"|")
			local class = classes[tonum(table_remove(ct,1))]
			if class=="UnionOperation" then
				LastIns = {UsePartColor="1"}
			else
            	LastIns = inst(class)
				if LastIns:IsA"Script" then
					s(LastIns)
				elseif LastIns:IsA("ModuleScript") then
					ms(LastIns)
	            end
			end
			
			local function SetProperty(LastIns,p,str,s)
				s = Types[typeof(LastIns[p])]
				if p=="CustomPhysicalProperties" then
					s = PhysicalProperties.new
				end
				if s then
					LastIns[p] = s(unpack(split(str,comma)))
				else
					LastIns[p] = str
				end
			end
 			
			local UnionData
            table_foreach(ct,function(s,p,a,str)
                a = p:find":"
                p,str = props[tonum(p:sub(1,a-1))],values[tonum(p:sub(a+1))]
				if p=="UnionData" then
					UnionData = split(str," ")
					return
				end
				if class=="UnionOperation" then
					LastIns[p] = str
					return
				end
				SetProperty(LastIns,p,str)
            end)

			if UnionData then
				local LI_Data = LastIns
				LastIns = DecodeUnion(UnionData)
				table_foreach(LI_Data,function(p,str)
					SetProperty(LastIns,p,str)
				end)
			end
			table.insert(InstanceList,LastIns)
            LastIns[parnt] = CurPar
        end
    end)
	table_remove(ICList,1)
	table_foreach(ICList,function(a,b)
		b = split(b,">")
		InstanceList[tonum(b[1])][props[tonum(b[2])]] = InstanceList[tonum(b[3])]
	end)
 
    return Model:GetChildren()
end
local Keyboard = Decode('Name,Anchored,Color,Material,Position,Orientation,Size,Scale,CanCollide,BottomSurface,TopSurface,Offset,Transparency,UnionData,Face,CanvasSize,Adornee,BackgroundColor3,Font,Text,TextColor3,TextScaled,'
..'TextSize,TextWrapped,Value;Part,Model,CylinderMesh,BlockMesh,UnionOperation,SurfaceGui,TextLabel,CFrameValue,BoolValue,Seat;Part|Keyboard|Stand|1|0.0666,0.0666,0.0666|272|0.6651,0.1,-6.3315|-90,0,0|0.'
..'2,0.2,0.2|1.2,1,1.2|0.6651,0.1,-7.6315|0.2,2.4,0.2|0.6651,0.1,-8.9315|-1.8348,1.5,-7.7314|-29.25,-90,90|0.2,0.2,5.73|-1.8348,1.5,-7.5315|-29.25,90,-90|-4.3348,0.1,-8.9315|-4.3348,0.1,-7.6315|-4.3348,0'
..'.1,-6.3315|0.6651,2.9,-6.3315|-4.3348,2.9,-8.9315|0.6651,2.9,-8.9315|-4.3348,2.9,-6.3315|-4.3348,2.9,-7.6315|0.6651,2.9,-7.6315|Keys|12|0.949,0.9529,0.9529|-4.1349,3.3,-7.0315|0.2,0.2,1.2|0|0|11|-4.23'
..'48,3.5,-7.2315|0.2,0.2,0.8|0.0199,-0.1001,0|0.6,1,1|10|-4.3348,3.3,-7.0315|9|-4.4349,3.5,-7.2315|0,-0.1001,0|8|-4.5349,3.3,-7.0315|7|-4.6348,3.5,-7.2315|-0.02,-0.1001,0|6|-4.7348,3.3,-7.0315|5|-4.9349'
..',3.3,-7.0315|4|-5.0349,3.5,-7.2315|3|-5.1349,3.3,-7.0315|2|-5.2348,3.5,-7.2315|-5.3348,3.3,-7.0315|-2.7348,3.3,-7.0315|-2.8349,3.5,-7.2315|-2.9349,3.3,-7.0315|-3.0348,3.5,-7.2315|-3.1348,3.3,-7.0315|-'
..'3.2348,3.5,-7.2315|-3.3348,3.3,-7.0315|-3.5348,3.3,-7.0315|-3.6349,3.5,-7.2315|-3.7348,3.3,-7.0315|-3.8348,3.5,-7.2315|-3.9349,3.3,-7.0315|-1.3348,3.3,-7.0315|-1.4349,3.5,-7.2315|-1.5349,3.3,-7.0315|-'
..'1.6349,3.5,-7.2315|-1.7349,3.3,-7.0315|-1.8348,3.5,-7.2315|-1.9349,3.3,-7.0315|-2.1349,3.3,-7.0315|-2.2348,3.5,-7.2315|-2.3349,3.3,-7.0315|-2.4349,3.5,-7.2315|-2.5349,3.3,-7.0315|0.0651,3.3,-7.0315|-0'
..'.0349,3.5,-7.2315|-0.1349,3.3,-7.0315|-0.2349,3.5,-7.2315|-0.3349,3.3,-7.0315|-0.4349,3.5,-7.2315|-0.5349,3.3,-7.0315|-0.7349,3.3,-7.0315|-0.8349,3.5,-7.2315|-0.9349,3.3,-7.0315|-1.0349,3.5,-7.2315|-1'
..'.1348,3.3,-7.0315|1.4652,3.3,-7.0315|1.3652,3.5,-7.2315|1.2651,3.3,-7.0315|1.1652,3.5,-7.2315|1.0652,3.3,-7.0315|0.9652,3.5,-7.2315|0.8652,3.3,-7.0315|0.6651,3.3,-7.0315|0.5651,3.5,-7.2315|0.4651,3.3,'
..'-7.0315|0.3651,3.5,-7.2315|0.2651,3.3,-7.0315|1.6652,3.3,-7.0315|KeyBound|-1.8352,3.4,-7.0316|7.1999,0.4,1.2|Case|Base|1 7.1999,0.3999,1.3999 -1.8348,3.3999,-8.3315 0,0,0 = n 1 0.1999,0.1999,0.3999 1.'
..'8652,3.2999,-6.4315 0,180,0 + 5 1,1,1 0,0,0 1 0.1999,0.1999,2.3999 1.8652,3.2999,-7.8315 0,0,0 = 1 0.1999,0.1999,0.7999 1.8652,3.4999,-7.0315 0,180,0 + 5 1,1,1 0,0,0 1 0.1999,0.1999,1.5999 1.8652,3.49'
..'99,-8.2315 0,0,0 = p n 1 0.1999,0.1999,0.3999 -5.5348,3.2999,-6.4315 0,180,0 + 5 1,1,1 0,0,0 1 0.1999,0.1999,2.3999 -5.5348,3.2999,-7.8315 0,0,0 = 1 0.1999,0.1999,0.7999 -5.5348,3.4999,-7.0315 0,180,0'
..' + 5 1,1,1 0,0,0 1 0.1999,0.1999,1.5999 -5.5348,3.4999,-8.2315 0,0,0 = p 1 7.5999,0.1999,2.7999 -1.8348,3.0999,-7.6315 0,0,0 = 1 7.1999,0.1999,0.1999 -1.8348,3.2999,-6.3315 0,180,0 + 5 1,0.5,1 0,-0.05'
..'01,0|Panel|1 2,0.2,0.2 -1.8348,3.8286,-8.7087 -9.4301,180,0 + 1 1,0.5,0.5 0,-0.0501,-0.0501 1 2,0.2,0.2 -1.8348,3.6647,-7.7222 -9.4301,180,0 + 1 1,0.5,0.5 0,-0.0501,0.05 1 0.2,0.2,1 -0.7348,3.7466,-8.'
..'2154 -9.4301,180,0 + 1 0.5,0.5,1 0.05,-0.0501,0 1 0.2,0.2,1 -2.9348,3.7467,-8.2154 -9.4301,180,0 + 1 0.5,0.5,1 -0.0501,-0.0501,0|Top|1 7.5999,0.1999,1.2 -1.8348,3.7,-8.2315 0,180,0 + 5 1,1,1 0,0,0 1 0'
..'.1999,0.1999,1.4 1.8652,3.7,-8.1315 0,180,0 + 5 1,1,1 0,0,0 n - 1 7.5999,0.1999,0.1999 -1.8348,3.7,-8.7315 0,180,0 = - 1 7.5999,0.1999,0.4 -1.8348,3.5,-8.8315 0,180,0 = 1 0.3999,7.5999,0.3999 -1.8348,'
..'3.6,-8.8315 90,-90,0 + 8 1,1,1 0,0,0 p 1 0.1999,0.1999,1.4 -5.5348,3.7,-8.1315 0,180,0 + 5 1,1,1 0,0,0|SpeakerR|0.5651,3.7188,-8.2201|-9.4301,180,0|2,0.2,1|0,-0.0501,0|1,0.5,1|SpeakerL|-4.2348,3.7188,'
..'-8.2201|Display|0.6431,0.7411,0.2784|-1.8348,3.626,-8.2355|0,-90,-9.4301|0.7999,0.2,2|GUI|1|200,80|0,200,0,80|0.7529,1,0.2901|5|Converted to script by Mokiros|0.0509,0.1058,0|48|BoundingBox|-1.8348,1.9,-7.6315|7.5999,3'
..'.7999,2.7999|offset|0,1.6,1,1,0,0,0,1,0,0,0,1|sit|Bench|Mask|2|1 0.2,1.6,0.2 -3.4348,0.8,-3.7315 0,0,0 = 1 3,0.2,0.2 -1.8348,0.7,-4.4315 0,0,0 = 1 0.2,0.2,1.2 -0.2348,0.7,-4.4315 0,0,0 = 1 0.2,1.6,0.2'
..' -0.2348,0.8,-3.7315 0,0,0 = 1 0.2,0.2,1.2 -3.4348,0.7,-4.4315 0,0,0 = 1 0.2,1.6,0.2 -0.2348,0.8,-5.1315 0,0,0 = n - 1 2.9999,0.2999,1.1999 -1.8348,1.75,-4.4315 0,0,0 = 1 3.3999,0.2999,1.5999 -1.8348,'
..'1.75,-4.4315 0,0,0 = p 1 3.5,0.2,1.7 -1.8348,1.9,-4.4315 0,0,0 = 1 0.2,1.6,0.2 -3.4348,0.8,-5.1315 0,0,0 =|0.1058,0.1647,0.2078|-1.8348,1,-4.4315|3.3999,2,1.6;0,170>17>168;2|1:2;n;2|1:3;n;1|2:4|3:5|4:'
..'6|5:7|6:8|7:9|3:5|3:5;n;3|8:10;p;1|2:4|3:5|5:11|6:8|7:12|3:5|3:5;n;3;p;1|2:4|3:5|4:6|5:13|6:8|7:9|3:5|3:5;n;3|8:10;p;1|2:4|3:5|5:14|6:15|7:16|3:5|3:5;1|2:4|3:5|5:17|6:18|7:16|3:5|3:5;1|2:4|3:5|4:6|5:1'
..'9|6:8|7:9|3:5|3:5;n;3|8:10;p;1|2:4|3:5|5:20|6:8|7:12|3:5|3:5;n;3;p;1|2:4|3:5|4:6|5:21|6:8|7:9|3:5|3:5;n;3|8:10;p;1|2:4|3:5|4:6|5:22|6:8|7:9|3:5|3:5;n;3|8:10;p;1|2:4|3:5|4:6|5:23|6:8|7:9|3:5|3:5;n;3|8:'
..'10;p;1|2:4|3:5|4:6|5:24|6:8|7:9|3:5|3:5;n;3|8:10;p;1|2:4|3:5|4:6|5:25|6:8|7:9|3:5|3:5;n;3|8:10;p;1|2:4|3:5|5:26|6:8|7:12|3:5|3:5;n;3;p;1|2:4|3:5|5:27|6:8|7:12|3:5|3:5;n;3;p;p;2|1:28;n;2|1:4;n;1|1:29|2'
..':4|3:30|4:6|5:31|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:35|2:4|3:5|4:6|5:36|7:37|9:33|10:34|11:34|3:5|3:5;n;4|12:38|8:39;p;1|1:40|2:4|3:30|4:6|5:41|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:42|2:4|'
..'3:5|4:6|5:43|7:37|9:33|10:34|11:34|3:5|3:5;n;4|12:44|8:39;p;1|1:45|2:4|3:30|4:6|5:46|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:47|2:4|3:5|4:6|5:48|7:37|9:33|10:34|11:34|3:5|3:5;n;4|12:49|8:39;p;1|1:50'
..'|2:4|3:30|4:6|5:51|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:52|2:4|3:30|4:6|5:53|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:54|2:4|3:5|4:6|5:55|7:37|9:33|10:34|11:34|3:5|3:5;n;4|12:38|8:39;p;1|1:56|2:'
..'4|3:30|4:6|5:57|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:58|2:4|3:5|4:6|5:59|7:37|9:33|10:34|11:34|3:5|3:5;n;4|12:49|8:39;p;1|1:4|2:4|3:30|4:6|5:60|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;p;2|1:58;n;1|'
..'1:29|2:4|3:30|4:6|5:61|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:35|2:4|3:5|4:6|5:62|7:37|9:33|10:34|11:34|3:5|3:5;n;4|12:38|8:39;p;1|1:40|2:4|3:30|4:6|5:63|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:4'
..'2|2:4|3:5|4:6|5:64|7:37|9:33|10:34|11:34|3:5|3:5;n;4|12:44|8:39;p;1|1:45|2:4|3:30|4:6|5:65|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:47|2:4|3:5|4:6|5:66|7:37|9:33|10:34|11:34|3:5|3:5;n;4|12:49|8:39;p;'
..'1|1:50|2:4|3:30|4:6|5:67|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:52|2:4|3:30|4:6|5:68|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:54|2:4|3:5|4:6|5:69|7:37|9:33|10:34|11:34|3:5|3:5;n;4|12:38|8:39;p;1|1'
..':56|2:4|3:30|4:6|5:70|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:58|2:4|3:5|4:6|5:71|7:37|9:33|10:34|11:34|3:5|3:5;n;4|12:49|8:39;p;1|1:4|2:4|3:30|4:6|5:72|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;p;2|1:5'
..'6;n;1|1:29|2:4|3:30|4:6|5:73|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:35|2:4|3:5|4:6|5:74|7:37|9:33|10:34|11:34|3:5|3:5;n;4|12:38|8:39;p;1|1:40|2:4|3:30|4:6|5:75|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p'
..';1|1:42|2:4|3:5|4:6|5:76|7:37|9:33|10:34|11:34|3:5|3:5;n;4|12:44|8:39;p;1|1:45|2:4|3:30|4:6|5:77|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:47|2:4|3:5|4:6|5:78|7:37|9:33|10:34|11:34|3:5|3:5;n;4|12:49|8'
..':39;p;1|1:50|2:4|3:30|4:6|5:79|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:52|2:4|3:30|4:6|5:80|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:54|2:4|3:5|4:6|5:81|7:37|9:33|10:34|11:34|3:5|3:5;n;4|12:38|8:39'
..';p;1|1:56|2:4|3:30|4:6|5:82|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:58|2:4|3:5|4:6|5:83|7:37|9:33|10:34|11:34|3:5|3:5;n;4|12:49|8:39;p;1|1:4|2:4|3:30|4:6|5:84|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;p'
..';2|1:54;n;1|1:29|2:4|3:30|4:6|5:85|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:35|2:4|3:5|4:6|5:86|7:37|9:33|10:34|11:34|3:5|3:5;n;4|12:38|8:39;p;1|1:40|2:4|3:30|4:6|5:87|7:32|9:33|10:34|11:34|3:30|3:30'
..';n;4;p;1|1:42|2:4|3:5|4:6|5:88|7:37|9:33|10:34|11:34|3:5|3:5;n;4|12:44|8:39;p;1|1:45|2:4|3:30|4:6|5:89|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:47|2:4|3:5|4:6|5:90|7:37|9:33|10:34|11:34|3:5|3:5;n;4|1'
..'2:49|8:39;p;1|1:50|2:4|3:30|4:6|5:91|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:52|2:4|3:30|4:6|5:92|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:54|2:4|3:5|4:6|5:93|7:37|9:33|10:34|11:34|3:5|3:5;n;4|12:3'
..'8|8:39;p;1|1:56|2:4|3:30|4:6|5:94|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:58|2:4|3:5|4:6|5:95|7:37|9:33|10:34|11:34|3:5|3:5;n;4|12:49|8:39;p;1|1:4|2:4|3:30|4:6|5:96|7:32|9:33|10:34|11:34|3:30|3:30;n'
..';4;p;p;2|1:52;n;1|1:29|2:4|3:30|4:6|5:97|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:35|2:4|3:5|4:6|5:98|7:37|9:33|10:34|11:34|3:5|3:5;n;4|12:38|8:39;p;1|1:40|2:4|3:30|4:6|5:99|7:32|9:33|10:34|11:34|3:3'
..'0|3:30;n;4;p;1|1:42|2:4|3:5|4:6|5:100|7:37|9:33|10:34|11:34|3:5|3:5;n;4|12:44|8:39;p;1|1:45|2:4|3:30|4:6|5:101|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:47|2:4|3:5|4:6|5:102|7:37|9:33|10:34|11:34|3:5|'
..'3:5;n;4|12:49|8:39;p;1|1:50|2:4|3:30|4:6|5:103|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:52|2:4|3:30|4:6|5:104|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:54|2:4|3:5|4:6|5:105|7:37|9:33|10:34|11:34|3:5|'
..'3:5;n;4|12:38|8:39;p;1|1:56|2:4|3:30|4:6|5:106|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;1|1:58|2:4|3:5|4:6|5:107|7:37|9:33|10:34|11:34|3:5|3:5;n;4|12:49|8:39;p;1|1:4|2:4|3:30|4:6|5:108|7:32|9:33|10:34|11'
..':34|3:30|3:30;n;4;p;p;2|1:50;n;1|1:4|2:4|3:30|4:6|5:109|7:32|9:33|10:34|11:34|3:30|3:30;n;4;p;p;1|1:110|2:4|3:30|4:6|13:4|5:111|7:112|9:33|10:34|11:34|3:30|3:30;n;4;p;p;2|1:113;n;5|1:114|2:4|3:5|3:5|3'
..':5|14:115;5|1:116|2:4|3:5|4:6|3:5|3:5|14:117;5|1:118|2:4|3:5|3:5|3:5|14:119;1|1:120|2:4|3:5|4:6|5:121|6:122|7:123|3:5|3:5;n;4|12:124|8:125;p;1|1:126|2:4|3:5|4:6|5:127|6:122|7:123|3:5|3:5;n;4|12:124|8:'
..'125;p;1|1:128|2:4|3:129|5:130|6:131|7:132|3:129|3:129;n;4;6|1:133|15:134|16:135;n;7|7:136|18:137|19:138|20:139|21:140|22:4|23:141|24:4;p;p;p;1|1:142|2:4|13:4|5:143|7:144;n;8|1:145|25:146;9|1:147;p;2|1'
..':148;n;5|1:149|2:4|3:5|9:33|10:150|3:5|3:5|14:151;10|2:4|3:152|13:4|5:153|7:154|10:150|11:34|3:152|3:152;p;p;')[1]
Keyboard.Parent = script
Keyboard.PrimaryPart = Keyboard.BoundingBox
if owner.Character and owner.Character.PrimaryPart then
	local p = owner.Character.PrimaryPart.Position
	Keyboard:SetPrimaryPartCFrame(CFrame.new(p.X,p.Y-1,p.Z-5))
end

----------------------------------
----------------------------------
----------------------------------
---------PIANO CONNECTION---------
----------------------------------
----------------------------------
----------------------------------

----------------------------------
------------VARIABLES-------------
----------------------------------

User = nil
Gui = nil

Bound = Keyboard.Keys.KeyBound

Connector = Instance.new("RemoteEvent")
Connector.Name = "Connector"
Connector.Parent = script

----------------------------------
------------FUNCTIONS-------------
----------------------------------

local LS_Source

SoundFolder = Keyboard.BoundingBox
SoundList = {"233836579", "233844049", "233845680", "233852841", "233854135", "233856105", "233856105"}
ExistingSounds = {}

local SoundCache = {}
local CacheFolder = Instance.new("Folder")
function GetSound()
	local snd = table.remove(SoundCache)
	if not snd then
		return Instance.new("Sound")
	elseif snd.Parent~=CacheFolder then
		return GetSound()
	else
		return snd
	end
end
function CacheSound(snd)
	if not snd.Parent then return end
	snd:Stop()
	snd.Parent = CacheFolder
	table.insert(SoundCache,snd)
end

function PlayNoteSound(note1)
	local note2 = (note1 - 1)%12 + 1	-- Which note? (1-12)
	local octave = math.ceil(note1/12) -- Which octave?
	local sound = math.ceil(note2/2) -- Which audio?
	local offset = 16 * (octave - 1) + 8 * (1 - note2%2) -- How far in audio?
	local audio = GetSound() -- Create the audio
	audio.Parent = SoundFolder
	audio.MaxDistance = 60
	audio.Volume = 10
	audio.SoundId = "rbxassetid://"..SoundList[sound] -- Give its sound
	audio.TimePosition = offset + (octave - .9)/15 -- set the time position
	audio:Play() -- Play the audio
	
	table.insert(ExistingSounds, 1, audio)
	if #ExistingSounds >= 10 then
		ExistingSounds[10]:Stop() -- limit the number of playing sounds!
		ExistingSounds[10] = nil
	end
	
	delay(4, function() audio:Stop() CacheSound(audio) end ) -- remove the audio in 4 seconds, enough time for it to play
end

function Receive(player, action, a, b)
	if player == User and action == "play" then
		HighlightPianoKey(a)
		PlayNoteSound(a)
	elseif player == User and action == "abort" then
		Deactivate()
		if SeatWeld then
			SeatWeld:Destroy()
		end
	end
end
function Activate(player)
	Gui = Instance.new("ScreenGui")
	Gui.Name = "PianoGui"
	Gui.Parent = player.PlayerGui
	local pr = Instance.new("ObjectValue")
	pr.Name = "Piano"
	pr.Value = script
	pr.Parent = Gui
	local ls = NLS(LS_Source,Gui)
	User = player
end
function Deactivate()
	if Gui then
		Gui:Destroy()
	end
	User = nil
end

----------------------------------
-----------CONNECTIONS------------
----------------------------------

Connector.OnServerEvent:connect(Receive)

----------------------------------
----------------------------------
----------------------------------
----------SEAT MECHANISM----------
----------------------------------
----------------------------------
----------------------------------

----------------------------------
------------VARIABLES-------------
----------------------------------

Seat = Keyboard.Bench.Seat
SeatWeld = nil


----------------------------------
------------FUNCTIONS-------------
----------------------------------

function WeldChanged(property)
	if property == "Parent" and SeatWeld.Parent == nil then
		SeatWeld = nil
		Deactivate()
		BreakSeatConnections()
	end
end
function ChildAdded(child)
	if child:IsA("Weld") then
		local root = child.Part1
		local character = root.Parent
		local player = game:GetService("Players"):GetPlayerFromCharacter(character)
		if player then
			SeatWeld = child
			Activate(player)
			MakeSeatConnections()
		end
	end
end

----------------------------------
-----------CONNECTIONS------------
----------------------------------

SeatWeldConnection = nil

function MakeSeatConnections()
	SeatWeldConnection = SeatWeld.Changed:connect(WeldChanged)
end
function BreakSeatConnections()
	SeatWeldConnection:disconnect()
end

Seat.ChildAdded:connect(ChildAdded)

----------------------------------
----------------------------------
----------------------------------
------------AESTHETICS------------
----------------------------------
----------------------------------
----------------------------------

----------------------------------
------------VARIABLES-------------
----------------------------------

Keys = Keyboard.Keys

----------------------------------
------------FUNCTIONS-------------
----------------------------------

function IsBlack(note)
	if note%12 == 2 or note%12 == 4 or note%12 == 7 or note%12 == 9 or note%12 == 11 then
		return true
	end
end

function HighlightPianoKey(note1)
	--print("highlight!")
	local octave = math.ceil(note1/12)
	local note2 = (note1 - 1)%12 + 1
	local key = Keys:FindFirstChild(tostring(octave)):FindFirstChild(tostring(note2))
	if IsBlack(note1) then
		key.Mesh.Offset = Vector3.new(0.02, -0.15, 0)
	else
		key.Mesh.Offset = Vector3.new(0, -.05, 0)
	end
	delay(.5, function() RestorePianoKey(note1) end)
end
function RestorePianoKey(note1)
	local octave = math.ceil(note1/12)
	local note2 = (note1 - 1)%12 + 1
	local key = Keys:FindFirstChild(tostring(octave)):FindFirstChild(tostring(note2))
	if IsBlack(note1) then
		key.Mesh.Offset = Vector3.new(0.02, -0.1, 0)
	else
		key.Mesh.Offset = Vector3.new(0, 0, 0)
	end
end

LS_Source = [====[
if script.Parent.Parent ~= owner.PlayerGui then return script:Destroy() end
function Decode(str,t,props,classes,values,ICList,Model,CurPar,LastIns,split,RemoveAndSplit,InstanceList)
    local tonum,table_remove,inst,parnt,comma,table_foreach = tonumber,table.remove,Instance.new,"Parent",",",
	function(t,f)
		for a,b in pairs(t) do
			f(a,b)
		end
	end
	local Types = {
		Color3 = Color3.new,
		Vector3 = Vector3.new,
		Vector2 = Vector2.new,
		UDim = UDim.new,
		UDim2 = UDim2.new,
		CFrame = CFrame.new,
		Rect = Rect.new,
		NumberRange = NumberRange.new,
		BrickColor = BrickColor.new,
		PhysicalProperties = PhysicalProperties.new,
		NumberSequence = function(...)
			local a = {...}
			local t = {}
			repeat
				t[#t+1] = NumberSequenceKeypoint.new(table_remove(a,1),table_remove(a,1),table_remove(a,1))
			until #a==0
			return NumberSequence.new(t)
		end,
		ColorSequence = function(...)
			local a = {...}
			local t = {}
			repeat
				t[#t+1] = ColorSequenceKeypoint.new(table_remove(a,1),Color3.new(table_remove(a,1),table_remove(a,1),table_remove(a,1)))
			until #a==0
			return ColorSequence.new(t)
		end,
		number = tonumber,
		boolean = function(a)
			return a=="1"
		end
	}
    split = function(str,sep)
		if not str then return end
		local fields = {}
		local ConcatNext = false
		str:gsub(("([^%s]+)"):format(sep),function(c)
			if ConcatNext == true then
				fields[#fields] = fields[#fields]..sep..c
				ConcatNext = false
			else
				fields[#fields+1] = c
			end
			if c:sub(#c)=="\\" then
				c = fields[#fields]
				fields[#fields] = c:sub(1,#c-1)
				ConcatNext = true
			end
		end)
		return fields
    end
 	RemoveAndSplit = function(t)
		return split(table_remove(t,1),comma)
	end
    t = split(str,";")
    props = RemoveAndSplit(t)
    classes = RemoveAndSplit(t)
	values = split(table_remove(t,1),'|')
	ICList = RemoveAndSplit(t)
	InstanceList = {}
    Model = inst"Model"
    CurPar = Model
    table_foreach(t,function(ct,c)
        if c=="n" or c=="p" then
            CurPar = c=="n" and LastIns or CurPar[parnt]
        else
            ct = split(c,"|")
			local class = classes[tonum(table_remove(ct,1))]
			if class=="UnionOperation" then
				LastIns = {UsePartColor="1"}
			else
            	LastIns = inst(class)
				if LastIns:IsA"Script" then
					s(LastIns)
				elseif LastIns:IsA("ModuleScript") then
					ms(LastIns)
	            end
			end
			
			local function SetProperty(LastIns,p,str,s)
				s = Types[typeof(LastIns[p])]
				if p=="CustomPhysicalProperties" then
					s = PhysicalProperties.new
				end
				if s then
					LastIns[p] = s(unpack(split(str,comma)))
				else
					LastIns[p] = str
				end
			end
 			
			local UnionData
            table_foreach(ct,function(s,p,a,str)
                a = p:find":"
                p,str = props[tonum(p:sub(1,a-1))],values[tonum(p:sub(a+1))]
				if p=="UnionData" then
					UnionData = split(str," ")
					return
				end
				if class=="UnionOperation" then
					LastIns[p] = str
					return
				end
				SetProperty(LastIns,p,str)
            end)

			if UnionData then
				local LI_Data = LastIns
				LastIns = DecodeUnion(UnionData)
				table_foreach(LI_Data,function(p,str)
					SetProperty(LastIns,p,str)
				end)
			end
			table.insert(InstanceList,LastIns)
            LastIns[parnt] = CurPar
        end
    end)
	table_remove(ICList,1)
	table_foreach(ICList,function(a,b)
		b = split(b,">")
		InstanceList[tonum(b[1])][props[tonum(b[2])]] = InstanceList[tonum(b[3])]
	end)
 
    return Model:GetChildren()
end
local Objects = Decode('Name,Position,Size,BackgroundColor3,BorderColor3,ClipsDescendants,Font,Text,TextColor3,TextSize,BackgroundTransparency,ZIndex,BorderSizePixel,CanvasSize,BottomImage,TopImage,MidImage,TextWrapped,TextX'
..'Alignment,TextYAlignment;Part,Frame,TextButton,TextLabel,ScrollingFrame,TextBox;Part|PianoGui|0.5,-380,1,0|0,760,0,210|0.2039,0.2039,0.2039|0.1176,0.1176,0.1176|1|ExitButton|0,20,0,160|0,350,0,30|1,0.'
..'3058,0.3058|1,0.0784,0.0784|4|Exit (Backspace)|1,1,1|24|Keys|0,20,0,20|0,720,0,120|0,0,0|0,20,1,0|0.5019,0.5019,0.5019|3| |14|Label|0.5,0,0.85,0|18|2|0,12,0,0|0,12,0,80|!|3|0,20,0,0|5|0,40,0,0|6|0,60,'
..'0,0|4|8|0,80,0,0|10|0,100,0,0|12|0,120,0,0|7|0,35,0,0|@|0,72,0,0|$|11|0,115,0,0|^|9|0,93,0,0|0,13,0,80|%|13|0,140,0,0|25|0,280,0,0|t|37|0,420,0,0|s|49|0,560,0,0|l|0,152,0,0|*|26|0,292,0,0|T|38|0,432,0'
..',0|S|50|0,572,0,0|L|15|0,160,0,0|27|0,300,0,0|y|39|0,440,0,0|d|51|0,580,0,0|z|17|0,180,0,0|0|29|0,320,0,0|u|41|0,460,0,0|f|53|0,600,0,0|x|0,200,0,0|q|30|0,340,0,0|i|42|0,480,0,0|g|54|0,620,0,0|c|20|0,'
..'220,0,0|w|32|0,360,0,0|o|44|0,500,0,0|h|56|0,640,0,0|v|22|0,240,0,0|e|34|0,380,0,0|p|46|0,520,0,0|j|58|0,660,0,0|b|0,260,0,0|r|36|0,400,0,0|a|48|0,540,0,0|k|60|0,680,0,0|n|16|0,175,0,0|(|28|0,315,0,0|'
..'Y|40|0,455,0,0|D|52|0,595,0,0|Z|19|0,212,0,0|Q|31|0,352,0,0|I|43|0,492,0,0|G|55|0,632,0,0|C|23|0,255,0,0|E|35|0,395,0,0|P|47|0,535,0,0|J|59|0,675,0,0|B|21|0,233,0,0|W|33|0,373,0,0|O|45|0,513,0,0|H|57|'
..'0,653,0,0|V|61|0,700,0,0|m|SheetsButton|0,390,0,160|0.4392,0.847,0.2509|0.2823,0.5686,0|Sheets (Space)|SheetsGui|0.5,-200,1,0|0,400,0,400|Sheet|1,0,1,0|0,360,0,360|0,0,0,0|rbxasset://textures/blackBkg'
..'_square.png|1,-12,50,0|Paste music here (1000 character limit)|0;0;2|1:2|2:3|3:4|4:5|5:6|6:7;n;3|1:8|2:9|3:10|4:11|5:12|7:13|8:14|9:15|10:16;2|1:17|2:18|3:19|4:15|5:20;n;3|1:7|3:21|4:15|5:22|7:23|8:24'
..'|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:7|9:22|10:28;p;3|1:29|2:30|3:31|4:20|5:22|12:29|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|12:29|7:23|8:32|9:15|10:28;p;3|1:33|2:34|3:21|4:15|5:22|7:23|8:2'
..'4|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:29|9:22|10:28;p;3|1:35|2:36|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:33|9:22|10:28;p;3|1:37|2:38|3:21|4:15|5:22|7:23|8:24|9:20|10:'
..'25;n;4|1:26|2:27|4:15|11:7|7:23|8:39|9:22|10:28;p;3|1:40|2:41|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:35|9:22|10:28;p;3|1:42|2:43|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:2'
..'6|2:27|4:15|11:7|7:23|8:37|9:22|10:28;p;3|1:44|2:45|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:46|9:22|10:28;p;3|1:39|2:47|3:31|4:20|5:22|12:29|7:23|8:24|9:20|10:25;n;4|1:26|2:'
..'27|4:15|11:7|12:29|7:23|8:48|9:15|10:28;p;3|1:46|2:49|3:31|4:20|5:22|12:29|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|12:29|7:23|8:50|9:15|10:28;p;3|1:51|2:52|3:31|4:20|5:22|12:29|7:23|8:24|9:20|10:'
..'25;n;4|1:26|2:27|4:15|11:7|12:29|7:23|8:53|9:15|10:28;p;3|1:54|2:55|3:56|4:20|5:22|12:29|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|12:29|7:23|8:57|9:15|10:28;p;3|1:58|2:59|3:21|4:15|5:22|7:23|8:24|'
..'9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:40|9:22|10:28;p;3|1:60|2:61|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:62|9:22|10:28;p;3|1:63|2:64|3:21|4:15|5:22|7:23|8:24|9:20|10:25'
..';n;4|1:26|2:27|4:15|11:7|7:23|8:65|9:22|10:28;p;3|1:66|2:67|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:68|9:22|10:28;p;3|1:25|2:69|3:31|4:20|5:22|12:29|7:23|8:24|9:20|10:25;n;4'
..'|1:26|2:27|4:15|11:7|12:29|7:23|8:70|9:15|10:28;p;3|1:71|2:72|3:31|4:20|5:22|12:29|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|12:29|7:23|8:73|9:15|10:28;p;3|1:74|2:75|3:31|4:20|5:22|12:29|7:23|8:24|'
..'9:20|10:25;n;4|1:26|2:27|4:15|11:7|12:29|7:23|8:76|9:15|10:28;p;3|1:77|2:78|3:31|4:20|5:22|12:29|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|12:29|7:23|8:79|9:15|10:28;p;3|1:80|2:81|3:21|4:15|5:22|7:'
..'23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:54|9:22|10:28;p;3|1:82|2:83|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:84|9:22|10:28;p;3|1:85|2:86|3:21|4:15|5:22|7:23|8:24|9:'
..'20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:87|9:22|10:28;p;3|1:88|2:89|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:90|9:22|10:28;p;3|1:91|2:92|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n'
..';4|1:26|2:27|4:15|11:7|7:23|8:93|9:22|10:28;p;3|1:94|2:95|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:96|9:22|10:28;p;3|1:97|2:98|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:'
..'27|4:15|11:7|7:23|8:99|9:22|10:28;p;3|1:100|2:101|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:102|9:22|10:28;p;3|1:28|2:103|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:1'
..'5|11:7|7:23|8:104|9:22|10:28;p;3|1:105|2:106|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:107|9:22|10:28;p;3|1:108|2:109|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11'
..':7|7:23|8:110|9:22|10:28;p;3|1:111|2:112|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:113|9:22|10:28;p;3|1:114|2:115|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7'
..':23|8:116|9:22|10:28;p;3|1:117|2:118|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:119|9:22|10:28;p;3|1:120|2:121|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|'
..'8:122|9:22|10:28;p;3|1:123|2:124|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:125|9:22|10:28;p;3|1:126|2:127|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:12'
..'8|9:22|10:28;p;3|1:129|2:130|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:131|9:22|10:28;p;3|1:132|2:133|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:134|9:'
..'22|10:28;p;3|1:135|2:136|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:137|9:22|10:28;p;3|1:16|2:138|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:139|9:22|10'
..':28;p;3|1:140|2:141|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:142|9:22|10:28;p;3|1:143|2:144|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:145|9:22|10:28;'
..'p;3|1:146|2:147|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:148|9:22|10:28;p;3|1:149|2:150|3:31|4:20|5:22|12:29|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|12:29|7:23|8:151|9:1'
..'5|10:28;p;3|1:152|2:153|3:31|4:20|5:22|12:29|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|12:29|7:23|8:154|9:15|10:28;p;3|1:155|2:156|3:31|4:20|5:22|12:29|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|'
..'12:29|7:23|8:157|9:15|10:28;p;3|1:158|2:159|3:31|4:20|5:22|12:29|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|12:29|7:23|8:160|9:15|10:28;p;3|1:161|2:162|3:31|4:20|5:22|12:29|7:23|8:24|9:20|10:25;n;4|'
..'1:26|2:27|4:15|11:7|12:29|7:23|8:163|9:15|10:28;p;3|1:164|2:165|3:31|4:20|5:22|12:29|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|12:29|7:23|8:166|9:15|10:28;p;3|1:167|2:168|3:31|4:20|5:22|12:29|7:23|'
..'8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|12:29|7:23|8:169|9:15|10:28;p;3|1:170|2:171|3:31|4:20|5:22|12:29|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|12:29|7:23|8:172|9:15|10:28;p;3|1:173|2:174|3:31|4'
..':20|5:22|12:29|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|12:29|7:23|8:175|9:15|10:28;p;3|1:176|2:177|3:31|4:20|5:22|12:29|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|12:29|7:23|8:178|9:15|10:28;p;'
..'3|1:179|2:180|3:31|4:20|5:22|12:29|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|12:29|7:23|8:181|9:15|10:28;p;3|1:182|2:183|3:31|4:20|5:22|12:29|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|12:29|7:23'
..'|8:184|9:15|10:28;p;3|1:185|2:186|3:56|4:20|5:22|12:29|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|12:29|7:23|8:187|9:15|10:28;p;3|1:188|2:189|3:56|4:20|5:22|12:29|7:23|8:24|9:20|10:25;n;4|1:26|2:27|'
..'4:15|11:7|12:29|7:23|8:190|9:15|10:28;p;3|1:191|2:192|3:56|4:20|5:22|12:29|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|12:29|7:23|8:193|9:15|10:28;p;3|1:194|2:195|3:56|4:20|5:22|12:29|7:23|8:24|9:20|'
..'10:25;n;4|1:26|2:27|4:15|11:7|12:29|7:23|8:196|9:15|10:28;p;3|1:197|2:198|3:21|4:15|5:22|7:23|8:24|9:20|10:25;n;4|1:26|2:27|4:15|11:7|7:23|8:199|9:22|10:28;p;p;3|1:200|2:201|3:10|4:202|5:203|7:13|8:20'
..'4|9:15|10:16;p;3|1:205|2:206|3:207|4:5|5:6|12:33|7:23|8:24|10:25;n;2|1:208|3:209|4:15|11:7|13:93;n;5|2:18|3:210|4:15|5:15|12:39|14:211|15:212|16:212|17:212|15:212;n;6|3:213|4:15|13:93|12:35|7:13|8:214'
..'|9:5|10:25|18:7|19:215|20:215;p;p;p;')
local Gui = script.Parent
for _,Object in pairs(Objects) do
	Object.Parent = Gui
end

local SScript = Gui:WaitForChild("Piano").Value
SScript.Keyboard.Case.Display.GUI.TextLabel.Text = "SB Edition by Mokiros\nOriginal by NickPatella"

PlayingEnabled = false

ScriptReady = false
----------------------------------
----------------------------------
----------------------------------
---------PIANO CONNECTION---------
----------------------------------
----------------------------------
----------------------------------

----------------------------------
------------VARIABLES-------------
----------------------------------

Connector = SScript:WaitForChild("Connector")

----------------------------------
------------FUNCTIONS-------------
----------------------------------

function Activate(cframe)
	PlayingEnabled = true
	MakePreventJumpConnections()
	MakeKeyboardConnections()
	MakeGuiConnections()
	SetCamera(cframe)	
	ShowPiano()
	SScript.Keyboard.BoundingBox.ChildAdded:Connect(function(s)
		if s:IsA("Sound") then
			s:Stop()
			s.Volume = 0
			wait()
			s:Destroy()
		end
	end)
end
function Deactivate()
	ReturnCamera()	
	BreakPreventJumpConnections()
	Jump(true)
	PlayingEnabled = false
	BreakKeyboardConnections()
	BreakGuiConnections()
	HidePiano()
	HideSheets()
end
function PlayNoteClient(note)
	PlayNoteSound(note)
	HighlightPianoKey(note)
	Connector:FireServer("play", note)
end
function Abort()
	Connector:FireServer("abort")
end

----------------------------------
-----------CONNECTIONS------------
----------------------------------


----------------------------------
----------------------------------
----------------------------------
----------KEYBOARD INPUT----------
----------------------------------
----------------------------------
----------------------------------

----------------------------------
------------VARIABLES-------------
----------------------------------

InputService = game:GetService("UserInputService")

----------------------------------
------------FUNCTIONS-------------
----------------------------------

function LetterToNote(key, shift)
	local letterNoteMap = "1!2@34$5%6^78*9(0qQwWeErtTyYuiIoOpPasSdDfgGhHjJklLzZxcCvVbBnm"
	local capitalNumberMap = ")!@#$%^&*("
	local letter = string.char(key)
	if shift then
		if tonumber(letter) then
			-- is a number
			letter = string.sub(capitalNumberMap, tonumber(letter) + 1, tonumber(letter) + 1)
		else
			letter = string.upper(letter)
		end
	end
	local note = string.find(letterNoteMap, letter, 1, true)
	if note then
		return note
	end
end

function KeyDown(Object)
	local key = Object.KeyCode.Value
	local shift = InputService:IsKeyDown(304) or InputService:IsKeyDown(303)
	if (key >= 97 and key <= 122) or  (key >= 48 and key <= 57) then
		-- a letter was pressed
		local note = LetterToNote(key, shift)
		if note then PlayNoteClient(note) end
	elseif key == 8 then
		-- backspace was pressed
		Deactivate()
	elseif key == 32 then
		-- space was pressed
		ToggleSheets()
	end
end

function Input(Object,TextBoxFocused)
	if TextBoxFocused then return end
	local type = Object.UserInputType.Name
	local state = Object.UserInputState.Name -- in case I ever add input types
	if type == "Keyboard" then
		if state == "Begin" then
			KeyDown(Object)
		end
	end
end

----------------------------------
-----------CONNECTIONS------------
----------------------------------

KeyboardConnection = nil
JumpConnection = nil

function MakeKeyboardConnections()
	KeyboardConnection = InputService.InputBegan:connect(Input)
	
end
function BreakKeyboardConnections()
	KeyboardConnection:Disconnect()
end



----------------------------------
----------------------------------
----------------------------------
----------GUI FUNCTIONS-----------
----------------------------------
----------------------------------
----------------------------------

----------------------------------
------------VARIABLES-------------
----------------------------------

PianoGui = Gui.PianoGui
SheetsGui = Gui.SheetsGui
SheetsVisible = false

----------------------------------
------------FUNCTIONS-------------
----------------------------------

function ShowPiano()
	PianoGui:TweenPosition(
		UDim2.new(0.5, -380, 1, -220),
		Enum.EasingDirection.Out,
		Enum.EasingStyle.Sine,
		.5,
		true
	)
end
function HidePiano()
	PianoGui:TweenPosition(
		UDim2.new(0.5, -380, 1, 0),
		Enum.EasingDirection.Out,
		Enum.EasingStyle.Sine,
		.5,
		true
	)
end
function ShowSheets()
	SheetsGui:TweenPosition(
		UDim2.new(0.5, -200, 1, -520),
		Enum.EasingDirection.Out,
		Enum.EasingStyle.Sine,
		.5,
		true
	)
end
function HideSheets()
	SheetsGui:TweenPosition(
		UDim2.new(0.5, -200, 1, 0),
		Enum.EasingDirection.Out,
		Enum.EasingStyle.Sine,
		.5,
		true
	)
end
function ToggleSheets()
	SheetsVisible = not SheetsVisible
	if SheetsVisible then
		ShowSheets()
	else
		HideSheets()
	end
end

function IsBlack(note)
	if note%12 == 2 or note%12 == 4 or note%12 == 7 or note%12 == 9 or note%12 == 11 then
		return true
	end
end

function HighlightPianoKey(note)
	local keyGui = PianoGui.Keys[note]
	if IsBlack(note) then
		keyGui.BackgroundColor3 = Color3.new(50/255, 50/255, 50/255)
	else
		keyGui.BackgroundColor3 = Color3.new(200/255, 200/255, 200/255)
	end
	delay(.5, function() RestorePianoKey(note) end)
end
function RestorePianoKey(note)
	local keyGui = PianoGui.Keys[note]
	if IsBlack(note) then
		keyGui.BackgroundColor3 = Color3.new(0, 0, 0)
	else
		keyGui.BackgroundColor3 = Color3.new(1, 1, 1)
	end
end

function PianoKeyPressed(Object, note)
	local type = Object.UserInputType.Name
	if type == "MouseButton1" or type == "Touch" then
		PlayNoteClient(note)
	end
end

function ExitButtonPressed(Object)
	local type = Object.UserInputType.Name
	if type == "MouseButton1" or type == "Touch" then
		Deactivate()
	end
end

function SheetsButtonPressed(Object)
	local type = Object.UserInputType.Name
	if type == "MouseButton1" or type == "Touch" then
		ToggleSheets()
	end
end

function SheetsEdited(property)
	if property == "Text" then
		local bounds = SheetsGui.Sheet.ScrollingFrame.TextBox.TextBounds
		SheetsGui.Sheet.ScrollingFrame.CanvasSize = UDim2.new(0, 0, 0, math.max(14, bounds.Y))
	end
end

----------------------------------
-----------CONNECTIONS------------
----------------------------------

PianoKeysConnections = {}
ExitButtonConnection = nil
SheetsButtonConnection = nil
SheetsEditedConnection = nil

function MakeGuiConnections()
	for i, v in pairs(PianoGui.Keys:GetChildren()) do
		PianoKeysConnections[i] = v.InputBegan:connect(function(Object) PianoKeyPressed(Object, tonumber(v.Name)) end)
	end
	
	ExitButtonConnection = PianoGui.ExitButton.InputBegan:connect(ExitButtonPressed)
	SheetsButtonConnection = PianoGui.SheetsButton.InputBegan:connect(SheetsButtonPressed)
	SheetsEditedConnection = SheetsGui.Sheet.ScrollingFrame.TextBox.Changed:connect(SheetsEdited)
end
function BreakGuiConnections()
	for i, v in pairs(PianoKeysConnections) do
		v:disconnect()
	end
	
	ExitButtonConnection:disconnect()
	SheetsButtonConnection:disconnect()
	SheetsEditedConnection:disconnect()
end

----------------------------------
----------------------------------
----------------------------------
----------SOUND CONTROL-----------
----------------------------------
----------------------------------
----------------------------------

----------------------------------
------------VARIABLES-------------
----------------------------------

ContentProvider = game:GetService("ContentProvider")
SoundFolder = Instance.new("Folder")
SoundFolder.Name = "SoundFolder"
SoundFolder.Parent = Gui
SoundList = {"233836579", "233844049", "233845680", "233852841", "233854135", "233856105", "233856105"}
ExistingSounds = {}

----------------------------------
------------FUNCTIONS-------------
----------------------------------

function PreloadAudio()
	for i, v in pairs(SoundList) do
		ContentProvider:Preload("rbxassetid://"..v)
	end
end
function PlayNoteSound(note1)
	local note2 = (note1 - 1)%12 + 1	-- Which note? (1-12)
	
	local octave = math.ceil(note1/12) -- Which octave?
	
	local sound = math.ceil(note2/2) -- Which audio?
	
	local offset = 16 * (octave - 1) + 8 * (1 - note2%2) -- How far in audio?
	
	local audio = Instance.new("Sound", SoundFolder) -- Create the audio
	audio.Volume = 10
	audio.SoundId = "rbxassetid://"..SoundList[sound] -- Give its sound
	audio.TimePosition = offset + (octave - .9)/15 -- set the time position
	audio:Play() -- Play the audio
	
	table.insert(ExistingSounds, 1, audio)
	if #ExistingSounds >= 10 then
		ExistingSounds[10]:Stop() -- limit the number of playing sounds!
		ExistingSounds[10] = nil
	end
	
	delay(4, function() audio:Stop() audio:remove() end ) -- remove the audio in 4 seconds, enough time for it to play
end

----------------------------------
----------------------------------
----------------------------------
----------CAMERA/PLAYER-----------
----------------------------------
----------------------------------
----------------------------------

----------------------------------
------------VARIABLES-------------
----------------------------------

Camera = workspace.CurrentCamera
controllers = {}
ControllerService = game:GetService("ControllerService")

----------------------------------
------------FUNCTIONS-------------
----------------------------------

function Jump(jump)
	local character = owner.Character
	if character then
		local humanoid = character:FindFirstChild("Humanoid")
		if humanoid then
			humanoid.Jump = jump
		end
	end
end
function HumanoidChanged(humanoid, property)
	--print(property)
	if property == "Jump" then
		humanoid.Jump = false
	elseif property == "Sit" then
		humanoid.Sit = true
	elseif property == "Parent" then
		Deactivate()
		Abort()
	end
end
function HumanoidDied()
	Deactivate()
end
function SetCamera(cframe)
	Camera.CameraType = Enum.CameraType.Scriptable
	Camera:Interpolate(cframe, cframe + cframe.lookVector, .5)
	--Camera.CoordinateFrame = cframe
end
function ReturnCamera()
	Camera.CameraType = Enum.CameraType.Custom
end

----------------------------------
-----------CONNECTIONS------------
----------------------------------

HumanoidChangedConnection = nil
HumanoidDiedConnection = nil

function MakePreventJumpConnections()
	local character = owner.Character
	if character then
		local humanoid = character:FindFirstChild("Humanoid")
		if humanoid then
			HumanoidChangedConnection = humanoid.Changed:connect(function(property)
				HumanoidChanged(humanoid, property)
			end)
			HumanoidDiedConnection = humanoid.Died:connect(HumanoidDied)
		end
	end
end
function BreakPreventJumpConnections()
	HumanoidChangedConnection:disconnect()
	HumanoidDiedConnection:disconnect()
end

----------------------------------
----------------------------------
----------------------------------
---------INITIATE SCRIPT----------
----------------------------------
----------------------------------
----------------------------------

ScriptReady = true
PreloadAudio()
local Bound = SScript.Keyboard.Keys.KeyBound
Activate(CFrame.new(
	(Bound.CFrame * CFrame.new(0, 5, 3)).p, -- +z is towards player
	(Bound.CFrame * CFrame.new(0, 1, 1)).p
))
]====]
INFO