Advertisement
Guest User

Untitled

a guest
Aug 25th, 2019
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.08 KB | None | 0 0
  1.  
  2. --[[
  3. // FileName: BubbleChat.lua
  4. // Written by: jeditkacheff, TheGamer101
  5. // Description: Code for rendering bubble chat
  6. ]]
  7.  
  8. --[[ SERVICES ]]
  9. local PlayersService = game:GetService('Players')
  10. local ReplicatedStorage = game:GetService("ReplicatedStorage")
  11. local ChatService = game:GetService("Chat")
  12. local TextService = game:GetService("TextService")
  13. --[[ END OF SERVICES ]]
  14.  
  15. local LocalPlayer = PlayersService.LocalPlayer
  16. while LocalPlayer == nil do
  17. PlayersService.ChildAdded:wait()
  18. LocalPlayer = PlayersService.LocalPlayer
  19. end
  20.  
  21. local PlayerGui = LocalPlayer:WaitForChild("PlayerGui")
  22.  
  23. local okShouldClipInGameChat, valueShouldClipInGameChat = pcall(function() return UserSettings():IsUserFeatureEnabled("UserShouldClipInGameChat") end)
  24. local shouldClipInGameChat = okShouldClipInGameChat and valueShouldClipInGameChat
  25.  
  26. local success, UserShouldLocalizeGameChatBubble = pcall(function()
  27. return UserSettings():IsUserFeatureEnabled("UserShouldLocalizeGameChatBubble")
  28. end)
  29. local UserShouldLocalizeGameChatBubble = success and UserShouldLocalizeGameChatBubble
  30.  
  31. --[[ SCRIPT VARIABLES ]]
  32. local CHAT_BUBBLE_FONT = Enum.Font.SourceSans
  33. local CHAT_BUBBLE_FONT_SIZE = Enum.FontSize.Size24 -- if you change CHAT_BUBBLE_FONT_SIZE_INT please change this to match
  34. local CHAT_BUBBLE_FONT_SIZE_INT = 24 -- if you change CHAT_BUBBLE_FONT_SIZE please change this to match
  35. local CHAT_BUBBLE_LINE_HEIGHT = CHAT_BUBBLE_FONT_SIZE_INT + 10
  36. local CHAT_BUBBLE_TAIL_HEIGHT = 14
  37. local CHAT_BUBBLE_WIDTH_PADDING = 30
  38. local CHAT_BUBBLE_FADE_SPEED = 1.5
  39.  
  40. local BILLBOARD_MAX_WIDTH = 400
  41. local BILLBOARD_MAX_HEIGHT = 250 --This limits the number of bubble chats that you see above characters
  42.  
  43. local ELIPSES = "..."
  44. local MaxChatMessageLength = 128 -- max chat message length, including null terminator and elipses.
  45. local MaxChatMessageLengthExclusive = MaxChatMessageLength - string.len(ELIPSES) - 1
  46.  
  47. local NEAR_BUBBLE_DISTANCE = 65 --previously 45
  48. local MAX_BUBBLE_DISTANCE = 100 --previously 80
  49.  
  50. --[[ END OF SCRIPT VARIABLES ]]
  51.  
  52.  
  53. -- [[ SCRIPT ENUMS ]]
  54. local BubbleColor = { WHITE = "dub",
  55. BLUE = "blu",
  56. GREEN = "gre",
  57. RED = "red" }
  58.  
  59. --[[ END OF SCRIPT ENUMS ]]
  60.  
  61. -- This screenGui exists so that the billboardGui is not deleted when the PlayerGui is reset.
  62. local BubbleChatScreenGui = Instance.new("ScreenGui")
  63. BubbleChatScreenGui.Name = "BubbleChat"
  64. BubbleChatScreenGui.ResetOnSpawn = false
  65. BubbleChatScreenGui.Parent = PlayerGui
  66.  
  67. --[[ FUNCTIONS ]]
  68.  
  69. local function lerpLength(msg, min, max)
  70. return min + (max-min) * math.min(string.len(msg)/75.0, 1.0)
  71. end
  72.  
  73. local function createFifo()
  74. local this = {}
  75. this.data = {}
  76.  
  77. local emptyEvent = Instance.new("BindableEvent")
  78. this.Emptied = emptyEvent.Event
  79.  
  80. function this:Size()
  81. return #this.data
  82. end
  83.  
  84. function this:Empty()
  85. return this:Size() <= 0
  86. end
  87.  
  88. function this:PopFront()
  89. table.remove(this.data, 1)
  90. if this:Empty() then emptyEvent:Fire() end
  91. end
  92.  
  93. function this:Front()
  94. return this.data[1]
  95. end
  96.  
  97. function this:Get(index)
  98. return this.data[index]
  99. end
  100.  
  101. function this:PushBack(value)
  102. table.insert(this.data, value)
  103. end
  104.  
  105. function this:GetData()
  106. return this.data
  107. end
  108.  
  109. return this
  110. end
  111.  
  112. local function createCharacterChats()
  113. local this = {}
  114.  
  115. this.Fifo = createFifo()
  116. this.BillboardGui = nil
  117.  
  118. return this
  119. end
  120.  
  121. local function createMap()
  122. local this = {}
  123. this.data = {}
  124. local count = 0
  125.  
  126. function this:Size()
  127. return count
  128. end
  129.  
  130. function this:Erase(key)
  131. if this.data[key] then count = count - 1 end
  132. this.data[key] = nil
  133. end
  134.  
  135. function this:Set(key, value)
  136. this.data[key] = value
  137. if value then count = count + 1 end
  138. end
  139.  
  140. function this:Get(key)
  141. if not key then return end
  142. if not this.data[key] then
  143. this.data[key] = createCharacterChats()
  144. local emptiedCon = nil
  145. emptiedCon = this.data[key].Fifo.Emptied:connect(function()
  146. emptiedCon:disconnect()
  147. this:Erase(key)
  148. end)
  149. end
  150. return this.data[key]
  151. end
  152.  
  153. function this:GetData()
  154. return this.data
  155. end
  156.  
  157. return this
  158. end
  159.  
  160. local function createChatLine(message, bubbleColor, isLocalPlayer)
  161. local this = {}
  162.  
  163. function this:ComputeBubbleLifetime(msg, isSelf)
  164. if isSelf then
  165. return lerpLength(msg,8,15)
  166. else
  167. return lerpLength(msg,12,20)
  168. end
  169. end
  170.  
  171. this.Origin = nil
  172. this.RenderBubble = nil
  173. this.Message = message
  174. this.BubbleDieDelay = this:ComputeBubbleLifetime(message, isLocalPlayer)
  175. this.BubbleColor = bubbleColor
  176. this.IsLocalPlayer = isLocalPlayer
  177.  
  178. return this
  179. end
  180.  
  181. local function createPlayerChatLine(player, message, isLocalPlayer)
  182. local this = createChatLine(message, BubbleColor.WHITE, isLocalPlayer)
  183.  
  184. if player then
  185. this.User = player.Name
  186. this.Origin = player.Character
  187. end
  188.  
  189. return this
  190. end
  191.  
  192. local function createGameChatLine(origin, message, isLocalPlayer, bubbleColor)
  193. local this = createChatLine(message, bubbleColor, isLocalPlayer)
  194. this.Origin = origin
  195.  
  196. return this
  197. end
  198.  
  199. function createChatBubbleMain(filePrefix, sliceRect)
  200. local chatBubbleMain = Instance.new("ImageLabel")
  201. chatBubbleMain.Name = "ChatBubble"
  202. chatBubbleMain.ScaleType = Enum.ScaleType.Slice
  203. chatBubbleMain.SliceCenter = sliceRect
  204. chatBubbleMain.Image = "rbxasset://textures/" .. tostring(filePrefix) .. ".png"
  205. chatBubbleMain.BackgroundTransparency = 1
  206. chatBubbleMain.BorderSizePixel = 0
  207. chatBubbleMain.Size = UDim2.new(1.0, 0, 1.0, 0)
  208. chatBubbleMain.Position = UDim2.new(0,0,0,0)
  209.  
  210. return chatBubbleMain
  211. end
  212.  
  213. function createChatBubbleTail(position, size)
  214. local chatBubbleTail = Instance.new("ImageLabel")
  215. chatBubbleTail.Name = "ChatBubbleTail"
  216. chatBubbleTail.Image = "rbxasset://textures/ui/dialog_tail.png"
  217. chatBubbleTail.BackgroundTransparency = 1
  218. chatBubbleTail.BorderSizePixel = 0
  219. chatBubbleTail.Position = position
  220. chatBubbleTail.Size = size
  221.  
  222. return chatBubbleTail
  223. end
  224.  
  225. function createChatBubbleWithTail(filePrefix, position, size, sliceRect)
  226. local chatBubbleMain = createChatBubbleMain(filePrefix, sliceRect)
  227.  
  228. local chatBubbleTail = createChatBubbleTail(position, size)
  229. chatBubbleTail.Parent = chatBubbleMain
  230.  
  231. return chatBubbleMain
  232. end
  233.  
  234. function createScaledChatBubbleWithTail(filePrefix, frameScaleSize, position, sliceRect)
  235. local chatBubbleMain = createChatBubbleMain(filePrefix, sliceRect)
  236.  
  237. local frame = Instance.new("Frame")
  238. frame.Name = "ChatBubbleTailFrame"
  239. frame.BackgroundTransparency = 1
  240. frame.SizeConstraint = Enum.SizeConstraint.RelativeXX
  241. frame.Position = UDim2.new(0.5, 0, 1, 0)
  242. frame.Size = UDim2.new(frameScaleSize, 0, frameScaleSize, 0)
  243. frame.Parent = chatBubbleMain
  244.  
  245. local chatBubbleTail = createChatBubbleTail(position, UDim2.new(1,0,0.5,0))
  246. chatBubbleTail.Parent = frame
  247.  
  248. return chatBubbleMain
  249. end
  250.  
  251. function createChatImposter(filePrefix, dotDotDot, yOffset)
  252. local result = Instance.new("ImageLabel")
  253. result.Name = "DialogPlaceholder"
  254. result.Image = "rbxasset://textures/" .. tostring(filePrefix) .. ".png"
  255. result.BackgroundTransparency = 1
  256. result.BorderSizePixel = 0
  257. result.Position = UDim2.new(0, 0, -1.25, 0)
  258. result.Size = UDim2.new(1, 0, 1, 0)
  259.  
  260. local image = Instance.new("ImageLabel")
  261. image.Name = "DotDotDot"
  262. image.Image = "rbxasset://textures/" .. tostring(dotDotDot) .. ".png"
  263. image.BackgroundTransparency = 1
  264. image.BorderSizePixel = 0
  265. image.Position = UDim2.new(0.001, 0, yOffset, 0)
  266. image.Size = UDim2.new(1, 0, 0.7, 0)
  267. image.Parent = result
  268.  
  269. return result
  270. end
  271.  
  272.  
  273. local this = {}
  274. this.ChatBubble = {}
  275. this.ChatBubbleWithTail = {}
  276. this.ScalingChatBubbleWithTail = {}
  277. this.CharacterSortedMsg = createMap()
  278.  
  279. -- init chat bubble tables
  280. local function initChatBubbleType(chatBubbleType, fileName, imposterFileName, isInset, sliceRect)
  281. this.ChatBubble[chatBubbleType] = createChatBubbleMain(fileName, sliceRect)
  282. this.ChatBubbleWithTail[chatBubbleType] = createChatBubbleWithTail(fileName, UDim2.new(0.5, -CHAT_BUBBLE_TAIL_HEIGHT, 1, isInset and -1 or 0), UDim2.new(0, 30, 0, CHAT_BUBBLE_TAIL_HEIGHT), sliceRect)
  283. this.ScalingChatBubbleWithTail[chatBubbleType] = createScaledChatBubbleWithTail(fileName, 0.5, UDim2.new(-0.5, 0, 0, isInset and -1 or 0), sliceRect)
  284. end
  285.  
  286. initChatBubbleType(BubbleColor.WHITE, "ui/dialog_white", "ui/chatBubble_white_notify_bkg", false, Rect.new(5,5,15,15))
  287. initChatBubbleType(BubbleColor.BLUE, "ui/dialog_blue", "ui/chatBubble_blue_notify_bkg", true, Rect.new(7,7,33,33))
  288. initChatBubbleType(BubbleColor.RED, "ui/dialog_red", "ui/chatBubble_red_notify_bkg", true, Rect.new(7,7,33,33))
  289. initChatBubbleType(BubbleColor.GREEN, "ui/dialog_green", "ui/chatBubble_green_notify_bkg", true, Rect.new(7,7,33,33))
  290.  
  291. function this:SanitizeChatLine(msg)
  292. if string.len(msg) > MaxChatMessageLengthExclusive then
  293. return string.sub(msg, 1, MaxChatMessageLengthExclusive + string.len(ELIPSES))
  294. else
  295. return msg
  296. end
  297. end
  298.  
  299. local function createBillboardInstance(adornee)
  300. local billboardGui = Instance.new("BillboardGui")
  301. billboardGui.Adornee = adornee
  302. billboardGui.Size = UDim2.new(0,BILLBOARD_MAX_WIDTH,0,BILLBOARD_MAX_HEIGHT)
  303. billboardGui.StudsOffset = Vector3.new(0, 1.5, 2)
  304. billboardGui.Parent = BubbleChatScreenGui
  305.  
  306. local billboardFrame = Instance.new("Frame")
  307. billboardFrame.Name = "BillboardFrame"
  308. billboardFrame.Size = UDim2.new(1,0,1,0)
  309. billboardFrame.Position = UDim2.new(0,0,-0.5,0)
  310. billboardFrame.BackgroundTransparency = 1
  311. billboardFrame.Parent = billboardGui
  312.  
  313. local billboardChildRemovedCon = nil
  314. billboardChildRemovedCon = billboardFrame.ChildRemoved:connect(function()
  315. if #billboardFrame:GetChildren() <= 1 then
  316. billboardChildRemovedCon:disconnect()
  317. billboardGui:Destroy()
  318. end
  319. end)
  320.  
  321. this:CreateSmallTalkBubble(BubbleColor.WHITE).Parent = billboardFrame
  322.  
  323. return billboardGui
  324. end
  325.  
  326. function this:CreateBillboardGuiHelper(instance, onlyCharacter)
  327. if instance and not this.CharacterSortedMsg:Get(instance)["BillboardGui"] then
  328. if not onlyCharacter then
  329. if instance:IsA("BasePart") then
  330. -- Create a new billboardGui object attached to this player
  331. local billboardGui = createBillboardInstance(instance)
  332. this.CharacterSortedMsg:Get(instance)["BillboardGui"] = billboardGui
  333. return
  334. end
  335. end
  336.  
  337. if instance:IsA("Model") then
  338. local head = instance:FindFirstChild("Head")
  339. if head and head:IsA("BasePart") then
  340. -- Create a new billboardGui object attached to this player
  341. local billboardGui = createBillboardInstance(head)
  342. this.CharacterSortedMsg:Get(instance)["BillboardGui"] = billboardGui
  343. end
  344. end
  345. end
  346. end
  347.  
  348. local function distanceToBubbleOrigin(origin)
  349. if not origin then return 100000 end
  350.  
  351. return (origin.Position - game.Workspace.CurrentCamera.CoordinateFrame.p).magnitude
  352. end
  353.  
  354. local function isPartOfLocalPlayer(adornee)
  355. if adornee and PlayersService.LocalPlayer.Character then
  356. return adornee:IsDescendantOf(PlayersService.LocalPlayer.Character)
  357. end
  358. end
  359.  
  360. function this:SetBillboardLODNear(billboardGui)
  361. local isLocalPlayer = isPartOfLocalPlayer(billboardGui.Adornee)
  362. billboardGui.Size = UDim2.new(0, BILLBOARD_MAX_WIDTH, 0, BILLBOARD_MAX_HEIGHT)
  363. billboardGui.StudsOffset = Vector3.new(0, isLocalPlayer and 1.5 or 2.5, isLocalPlayer and 2 or 0.1)
  364. billboardGui.Enabled = true
  365. local billChildren = billboardGui.BillboardFrame:GetChildren()
  366. for i = 1, #billChildren do
  367. billChildren[i].Visible = true
  368. end
  369. billboardGui.BillboardFrame.SmallTalkBubble.Visible = false
  370. end
  371.  
  372. function this:SetBillboardLODDistant(billboardGui)
  373. local isLocalPlayer = isPartOfLocalPlayer(billboardGui.Adornee)
  374. billboardGui.Size = UDim2.new(4,0,3,0)
  375. billboardGui.StudsOffset = Vector3.new(0, 3, isLocalPlayer and 2 or 0.1)
  376. billboardGui.Enabled = true
  377. local billChildren = billboardGui.BillboardFrame:GetChildren()
  378. for i = 1, #billChildren do
  379. billChildren[i].Visible = false
  380. end
  381. billboardGui.BillboardFrame.SmallTalkBubble.Visible = true
  382. end
  383.  
  384. function this:SetBillboardLODVeryFar(billboardGui)
  385. billboardGui.Enabled = false
  386. end
  387.  
  388. function this:SetBillboardGuiLOD(billboardGui, origin)
  389. if not origin then return end
  390.  
  391. if origin:IsA("Model") then
  392. local head = origin:FindFirstChild("Head")
  393. if not head then origin = origin.PrimaryPart
  394. else origin = head end
  395. end
  396.  
  397. local bubbleDistance = distanceToBubbleOrigin(origin)
  398.  
  399. if bubbleDistance < NEAR_BUBBLE_DISTANCE then
  400. this:SetBillboardLODNear(billboardGui)
  401. elseif bubbleDistance >= NEAR_BUBBLE_DISTANCE and bubbleDistance < MAX_BUBBLE_DISTANCE then
  402. this:SetBillboardLODDistant(billboardGui)
  403. else
  404. this:SetBillboardLODVeryFar(billboardGui)
  405. end
  406. end
  407.  
  408. function this:CameraCFrameChanged()
  409. for index, value in pairs(this.CharacterSortedMsg:GetData()) do
  410. local playerBillboardGui = value["BillboardGui"]
  411. if playerBillboardGui then this:SetBillboardGuiLOD(playerBillboardGui, index) end
  412. end
  413. end
  414.  
  415. function this:CreateBubbleText(message, shouldAutoLocalize)
  416. local bubbleText = Instance.new("TextLabel")
  417. bubbleText.Name = "BubbleText"
  418. bubbleText.BackgroundTransparency = 1
  419. bubbleText.Position = UDim2.new(0,CHAT_BUBBLE_WIDTH_PADDING/2,0,0)
  420. bubbleText.Size = UDim2.new(1,-CHAT_BUBBLE_WIDTH_PADDING,1,0)
  421. bubbleText.Font = CHAT_BUBBLE_FONT
  422. if shouldClipInGameChat then
  423. bubbleText.ClipsDescendants = true
  424. end
  425. bubbleText.TextWrapped = true
  426. bubbleText.FontSize = CHAT_BUBBLE_FONT_SIZE
  427. bubbleText.Text = message
  428. bubbleText.Visible = false
  429. bubbleText.AutoLocalize = shouldAutoLocalize
  430.  
  431. return bubbleText
  432. end
  433.  
  434. function this:CreateSmallTalkBubble(chatBubbleType)
  435. local smallTalkBubble = this.ScalingChatBubbleWithTail[chatBubbleType]:Clone()
  436. smallTalkBubble.Name = "SmallTalkBubble"
  437. smallTalkBubble.AnchorPoint = Vector2.new(0, 0.5)
  438. smallTalkBubble.Position = UDim2.new(0,0,0.5,0)
  439. smallTalkBubble.Visible = false
  440. local text = this:CreateBubbleText("...")
  441. text.TextScaled = true
  442. text.TextWrapped = false
  443. text.Visible = true
  444. text.Parent = smallTalkBubble
  445.  
  446. return smallTalkBubble
  447. end
  448.  
  449. function this:UpdateChatLinesForOrigin(origin, currentBubbleYPos)
  450. local bubbleQueue = this.CharacterSortedMsg:Get(origin).Fifo
  451. local bubbleQueueSize = bubbleQueue:Size()
  452. local bubbleQueueData = bubbleQueue:GetData()
  453. if #bubbleQueueData <= 1 then return end
  454.  
  455. for index = (#bubbleQueueData - 1), 1, -1 do
  456. local value = bubbleQueueData[index]
  457. local bubble = value.RenderBubble
  458. if not bubble then return end
  459. local bubblePos = bubbleQueueSize - index + 1
  460.  
  461. if bubblePos > 1 then
  462. local tail = bubble:FindFirstChild("ChatBubbleTail")
  463. if tail then tail:Destroy() end
  464. local bubbleText = bubble:FindFirstChild("BubbleText")
  465. if bubbleText then bubbleText.TextTransparency = 0.5 end
  466. end
  467.  
  468. local udimValue = UDim2.new( bubble.Position.X.Scale, bubble.Position.X.Offset,
  469. 1, currentBubbleYPos - bubble.Size.Y.Offset - CHAT_BUBBLE_TAIL_HEIGHT )
  470. bubble:TweenPosition(udimValue, Enum.EasingDirection.Out, Enum.EasingStyle.Bounce, 0.1, true)
  471. currentBubbleYPos = currentBubbleYPos - bubble.Size.Y.Offset - CHAT_BUBBLE_TAIL_HEIGHT
  472. end
  473. end
  474.  
  475. function this:DestroyBubble(bubbleQueue, bubbleToDestroy)
  476. if not bubbleQueue then return end
  477. if bubbleQueue:Empty() then return end
  478.  
  479. local bubble = bubbleQueue:Front().RenderBubble
  480. if not bubble then
  481. bubbleQueue:PopFront()
  482. return
  483. end
  484.  
  485. spawn(function()
  486. while bubbleQueue:Front().RenderBubble ~= bubbleToDestroy do
  487. wait()
  488. end
  489.  
  490. bubble = bubbleQueue:Front().RenderBubble
  491.  
  492. local timeBetween = 0
  493. local bubbleText = bubble:FindFirstChild("BubbleText")
  494. local bubbleTail = bubble:FindFirstChild("ChatBubbleTail")
  495.  
  496. while bubble and bubble.ImageTransparency < 1 do
  497. timeBetween = wait()
  498. if bubble then
  499. local fadeAmount = timeBetween * CHAT_BUBBLE_FADE_SPEED
  500. bubble.ImageTransparency = bubble.ImageTransparency + fadeAmount
  501. if bubbleText then bubbleText.TextTransparency = bubbleText.TextTransparency + fadeAmount end
  502. if bubbleTail then bubbleTail.ImageTransparency = bubbleTail.ImageTransparency + fadeAmount end
  503. end
  504. end
  505.  
  506. if bubble then
  507. bubble:Destroy()
  508. bubbleQueue:PopFront()
  509. end
  510. end)
  511. end
  512.  
  513. function this:CreateChatLineRender(instance, line, onlyCharacter, fifo, shouldAutoLocalize)
  514. if not instance then return end
  515.  
  516. if not this.CharacterSortedMsg:Get(instance)["BillboardGui"] then
  517. this:CreateBillboardGuiHelper(instance, onlyCharacter)
  518. end
  519.  
  520. local billboardGui = this.CharacterSortedMsg:Get(instance)["BillboardGui"]
  521. if billboardGui then
  522. local chatBubbleRender = this.ChatBubbleWithTail[line.BubbleColor]:Clone()
  523. chatBubbleRender.Visible = false
  524. local bubbleText = this:CreateBubbleText(line.Message, shouldAutoLocalize)
  525.  
  526. bubbleText.Parent = chatBubbleRender
  527. chatBubbleRender.Parent = billboardGui.BillboardFrame
  528.  
  529. line.RenderBubble = chatBubbleRender
  530.  
  531. local currentTextBounds = TextService:GetTextSize(
  532. bubbleText.Text, CHAT_BUBBLE_FONT_SIZE_INT, CHAT_BUBBLE_FONT,
  533. Vector2.new(BILLBOARD_MAX_WIDTH, BILLBOARD_MAX_HEIGHT))
  534. local bubbleWidthScale = math.max((currentTextBounds.X + CHAT_BUBBLE_WIDTH_PADDING)/BILLBOARD_MAX_WIDTH, 0.1)
  535. local numOflines = (currentTextBounds.Y/CHAT_BUBBLE_FONT_SIZE_INT)
  536.  
  537. -- prep chat bubble for tween
  538. chatBubbleRender.Size = UDim2.new(0,0,0,0)
  539. chatBubbleRender.Position = UDim2.new(0.5,0,1,0)
  540.  
  541. local newChatBubbleOffsetSizeY = numOflines * CHAT_BUBBLE_LINE_HEIGHT
  542.  
  543. chatBubbleRender:TweenSizeAndPosition(UDim2.new(bubbleWidthScale, 0, 0, newChatBubbleOffsetSizeY),
  544. UDim2.new( (1-bubbleWidthScale)/2, 0, 1, -newChatBubbleOffsetSizeY),
  545. Enum.EasingDirection.Out, Enum.EasingStyle.Elastic, 0.1, true,
  546. function() bubbleText.Visible = true end)
  547.  
  548. -- todo: remove when over max bubbles
  549. this:SetBillboardGuiLOD(billboardGui, line.Origin)
  550. this:UpdateChatLinesForOrigin(line.Origin, -newChatBubbleOffsetSizeY)
  551.  
  552. delay(line.BubbleDieDelay, function()
  553. this:DestroyBubble(fifo, chatBubbleRender)
  554. end)
  555. end
  556. end
  557.  
  558. function this:OnPlayerChatMessage(sourcePlayer, message, targetPlayer)
  559.  
  560. if not this:BubbleChatEnabled() then return end
  561.  
  562. local localPlayer = PlayersService.LocalPlayer
  563. local fromOthers = localPlayer ~= nil and sourcePlayer ~= localPlayer
  564.  
  565. local safeMessage = this:SanitizeChatLine(message)
  566.  
  567. local line = createPlayerChatLine(sourcePlayer, safeMessage, not fromOthers)
  568.  
  569. if sourcePlayer and line.Origin then
  570. local fifo = this.CharacterSortedMsg:Get(line.Origin).Fifo
  571. fifo:PushBack(line)
  572. --Game chat (badges) won't show up here
  573. this:CreateChatLineRender(sourcePlayer.Character, line, true, fifo, false)
  574. end
  575. end
  576.  
  577. function this:OnGameChatMessage(origin, message, color)
  578. local localPlayer = PlayersService.LocalPlayer
  579. local fromOthers = localPlayer ~= nil and (localPlayer.Character ~= origin)
  580.  
  581. local bubbleColor = BubbleColor.WHITE
  582.  
  583. if color == Enum.ChatColor.Blue then bubbleColor = BubbleColor.BLUE
  584. elseif color == Enum.ChatColor.Green then bubbleColor = BubbleColor.GREEN
  585. elseif color == Enum.ChatColor.Red then bubbleColor = BubbleColor.RED end
  586.  
  587. local safeMessage = this:SanitizeChatLine(message)
  588. local line = createGameChatLine(origin, safeMessage, not fromOthers, bubbleColor)
  589.  
  590. this.CharacterSortedMsg:Get(line.Origin).Fifo:PushBack(line)
  591. if UserShouldLocalizeGameChatBubble then
  592. this:CreateChatLineRender(origin, line, false, this.CharacterSortedMsg:Get(line.Origin).Fifo, true)
  593. else
  594. this:CreateChatLineRender(origin, line, false, this.CharacterSortedMsg:Get(line.Origin).Fifo, false)
  595. end
  596. end
  597.  
  598. function this:BubbleChatEnabled()
  599. local clientChatModules = ChatService:FindFirstChild("ClientChatModules")
  600. if clientChatModules then
  601. local chatSettings = clientChatModules:FindFirstChild("ChatSettings")
  602. if chatSettings then
  603. local chatSettings = require(chatSettings)
  604. if chatSettings.BubbleChatEnabled ~= nil then
  605. return chatSettings.BubbleChatEnabled
  606. end
  607. end
  608. end
  609. return PlayersService.BubbleChat
  610. end
  611.  
  612. function this:ShowOwnFilteredMessage()
  613. local clientChatModules = ChatService:FindFirstChild("ClientChatModules")
  614. if clientChatModules then
  615. local chatSettings = clientChatModules:FindFirstChild("ChatSettings")
  616. if chatSettings then
  617. chatSettings = require(chatSettings)
  618. return chatSettings.ShowUserOwnFilteredMessage
  619. end
  620. end
  621. return false
  622. end
  623.  
  624. function findPlayer(playerName)
  625. for i,v in pairs(PlayersService:GetPlayers()) do
  626. if v.Name == playerName then
  627. return v
  628. end
  629. end
  630. end
  631.  
  632. ChatService.Chatted:connect(function(origin, message, color) this:OnGameChatMessage(origin, message, color) end)
  633.  
  634. local cameraChangedCon = nil
  635. if game.Workspace.CurrentCamera then
  636. cameraChangedCon = game.Workspace.CurrentCamera:GetPropertyChangedSignal("CFrame"):connect(function(prop) this:CameraCFrameChanged() end)
  637. end
  638.  
  639. game.Workspace.Changed:connect(function(prop)
  640. if prop == "CurrentCamera" then
  641. if cameraChangedCon then cameraChangedCon:disconnect() end
  642. if game.Workspace.CurrentCamera then
  643. cameraChangedCon = game.Workspace.CurrentCamera:GetPropertyChangedSignal("CFrame"):connect(function(prop) this:CameraCFrameChanged() end)
  644. end
  645. end
  646. end)
  647.  
  648.  
  649. local AllowedMessageTypes = nil
  650.  
  651. function getAllowedMessageTypes()
  652. if AllowedMessageTypes then
  653. return AllowedMessageTypes
  654. end
  655. local clientChatModules = ChatService:FindFirstChild("ClientChatModules")
  656. if clientChatModules then
  657. local chatSettings = clientChatModules:FindFirstChild("ChatSettings")
  658. if chatSettings then
  659. chatSettings = require(chatSettings)
  660. if chatSettings.BubbleChatMessageTypes then
  661. AllowedMessageTypes = chatSettings.BubbleChatMessageTypes
  662. return AllowedMessageTypes
  663. end
  664. end
  665. local chatConstants = clientChatModules:FindFirstChild("ChatConstants")
  666. if chatConstants then
  667. chatConstants = require(chatConstants)
  668. AllowedMessageTypes = {chatConstants.MessageTypeDefault, chatConstants.MessageTypeWhisper}
  669. end
  670. return AllowedMessageTypes
  671. end
  672. return {"Message", "Whisper"}
  673. end
  674.  
  675. function checkAllowedMessageType(messageData)
  676. local allowedMessageTypes = getAllowedMessageTypes()
  677. for i = 1, #allowedMessageTypes do
  678. if allowedMessageTypes[i] == messageData.MessageType then
  679. return true
  680. end
  681. end
  682. return false
  683. end
  684.  
  685. local ChatEvents = ReplicatedStorage:WaitForChild("DefaultChatSystemChatEvents")
  686. local OnMessageDoneFiltering = ChatEvents:WaitForChild("OnMessageDoneFiltering")
  687. local OnNewMessage = ChatEvents:WaitForChild("OnNewMessage")
  688.  
  689. OnNewMessage.OnClientEvent:connect(function(messageData, channelName)
  690. if not checkAllowedMessageType(messageData) then
  691. return
  692. end
  693.  
  694. local sender = findPlayer(messageData.FromSpeaker)
  695. if not sender then
  696. return
  697. end
  698.  
  699. if not messageData.IsFiltered or messageData.FromSpeaker == LocalPlayer.Name then
  700. if messageData.FromSpeaker ~= LocalPlayer.Name or this:ShowOwnFilteredMessage() then
  701. return
  702. end
  703. end
  704.  
  705. this:OnPlayerChatMessage(sender, messageData.Message, nil)
  706. end)
  707.  
  708. OnMessageDoneFiltering.OnClientEvent:connect(function(messageData, channelName)
  709. if not checkAllowedMessageType(messageData) then
  710. return
  711. end
  712.  
  713. local sender = findPlayer(messageData.FromSpeaker)
  714. if not sender then
  715. return
  716. end
  717.  
  718. if messageData.FromSpeaker == LocalPlayer.Name and not this:ShowOwnFilteredMessage() then
  719. return
  720. end
  721.  
  722. this:OnPlayerChatMessage(sender, messageData.Message, nil)
  723. end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement