So, I have a code that runs a round system. In the round 2 players have a duel and the winner gets teleported back to his corresponding seat.
I made a script that constantly checks if a player left, and if he did, which one and assigns a value to a variable.
The problem is that the code continues if either one player has 0 health or if he left which leaves me with something like this (This is an example if player1 died or if he left)
if _G.jmp1.Humanoid.Health == 0 or wpl.Value == 1 then --wpl is the player who left and _G.jmp1 is the character of the player
_G.jmp1.Humanoid:UnequipTools()
duelfinish:FireAllClients(pla1)
Players:GetPlayerFromCharacter(_G.jmp2).leaderstats.Kills.Value = Players:GetPlayerFromCharacter(_G.jmp2).leaderstats.Kills.Value + 1
script.Parent.DuelRoundScript.Disabled = true --stop round timer
wait(2.5)
died:FireClient(pla2) --DOES NOTHING, ADD A DEATH GUI
wait(0.5)
_G.jmp2:WaitForChild("Humanoid").Health = 0 --kill the winner, add a victory animation later or something also learn how to instantly reset a character!!!!!!!!!!!
wait(1.6)
duel2.Character.HumanoidRootPart.CFrame = duelseat2.CFrame --Teleport the winner back to his seat
status.Value = "The duel has been decided!"
wait(2)
status.Value = duelist2 .. " is the winner of duel " .. rounds .."!"
number = number - 1
wait(5)
break --Stop the duel round
end
Now I’m not entirely sure what to add to this to make sure the code continues if both players leave. I tried checking if the player2 (in this case the one who won) is nil and doing a break the code. If I do that the code just simply skips over the part where I teleport the player to his seat.
Has anybody had an issue like this? Or does anybody know how to go about fixing this part of the code
Edit: Breaks are here because this is in a while loop. If you have any questions about the code please ask
I only use _G to store the 2 players that are “dueling” so that I can continuously check what is happening with them. If that’s what you mean by game state then my bad
im finding it pretty difficult to understand what your problem is…
I tried checking if the player2 (in this case the one who won) is nil and doing a break the code. If I do that the code just simply skips over the part where I teleport the player to his seat.
i presume you mean that the problem is that the player2 isnt teleporting to their seat?
you could more reliably wait for the character to respawn by doing
_G.jmp2:WaitForChild("Humanoid").Health = 0
Players:GetPlayerFromCharacter(_G.jmp2).CharacterAdded:Wait()
--[[ remainder of code goes here]]--
instead of using wait(1.6)
if you could elaborate on what your exact problem is, that would be great!
Yea sure, no problem!
So the problem I am facing is that when player2 leaves the game the code bugs out and stops working.
I have tried to counter this by doing this code after every wait:
if Players:GetPlayerFromCharacter(_G.jmp2) == nil then
break
end
When I did this, the code did work, but the player wasn’t getting teleported.
Edit: So after seeing that the code above isn’t working well, I am searching for suggestions as for what might be the correct way of going about this
you could try using the coroutine library to cancel the code while its running if player 2 leaves
RoundCoroutine = coroutine.create(function()
--[[ While loop ]]--
if _G.jmp1.Humanoid.Health == 0 or wpl.Value == 1 then --wpl is the player who left and _G.jmp1 is the character of the player
Players.PlayerRemoving:Once(function(leavingPlayer)
if leavingPlayer.UserId == Players:GetPlayerFromCharacter(_G.jmp2).UserId then -- Player 2 has just left
coroutine.yield(RoundCoroutine) -- You need to yield a coroutine before closing it
coroutine.close(RoundCoroutine)
end
end)
--[[ Rest of code goes here ]]--
end
end)
coroutine.resume(RoundCoroutine)
you can look at the coroutine documentation here if you would like to.
Thanks for the reply and the documentation, never heard of coroutines so I’m gonna spend some time on it haha.
Also thanks for the compliment! I’m making it for a final high school project which I hope to get a really good grade on and I plan to add a lot more things since I have over a year to work on it!
Oh so basically how this works is we declare a coroutine and keep checking if a player left and if he left we just stop and close the coroutine so the rest of the code can continue? Thats really useful then!
Ok so this is perfect and works, but is there a way to stop the rest of the code until the coroutine is finished? After the players get teleported to the duel and the coroutine is made, the game realizes there’s only 1 player left at the table and gets sent to the win() function.
So I need the rest of the code to stop until the coroutine is finished
we declare a coroutine and keep checking if a player left…
now that you mention it, for performance, it would probably to change how the event is handled, because you only need to check if the player has left once.
also, setting it to PlayerRemoving:Once() will make the function not fire if Player 1 dies and then leaves, so that NEEDS to be changed!
RoundCoroutine = coroutine.create(function()
local PlayerLeaveConnection -- Connection that will be assigned later
--[[ While loop ]]--
if _G.jmp1.Humanoid.Health == 0 or wpl.Value == 1 then --wpl is the player who left and _G.jmp1 is the character of the player
if PlayerLeaveConnection == nil then -- PlayerLeaveConnection has not been assigned to..
PlayerLeaveConnection = Players.PlayerRemoving:Connect(function(leavingPlayer)
if leavingPlayer.UserId == Players:GetPlayerFromCharacter(_G.jmp2).UserId then -- Player 2 has just left
PlayerLeaveConnection:Disconnect() -- Players leaving will no-longer do anything
coroutine.yield(RoundCoroutine) -- You need to yield a coroutine before closing it
coroutine.close(RoundCoroutine)
end
end)
end
--[[ Rest of code goes here ]]--
end
end)
coroutine.resume(RoundCoroutine)
Yea, its a good thing you spotted that. Because if player1 left before player2 then the coroutine wouldn’t play out how we want it to be. Thanks a lot man!