Waltz Scripting

My quest to get good at scripting continues!

I’ve been working on a script this morning to handle pairing players together so they could dance together for a ball. Players get about 60 seconds to choose a partner and if they haven’t got one by then the script randomly assigns them one. I’m using an array of dictionaries to store each pair (the dictionary holds the two players). I also used a dictionary of the pairs to keep track of stuff because i wasn’t too sure which i wanted to use. For the final code I will only either use the array and just loop through it to find the index tho.

rn tho its a little iffy and hard to test alone so any advice on how to fix/improve it would be very appreciated!

-- Array of all Pairs
local pairArray = {}

-- Dictionary of Pairs to keep track of stuff for now
local Pairs = {}

-- Function to Create Individual Pair Dictionary
local function createDictionary(player1,player2)
	local individualPair = {
		Player1 = player1,
		Player2 = player2
	}
	table.insert(pairArray, individualPair)
	print(player1," and ", player2, " are now paired!")	
	
	Pairs[player1.Name] = player2
	Pairs[player2.Name] = player1
end

-- Function to Handle Manual Pairing by Player Click
local function onPlayerClick(player,clickDetector) --player is the player who clicked the clickdetector
	local clickDetector = clickDetector

	local Player1 = player
	local Player2 = game.Players:GetPlayerFromCharacter(clickDetector.Parent)
	
	-- Check if the players are already partners
	if Pairs[Player1.Name] == Player2 then
		Player1:Chat(Player2.Name .. " is already your partner")
		
	-- Check if the player2 is already paired
	elseif Pairs[Player2.Name] ~= nil then
		Player1:Chat(Player2.Name .. " is already paired with " .. Pairs[Player2.Name])
		
	-- Ask Player2 to accept the invitation to dance	
	else 
		local confirmed = false
		local confirmationGui = Player2.PlayerGui:WaitForChild("WaltzStuff").ConfirmationGUI
		confirmationGui.Enabled = true
		confirmationGui.Accept.MouseButton1Click:Connect(function()
			confirmed = true
			confirmationGui.Enabled = false
		end)
		confirmationGui.Decline.MouseButton1Click:Connect(function()
			confirmationGui.Enabled = false
		end)
		while not confirmed do
			wait(10)
			if not confirmed then
				confirmationGui.Enabled = false
			end
		end
		
		-- If player2 confirms, create a pair
		if confirmed then
			if Pairs[Player1.Name] ~= nil then
				Pairs[Player1.Name] = nil
			end
			createDictionary(Player1, Player2)				
		end
	end
end

-- Function to pair players randomly
local function pairUnpairedPlayers()
	local unpairedPlayers = {}
	for _, player in pairs(game.Players:GetPlayers()) do
		if Pairs[player.Name] == nil then
			table.insert(unpairedPlayers, player)
		end
	end
	for i = 1, #unpairedPlayers, 2 do
		createDictionary(unpairedPlayers[i], unpairedPlayers[i+1])
		table.remove(unpairedPlayers[i])
		table.remove(unpairedPlayers[i+1])
	end
end

--Connect createDictionary to each player's click detector
for _, player in pairs(game.Players:GetPlayers()) do
	local clickDetector = player.Character:WaitForChild("WaltzClick")
	clickDetector.MouseClick:Connect(onPlayerClick(player,clickDetector))
end



-- Function to remove an item from an array given its value
local function removeItemFromArray(array, value)
	for i, v in ipairs(array) do
		if v == value then
			table.remove(array, i)
			break
		end
	end
end

-- Function for When a Player Leaves the Game
local Players = game:GetService("Players")

Players.PlayerRemoving:Connect(function(player)
	if Pairs [player.Name] ~= nil then
		local partner = Pairs[player.Name]
		
		Pairs [partner.Name] = nil
		Pairs [player.Name] = nil
		
		removeItemFromArray(pairArray,player)
	end
end)


------------------ Initiate Sequence ----------------------------------
print("Sequencing Begun")
wait(10)
-- Display DanceStart
local WaltzGUI = game.StarterGui.WaltzStuff
local dancestart = WaltzGUI.DanceStart


for i,player in pairs(game:GetService("Players"):GetPlayers())do
	player.PlayerGui:WaitForChild("WaltzStuff").DanceStart.Enabled = true
end

wait(10)
for i,player in pairs(game:GetService("Players"):GetPlayers())do
	player.PlayerGui:WaitForChild("WaltzStuff").DanceStart.Enabled = false
end

print("Successful display")
-- Display PartnerChoice
local partnerChoice = WaltzGUI.PartnerChoice

for i,player in pairs(game:GetService("Players"):GetPlayers())do
	player.PlayerGui:WaitForChild("WaltzStuff").PartnerChoice.Enabled = true
end
wait(10)
for i,player in pairs(game:GetService("Players"):GetPlayers())do
	player.PlayerGui:WaitForChild("WaltzStuff").PartnerChoice.Enabled = false
end

-- Countdown for Players to Select Partners
local countGUI = WaltzGUI.CountGUI
--countGUI.Enabled = true

for i,player in pairs(game:GetService("Players"):GetPlayers())do
	player.PlayerGui:WaitForChild("WaltzStuff").CountGUI.Enabled = true
end

local countValue = game.ReplicatedStorage.CountValue
for count = 0,60,1 do
	countValue.Value = countValue.Value - 1
end

countGUI.Enabled = false

-- Pair Remaining Players
pairUnpairedPlayers()

-- Run Dance
for index, value in ipairs(pairArray) do
	local player1 = value.Player1
	local player2 = value.Player2
	
	local Character1 = player1.Character
	local Character2 = player2.Character
	
	local humanoid1 = Character1:WaitForChild("Humanoid")
	local humanoid2 = Character2:WaitForChild("Humanoid")					

	local Animator1 = humanoid1:WaitForChild("Animator")
	local Animator2 = humanoid2:WaitForChild("Animator")

	local Waltz1 = game.ServerStorage.Waltz1
	local Waltz1Track = Animator1:LoadAnimation(Waltz1)

	local Waltz2 = game.ServerStorage.Waltz2
	local Waltz2Track = Animator2:LoadAnimation(Waltz2)					

	humanoid1.WalkSpeed = 0
	humanoid2.WalkSpeed = 0
	
	-- Set the two player's positions
	local DancePositions = game.Workspace.DancePositions
	
	local offsetCframe1 = CFrame.new(2,0,0)
	local offsetCframe2 = CFrame.new(-2,0,0)
	
	local targetPosition = DancePositions[index].Position
	cFrame1 = DancePositions[index].CFrame:ToWorldSpace(offsetCframe1)
	cFrame2 = DancePositions[index].CFrame:ToWorldSpace(offsetCframe2)
	
	humanoid1.CFrame = CFrame.new(cFrame1,targetPosition)
	humanoid2.CFrame = CFrame.new(cFrame2,targetPosition)
	
	Waltz1Track:Play()
	Waltz2Track:Play()

	Waltz1Track.Stopped:Wait()
	Waltz2Track.Stopped:Wait()
	
	humanoid1.WalkSpeed = 16	
	humanoid2.WalkSpeed = 16
end

1 Like

Does the code work? Or whats the issue? It’s not super clear what your question is

1 Like

I haven’t gotten to test it yet because I need at least another player to do so (and my computer cant run the test feature in studio with two player so in the mean time I’m just looking for feedback on how to improve it + if anyone sees any logic/syntax errors I might’ve missed.