Advertisement
Guest User

Untitled

a guest
Feb 25th, 2017
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.71 KB | None | 0 0
  1. local lookForGameEvent = game.ReplicatedStorage.LookForGameEvent
  2. local rankedList = require(game.ServerStorage.MatchmakingRankedListModule)
  3. local ratingData = game:GetService("DataStoreService"):GetDataStore("RatingData")
  4. local teleportService = game:GetService("TeleportService")
  5. local arenaPlaceTemplateId = 667393809
  6.  
  7. -- Table to hold the queue of players looking for a game
  8. local matchMakingQueue = {}
  9.  
  10. -- Add player's id to the queue as well as the time that they entered the queue
  11. local addToMMQueue = function(playerId, enteredTime)
  12.     local data = {}
  13.     data.UserId = playerId
  14.     data.EnteredQueue = enteredTime
  15.     table.insert(matchMakingQueue, data)
  16. end
  17.  
  18. -- Remove player from the queue
  19. local removeFromMMQueue = function(playerId)
  20.     for i, playerData in pairs(matchMakingQueue) do
  21.         if playerData.UserId == playerId then
  22.             table.remove(matchMakingQueue, i)
  23.             return
  24.         end
  25.     end
  26. end
  27.  
  28. -- Handle player joining the game. If they are a new player we need to give them
  29. -- an initial rank. For existing players we need to fetch their rank from our
  30. -- DataStore. Lastly, we want to display the player's rank in the Leaderboard
  31. game.Players.PlayerAdded:connect(function(player)
  32.     local playerData = {}
  33.  
  34.     -- Create a default rating of 1500 if the player's data is not in the DataStore
  35.     ratingData:UpdateAsync(player.userId, function(oldValue)
  36.         local newValue = oldValue
  37.         if not newValue then
  38.             newValue = {Rating = 1500}
  39.         end
  40.         return newValue
  41.     end)
  42.     playerData.Score = ratingData:GetAsync(tostring(player.userId)).Rating
  43.  
  44.     -- Display rating in Leaderboard
  45.     local leaderstats = Instance.new("Model", player)
  46.     leaderstats.Name = "leaderstats"
  47.  
  48.     local displayRating = Instance.new("IntValue", leaderstats)
  49.     displayRating.Name = "Rating"
  50.     displayRating.Value = playerData.Score
  51. end)
  52.  
  53. -- Adds player both to queue and list to search for match
  54. local function playerSearchingForMatch(userId, rank)
  55.     local now = os.time()
  56.     addToMMQueue(userId, now)
  57.     rankedList:AddPlayer(userId, rank, now)
  58. end
  59.  
  60. -- Remove player from list and queue when they leave the game
  61. game.Players.PlayerRemoving:connect(function(player)
  62.     removeFromMMQueue(player.userId)
  63.     rankedList:RemovePlayer(player.userId)
  64. end)
  65.  
  66. -- Handle remote event to either add or remove player from the queue
  67. lookForGameEvent.OnServerEvent:connect(function(player, lookingForGame)
  68.     if lookingForGame then
  69.         print(player.Name .. " now looking for game")
  70.         local enteredTime = os.time()
  71.         playerSearchingForMatch(player.userId, player.leaderstats.Rating.Value)
  72.     else
  73.         print(player.Name .. " has left the queue")
  74.         removeFromMMQueue(player.userId)
  75.         rankedList:RemovePlayer(player.userId)
  76.     end
  77. end)
  78.  
  79. -- Returns a rank range to search through based on time waiting in the queue.
  80. -- If player has been waiting too long just return math.huge so the player can
  81. -- be matched with anyone.
  82. local getRange = function(timeWaiting)
  83.     if timeWaiting < 10 then
  84.         return 100
  85.     elseif timeWaiting >=10 and timeWaiting < 20 then
  86.         return 200
  87.     elseif timeWaiting >=20 and timeWaiting <= 35 then
  88.         return 300
  89.     end
  90.     return math.huge
  91. end
  92.  
  93. -- Creates place for game and teleports both players to it
  94. local startGame = function(playerAId, playerBId)
  95.     local message = ""
  96.     print("starting game with " .. playerAId .. " and " .. playerBId)
  97.  
  98.     -- Get both player objects
  99.     local playerA = nil
  100.     local playerB = nil
  101.     for _, player in pairs(game.Players:GetPlayers()) do
  102.         if player.userId == playerAId then
  103.             playerA = player
  104.         end
  105.         if player.userId == playerBId then
  106.             playerB = player
  107.         end
  108.     end
  109.  
  110.     -- Create arena place and get its id
  111.     local arenaPlaceId = game:GetService("AssetService"):CreatePlaceAsync(
  112.         "Arena place for " .. playerA.Name .. " and " .. playerB.Name, arenaPlaceTemplateId)
  113.  
  114.     -- Bind OnTeleport event to playerA (who is teleported first). If that teleport is successful
  115.     -- then we want playerB to be teleported to the same instance
  116.     local connection = playerA.OnTeleport:connect(function(teleportState, placeId)
  117.         if teleportState == Enum.TeleportState.Started then
  118.             local teleportStarted = os.time()
  119.             -- Keep checking if playerA has arrived in other instance.
  120.             while true do
  121.                 local success, error, placeId, arenaInstanceId = teleportService:GetPlayerPlaceInstanceAsync(playerAId)
  122.                 -- If playerA is in the correct place then we can teleport playerB there as well
  123.                 if placeId == arenaPlaceId then
  124.                     teleportService:TeleportToPlaceInstance(arenaPlaceId, arenaInstanceId, playerB)
  125.                     return
  126.                 end
  127.                 wait()
  128.             end
  129.         end
  130.     end)
  131.     wait(1)
  132.  
  133.     -- Teleport playerA to the arena
  134.     teleportService:Teleport(arenaPlaceId, playerA)
  135. end
  136.  
  137. -- Matchmaking loop. Cycles about every 5 seconds to match players.
  138. while true do
  139.     local now = os.time()
  140.     -- Cycle through queue, try to find players in range
  141.     for _, mmData in pairs(matchMakingQueue) do
  142.         print("attempting to find match for " .. mmData.UserId)
  143.         -- Get rank range to search
  144.         local range = getRange(now - mmData.EnteredQueue)
  145.         -- Use list to find a player in player's rank range
  146.         local otherPlayerId = rankedList:FindPlayerInRange(mmData.UserId, range)
  147.         if otherPlayerId then
  148.             -- Another player was found. Remove both players from the queue and list so they
  149.             -- can't be matched with anyone else
  150.             print("found player: " .. otherPlayerId)
  151.             rankedList:RemovePlayer(mmData.UserId)
  152.             rankedList:RemovePlayer(otherPlayerId)
  153.             removeFromMMQueue(mmData.UserId)
  154.             removeFromMMQueue(otherPlayerId)
  155.             -- Start game with the two players. This function can take some times, so start a
  156.             -- coroutine so the loop can continue.
  157.             local thread = coroutine.create(function() startGame(mmData.UserId, otherPlayerId) end)
  158.             coroutine.resume(thread)
  159.         end
  160.     end
  161.     wait(5)
  162. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement