Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --game:GetService("StarterGui"):SetCoreGuiEnabled("Chat", false)
- local NameColorDependsOnChatColor = true
- local StrokeTransparency = 0.5 -- Number 0 to 1. Lower stroke transparency is easier to read against colorful backgrounds.
- while not _G.PlayerListAPI do wait() end
- local PLAYERLIST_ADMINS, PLAYERLIST_CHATCOLORS, PLAYERLIST_ALIASES = _G.PlayerListAPI:GetChatData()
- local forceChatGUI = false
- -- Utility functions + Globals
- local function WaitForChild(parent, childName)
- while parent:FindFirstChild(childName) == nil do
- parent.ChildAdded:wait(0.03)
- end
- return parent[childName]
- end
- local function typedef(obj)
- return obj
- end
- local function IsPhone()
- local rGui = script.Parent
- if rGui.AbsoluteSize.Y < 600 then
- return true
- end
- return false
- end
- local export = {}
- export.NameColorDependsOnChatColor = NameColorDependsOnChatColor
- export.SetNameColorDependsOnChatColor = function(self, b)
- self.NameColorDependsOnChatColor = b
- end
- -- Users can use enough white spaces to spoof chatting as other players
- -- This function removes trailing and leading white spaces
- -- AFAIK, there is no reason for spam white spaces
- local function StringTrim(str)
- -- %S is whitespaces
- -- When we find the first non space character defined by ^%s
- -- we yank out anything in between that and the end of the string
- -- Everything else is replaced with %1 which is essentially nothing
- return (str:gsub("^%s*(.-)%s*$", "%1"))
- end
- while Game.Players.LocalPlayer == nil do wait(0.03) end
- local Player = Game.Players.LocalPlayer
- while Player.Character == nil do wait(0.03) end
- local RbxUtility = LoadLibrary('RbxUtility')
- local Gui = typedef(RbxUtility)
- local Camera = Game.Workspace.CurrentCamera
- -- Services
- local CoreGuiService = Game:GetService('CoreGui')
- local PlayersService = Game:GetService('Players')
- local DebrisService= Game:GetService('Debris')
- local GuiService = Game:GetService('GuiService')
- -- Lua Enums
- local Enums do
- Enums = {}
- local EnumName = {} -- used as unique key for enum name
- local enum_mt = {
- __call = function(self,value)
- return self[value] or self[tonumber(value)]
- end;
- __index = {
- GetEnumItems = function(self)
- local t = {}
- for i,item in pairs(self) do
- if type(i) == 'number' then
- t[#t+1] = item
- end
- end
- table.sort(t,function(a,b) return a.Value < b.Value end)
- return t
- end;
- };
- __tostring = function(self)
- return "Enum." .. self[EnumName]
- end;
- }
- local item_mt = {
- __call = function(self,value)
- return value == self or value == self.Name or value == self.Value
- end;
- __tostring = function(self)
- return "Enum." .. self[EnumName] .. "." .. self.Name
- end;
- }
- function CreateEnum(enumName)
- return function(t)
- local e = {[EnumName] = enumName}
- for i,name in pairs(t) do
- local item = setmetatable({Name=name,Value=i,Enum=e,[EnumName]=enumName},item_mt)
- e[i] = item
- e[name] = item
- e[item] = item
- end
- Enums[enumName] = e
- return setmetatable(e, enum_mt)
- end
- end
- end
- ---------------------------------------------------
- ------------------ Input class --------------------
- local Input = {
- Mouse = Player:GetMouse(),
- Speed = 0,
- Simulating = false,
- Configuration = {
- DefaultSpeed = 1
- },
- UserIsScrolling = false
- }
- ---------------------------------------------------
- ------------------ Chat class --------------------
- local Chat = {
- ChatColors = {
- BrickColor.new("Bright red"),
- BrickColor.new("Bright blue"),
- BrickColor.new("Earth green"),
- BrickColor.new("Bright violet"),
- BrickColor.new("Bright orange"),
- BrickColor.new("Bright yellow"),
- BrickColor.new("Light reddish violet"),
- BrickColor.new("Brick yellow"),
- },
- Gui = nil,
- Frame = nil,
- RenderFrame = nil,
- TapToChatLabel = nil,
- ClickToChatButton = nil,
- ScrollingLock = false,
- EventListener = nil,
- -- This is actually a ring buffer
- -- Meaning at hitting the historyLength it wraps around
- -- Reuses the text objects, so chat atmost uses 100 text objects
- MessageQueue = {},
- -- Stores all the values for configuring chat
- Configuration = {
- FontSize = Enum.FontSize.Size12, -- 10 is good
- -- Also change this when you are changing the above, this is suboptimal but so is our interface to find FontSize
- NumFontSize = 12,
- HistoryLength = 20, -- stores up to 50 of the last chat messages for you to scroll through,
- Size = UDim2.new(0.38, 0, 0.20, 0),
- MessageColor = Color3.new(1, 1, 1),
- AdminMessageColor = Color3.new(1, 215/255, 0),
- XScale = 0.025,
- LifeTime = 45,
- Position = UDim2.new(0, 2, 0.05, 0),
- DefaultTweenSpeed = 0.15,
- },
- -- This could be redone by just using the previous and next fields of the Queue
- -- But the iterators cause issues, will be optimized later
- SlotPositions_List = {},
- -- To precompute and store all player null strings since its an expensive process
- CachedSpaceStrings_List = {},
- MouseOnFrame = false,
- GotFocus = false,
- Messages_List = {},
- MessageThread = nil,
- Admins_List = PLAYERLIST_ADMINS,
- SafeChat_List = {
- ['Use the Chat menu to talk to me.'] = {'/sc 0', true},
- ['I can only see menu chats.'] = {'/sc 1', true},
- ['Hello'] = {
- ['Hi'] = {'/sc 2_0', true, ['Hi there!'] = true, ['Hi everyone'] = true},
- ['Howdy'] = {'/sc 2_1', true, ['Howdy partner!'] = true},
- ['Greetings'] = {'/sc 2_2', true, ['Greetings everyone'] = true, ['Greetings Robloxians!'] = true, ['Seasons greetings!'] = true},
- ['Welcome'] = {'/sc 2_3', true, ['Welcome to my place'] = true, ['Welcome to my barbeque'] = true, ['Welcome to our base'] = true},
- ['Hey there!'] = {'/sc 2_4', true},
- ['What\'s up?'] = {'/sc 2_5', true, ['How are you doing?'] = true, ['How\'s it going?'] = true, ['What\'s new?'] = true},
- ['Good day'] = {'/sc 2_6', true, ['Good morning'] = true, ['Good evening'] = true, ['Good afternoon'] = true, ['Good night'] = true},
- ['Silly'] = {'/sc 2_7', true, ['Waaaaaaaz up?!'] = true, ['Hullo!'] = true, ['Behold greatness, mortals!'] = true, ['Pardon me, is this Sparta?'] = true, ['THIS IS SPARTAAAA!'] = true},
- ['Happy Holidays!'] = {'/sc 2_8', true, ['Happy New Year!'] = true,
- ['Happy Valentine\'s Day!'] = true,
- ['Beware the Ides of March!'] = true,
- ['Happy St. Patrick\'s Day!'] = true,
- ['Happy Easter!'] = true,
- ['Happy Earth Day!'] = true,
- ['Happy 4th of July!'] = true,
- ['Happy Thanksgiving!'] = true,
- ['Happy Halloween!'] = true,
- ['Happy Hanukkah!'] = true,
- ['Merry Christmas!'] = true,
- ['Happy Halloween!'] = true,
- ['Happy Earth Day!'] = true,
- ['Happy May Day!'] = true,
- ['Happy Towel Day!'] = true,
- ['Happy ROBLOX Day!'] = true,
- ['Happy LOL Day!'] = true },
- [1] = '/sc 2'
- },
- ['Goodbye'] = {
- ['Good Night']= {'/sc 3_0', true,
- ['Sweet dreams'] = true,
- ['Go to sleep!'] = true,
- ['Lights out!'] = true,
- ['Bedtime'] = true,
- ['Going to bed now'] = true},
- ['Later']= {'/sc 3_1', true,
- ['See ya later'] = true,
- ['Later gator!'] = true,
- ['See you tomorrow'] = true},
- ['Bye'] = {'/sc 3_2', true, ['Hasta la bye bye!'] = true},
- ['I\'ll be right back'] = {'/sc 3_3', true},
- ['I have to go'] = {'/sc 3_4', true},
- ['Farewell'] = {'/sc 3_5', true, ['Take care'] = true, ['Have a nice day'] = true, ['Goodluck!'] = true, ['Ta-ta for now!'] = true},
- ['Peace'] = {'/sc 3_6', true, ['Peace out!'] = true, ['Peace dudes!'] = true, ['Rest in pieces!'] = true},
- ['Silly'] = {'/sc 3_7', true,
- ['To the batcave!'] = true,
- ['Over and out!'] = true,
- ['Happy trails!'] = true,
- ['I\'ve got to book it!'] = true,
- ['Tootles!'] = true,
- ['Smell you later!'] = true,
- ['GG!'] = true,
- ['My house is on fire! gtg.'] = true},
- [1] = '/sc 3'
- },
- ['Friend'] ={
- ['Wanna be friends?'] = {'/sc 4_0', true},
- ['Follow me'] = {'/sc 4_1', true, ['Come to my place!'] = true, ['Come to my base!'] = true, ['Follow me, team!'] = true, ['Follow me'] = true},
- ['Your place is cool'] = {'/sc 4_2', true, ['Your place is fun'] = true, ['Your place is awesome'] = true, ['Your place looks good'] = true, ['This place is awesome!'] = true},
- ['Thank you'] = {'/sc 4_3', true, ['Thanks for playing'] = true, ['Thanks for visiting'] = true, ['Thanks for everything'] = true, ['No, thank you'] = true, ['Thanx'] = true},
- ['No problem'] = {'/sc 4_4', true, ['Don\'t worry'] = true, ['That\'s ok'] = true, ['np'] = true},
- ['You are ...'] = {'/sc 4_5', true,
- ['You are great!'] = true,
- ['You are good!'] = true,
- ['You are cool!'] = true,
- ['You are funny!'] = true,
- ['You are silly!'] = true,
- ['You are awesome!'] = true,
- ['You are doing something I don\'t like, please stop'] = true
- },
- ['I like ...'] = {'/sc 4_6', true, ['I like your name'] = true, ['I like your shirt'] = true, ['I like your place'] = true, ['I like your style'] = true,
- ['I like you'] = true, ['I like items'] = true, ['I like money'] = true},
- ['Sorry'] = {'/sc 4_7', true, ['My bad!'] = true, ['I\'m sorry'] = true, ['Whoops!'] = true, ['Please forgive me.'] = true, ['I forgive you.'] = true,
- ['I didn\'t mean to do that.'] = true, ['Sorry, I\'ll stop now.'] = true},
- [1] = '/sc 4'
- },
- ['Questions'] = {
- ['Who?'] = {'/sc 5_0', true, ['Who wants to be my friend?'] = true, ['Who wants to be on my team?'] = true, ['Who made this brilliant game?'] = true},
- ['What?'] = {'/sc 5_1', true, ['What is your favorite animal?'] = true, ['What is your favorite game?'] = true, ['What is your favorite movie?'] = true,
- ['What is your favorite TV show?'] = true, ['What is your favorite music?'] = true, ['What are your hobbies?'] = true, ['LOLWUT?'] = true},
- ['When?'] = {'/sc 5_2', true, ['When are you online?'] = true, ['When is the new version coming out?'] = true, ['When can we play again?'] = true, ['When will your place be done?'] = true},
- ['Where?'] = {'/sc 5_3', true, ['Where do you want to go?'] = true, ['Where are you going?'] = true, ['Where am I?!'] = true, ['Where did you go?'] = true},
- ['How?'] = {'/sc 5_4', true, ['How are you today?'] = true, ['How did you make this cool place?'] = true, ['LOLHOW?'] = true},
- ['Can I...'] = {'/sc 5_5', true, ['Can I have a tour?'] = true, ['Can I be on your team?'] = true, ['Can I be your friend?'] = true, ['Can I try something?'] = true,
- ['Can I have that please?'] = true, ['Can I have that back please?'] = true, ['Can I have borrow your hat?'] = true, ['Can I have borrow your gear?'] = true},
- [1] = '/sc 5'
- },
- ['Answers'] = {
- ['You need help?'] = {'/sc 6_0', true, ['Check out the news section'] = true, ['Check out the help section'] = true, ['Read the wiki!'] = true,
- ['All the answers are in the wiki!'] = true, ['I will help you with this.'] = true},
- ['Some people ...'] = {'/sc 6_1', true, ['Me'] = true, ['Not me'] = true, ['You'] = true, ['All of us'] = true, ['Everyone but you'] = true, ['Builderman!'] = true,
- ['Telamon!'] = true, ['My team'] = true, ['My group'] = true, ['Mom'] = true, ['Dad'] = true, ['Sister'] = true, ['Brother'] = true, ['Cousin'] = true,
- ['Grandparent'] = true, ['Friend'] = true},
- ['Time ...'] = {'/sc 6_2', true, ['In the morning'] = true, ['In the afternoon'] = true, ['At night'] = true, ['Tomorrow'] = true, ['This week'] = true, ['This month'] = true,
- ['Sometime'] = true, ['Sometimes'] = true, ['Whenever you want'] = true, ['Never'] = true, ['After this'] = true, ['In 10 minutes'] = true, ['In a couple hours'] = true,
- ['In a couple days'] = true},
- ['Animals'] = {'/sc 6_3', true,
- ['Cats'] = {['Lion'] = true, ['Tiger'] = true, ['Leopard'] = true, ['Cheetah'] = true},
- ['Dogs'] = {['Wolves'] = true, ['Beagle'] = true, ['Collie'] = true, ['Dalmatian'] = true, ['Poodle'] = true, ['Spaniel'] = true,
- ['Shepherd'] = true, ['Terrier'] = true, ['Retriever'] = true},
- ['Horses'] = {['Ponies'] = true, ['Stallions'] = true, ['Pwnyz'] = true},
- ['Reptiles'] = {['Dinosaurs'] = true, ['Lizards'] = true, ['Snakes'] = true, ['Turtles!'] = true},
- ['Hamster'] = true,
- ['Monkey'] = true,
- ['Bears'] = true,
- ['Fish'] = {['Goldfish'] = true, ['Sharks'] = true, ['Sea Bass'] = true, ['Halibut'] = true, ['Tropical Fish'] = true},
- ['Birds'] = {['Eagles'] = true, ['Penguins'] = true, ['Parakeets'] = true, ['Owls'] = true, ['Hawks'] = true, ['Pidgeons'] = true},
- ['Elephants'] = true,
- ['Mythical Beasts'] = {['Dragons'] = true, ['Unicorns'] = true, ['Sea Serpents'] = true, ['Sphinx'] = true, ['Cyclops'] = true,
- ['Minotaurs'] = true, ['Goblins'] = true, ['Honest Politicians'] = true, ['Ghosts'] = true, ['Scylla and Charybdis'] = true}
- },
- ['Games'] = {'/sc 6_4', true,
- ['Action'] = true, ['Puzzle'] = true, ['Strategy'] = true, ['Racing'] = true, ['RPG'] = true, ['Obstacle Course'] = true, ['Tycoon'] = true,
- ['Roblox'] = { ['BrickBattle'] = true, ['Community Building'] = true, ['Roblox Minigames'] = true, ['Contest Place'] = true},
- ['Board games'] = { ['Chess'] = true, ['Checkers'] = true, ['Settlers of Catan'] = true, ['Tigris and Euphrates'] = true, ['El Grande'] = true,
- ['Stratego'] = true, ['Carcassonne'] = true}
- },
- ['Sports'] = {'/sc 6_5', true, ['Hockey'] = true, ['Soccer'] = true, ['Football'] = true, ['Baseball'] = true, ['Basketball'] = true,
- ['Volleyball'] = true, ['Tennis'] = true, ['Sports team practice'] = true,
- ['Watersports'] = { ['Surfing'] = true,['Swimming'] = true, ['Water Polo'] = true},
- ['Winter sports'] = { ['Skiing'] = true, ['Snowboarding'] = true, ['Sledding'] = true, ['Skating'] = true},
- ['Adventure'] = {['Rock climbing'] = true, ['Hiking'] = true, ['Fishing'] = true, ['Horseback riding'] = true},
- ['Wacky'] = {['Foosball'] = true, ['Calvinball'] = true, ['Croquet'] = true, ['Cricket'] = true, ['Dodgeball'] = true,
- ['Squash'] = true, ['Trampoline'] = true}
- },
- ['Movies/TV'] = {'/sc 6_6', true, ['Science Fiction'] = true, ['Animated'] = {['Anime'] = true}, ['Comedy'] = true, ['Romantic'] = true,
- ['Action'] = true, ['Fantasy'] = true},
- ['Music'] = {'/sc 6_7', true, ['Country'] = true, ['Jazz'] = true, ['Rap'] = true, ['Hip-hop'] = true, ['Techno'] = true, ['Classical'] = true,
- ['Pop'] = true, ['Rock'] = true},
- ['Hobbies'] = {'/sc 6_8', true,
- ['Computers'] = { ['Building computers'] = true, ['Videogames'] = true, ['Coding'] = true, ['Hacking'] = true},
- ['The Internet'] = { ['lol. teh internets!'] = true, ['Watching vids'] = true},
- ['Dance'] = true, ['Gymnastics'] = true, ['Listening to music'] = true, ['Arts and crafts'] = true,
- ['Martial Arts'] = {['Karate'] = true, ['Judo'] = true, ['Taikwon Do'] = true, ['Wushu'] = true, ['Street fighting'] = true},
- ['Music lessons'] = {['Playing in my band'] = true, ['Playing piano'] = true, ['Playing guitar'] = true,
- ['Playing violin'] = true, ['Playing drums'] = true, ['Playing a weird instrument'] = true}
- },
- ['Location'] = {'/sc 6_9', true,
- ['USA'] = {
- ['West'] = { ['Alaska'] = true, ['Arizona'] = true, ['California'] = true, ['Colorado'] = true, ['Hawaii'] = true,
- ['Idaho'] = true, ['Montana'] = true, ['Nevada'] = true, ['New Mexico'] = true, ['Oregon'] = true,
- ['Utah'] = true, ['Washington'] = true, ['Wyoming'] = true
- },
- ['South'] = { ['Alabama'] = true, ['Arkansas'] = true, ['Florida'] = true, ['Georgia'] = true, ['Kentucky'] = true,
- ['Louisiana'] = true, ['Mississippi'] = true, ['North Carolina'] = true, ['Oklahoma'] = true,
- ['South Carolina'] = true, ['Tennessee'] = true, ['Texas'] = true, ['Virginia'] = true, ['West Virginia'] = true
- },
- ['Northeast'] = {['Connecticut'] = true, ['Delaware'] = true, ['Maine'] = true, ['Maryland'] = true, ['Massachusetts'] = true,
- ['New Hampshire'] = true, ['New Jersey'] = true, ['New York'] = true, ['Pennsylvania'] = true, ['Rhode Island'] = true,
- ['Vermont'] = true
- },
- ['Midwest'] = {['Illinois'] = true, ['Indiana'] = true, ['Iowa'] = true, ['Kansas'] = true, ['Michigan'] = true, ['Minnesota'] = true,
- ['Missouri'] = true, ['Nebraska'] = true, ['North Dakota'] = true, ['Ohio'] = true, ['South Dakota'] = true, ['Wisconsin'] = true}
- },
- ['Canada'] = {['Alberta'] = true, ['British Columbia'] = true, ['Manitoba'] = true, ['New Brunswick'] = true, ['Newfoundland'] = true,
- ['Northwest Territories'] = true, ['Nova Scotia'] = true, ['Nunavut'] = true, ['Ontario'] = true, ['Prince Edward Island'] = true,
- ['Quebec'] = true, ['Saskatchewan'] = true, ['Yukon'] = true},
- ['Mexico'] = true,
- ['Central America'] = true,
- ['Europe'] = {['France'] = true, ['Germany'] = true, ['Spain'] = true, ['Italy'] = true, ['Poland'] = true, ['Switzerland'] = true,
- ['Greece'] = true, ['Romania'] = true, ['Netherlands'] = true,
- ['Great Britain'] = {['England'] = true, ['Scotland'] = true, ['Wales'] = true, ['Northern Ireland'] = true}
- },
- ['Asia'] = { ['China'] = true, ['India'] = true, ['Japan'] = true, ['Korea'] = true, ['Russia'] = true, ['Vietnam'] = true},
- ['South America'] = { ['Argentina'] = true, ['Brazil'] = true},
- ['Africa'] = { ['Eygpt'] = true, ['Swaziland'] = true},
- ['Australia'] = true, ['Middle East'] = true, ['Antarctica'] = true, ['New Zealand'] = true
- },
- ['Age'] = {'/sc 6_10', true, ['Rugrat'] = true, ['Kid'] = true, ['Tween'] = true, ['Teen'] = true, ['Twenties'] = true,
- ['Old'] = true, ['Ancient'] = true, ['Mesozoic'] = true, ['I don\'t want to say my age. Don\'t ask.'] = true},
- ['Mood'] = {'/sc 6_11', true, ['Good'] = true, ['Great!'] = true, ['Not bad'] = true, ['Sad'] = true, ['Hyper'] = true,
- ['Chill'] = true, ['Happy'] = true, ['Kind of mad'] = true},
- ['Boy'] = {'/sc 6_12', true},
- ['Girl'] = {'/sc 6_13', true},
- ['I don\'t want to say boy or girl. Don\'t ask.'] = {'/sc 6_14', true},
- [1] = '/sc 6'
- },
- ['Game'] = {
- ['Let\'s build'] = {'/sc 7_0', true},
- ['Let\'s battle'] = {'/sc 7_1', true},
- ['Nice one!'] = {'/sc 7_2', true},
- ['So far so good'] = {'/sc 7_3', true},
- ['Lucky shot!'] = {'/sc 7_4', true},
- ['Oh man!'] = {'/sc 7_5', true},
- ['I challenge you to a fight!'] = {'/sc 7_6', true},
- ['Help me with this'] = {'/sc 7_7', true},
- ['Let\'s go to your game'] = {'/sc 7_8', true},
- ['Can you show me how do to that?'] = {'/sc 7_9', true},
- ['Backflip!'] = {'/sc 7_10', true},
- ['Frontflip!'] = {'/sc 7_11', true},
- ['Dance!'] = {'/sc 7_12', true},
- ['I\'m on your side!'] = {'/sc 7_13', true},
- ['Game Commands'] = {'/sc 7_14', true, ['regen'] = true, ['reset'] = true, ['go'] = true, ['fix'] = true, ['respawn'] = true},
- [1] = '/sc 7'
- };
- ['Silly'] = {
- ['Muahahahaha!'] = true,
- ['all your base are belong to me!'] = true,
- ['GET OFF MAH LAWN'] = true,
- ['TEH EPIK DUCK IS COMING!!!'] = true,
- ['ROFL'] = true,
- ['1337'] = {true, ['i r teh pwnz0r!'] = true, ['w00t!'] = true, ['z0mg h4x!'] = true, ['ub3rR0xXorzage!'] = true}
- },
- ['Yes'] = {
- ['Absolutely!'] = true,
- ['Rock on!'] = true,
- ['Totally!'] = true,
- ['Juice!'] = true,
- ['Yay!'] = true,
- ['Yesh'] = true
- },
- ['No'] = {
- ['Ummm. No.'] = true,
- ['...'] = true,
- ['Stop!'] = true,
- ['Go away!'] = true,
- ['Don\'t do that'] = true,
- ['Stop breaking the rules'] = true,
- ['I don\'t want to'] = true
- },
- ['Ok'] = {
- ['Well... ok'] = true,
- ['Sure'] = true
- },
- ['Uncertain'] = {
- ['Maybe'] = true,
- ['I don\'t know'] = true,
- ['idk'] = true,
- ['I can\'t decide'] = true,
- ['Hmm...'] = true
- },
- [':-)'] = {
- [':-('] = true,
- [':D'] = true,
- [':-O'] = true,
- ['lol'] = true,
- ['=D'] = true,
- ['D='] = true,
- ['XD'] = true,
- [';D'] = true,
- [';)'] = true,
- ['O_O'] = true,
- ['=)'] = true,
- ['@_@'] = true,
- ['>_<'] = true,
- ['T_T'] = true,
- ['^_^'] = true,
- ['<(0_0<) <(0_0)> (>0_0)> KIRBY DANCE'] = true,
- [')\';'] = true,
- [':3'] = true
- },
- ['Ratings'] = {
- ['Rate it!'] = true,
- ['I give it a 1 out of 10'] = true,
- ['I give it a 2 out of 10'] = true,
- ['I give it a 3 out of 10'] = true,
- ['I give it a 4 out of 10'] = true,
- ['I give it a 5 out of 10'] = true,
- ['I give it a 6 out of 10'] = true,
- ['I give it a 7 out of 10'] = true,
- ['I give it a 8 out of 10'] = true,
- ['I give it a 9 out of 10'] = true,
- ['I give it a 10 out of 10!'] = true,
- }
- },
- CreateEnum('SafeChat'){'Level1', 'Level2', 'Level3'},
- SafeChatTree = {},
- TempSpaceLabel = nil
- }
- ---------------------------------------------------
- local function GetNameValue(pName)
- local value = 0
- for index = 1, #pName do
- local cValue = string.byte(string.sub(pName, index, index))
- local reverseIndex = #pName - index + 1
- if #pName%2 == 1 then
- reverseIndex = reverseIndex - 1
- end
- if reverseIndex%4 >= 2 then
- cValue = -cValue
- end
- value = value + cValue
- end
- return value%8
- end
- function Chat:ComputeChatColor(pName)
- if export.NameColorDependsOnChatColor then
- return PLAYERLIST_CHATCOLORS[pName:lower()] or self.ChatColors[GetNameValue(pName) + 1].Color
- else
- return self.ChatColors[GetNameValue(pName) + 1].Color
- end
- end
- -- This is context based scrolling
- function Chat:EnableScrolling(toggle)
- -- Genius idea gone to fail, if we switch the camera type we can effectively lock the
- -- camera and do no click scrolling
- self.MouseOnFrame = false
- if self.RenderFrame then
- self.RenderFrame.MouseEnter:connect(function()
- local character = Player.Character
- local torso = WaitForChild(character, 'Torso')
- local humanoid = WaitForChild(character, 'Humanoid')
- local head = WaitForChild(character, 'Head')
- if toggle then
- self.MouseOnFrame = true
- Camera.CameraType = 'Scriptable'
- -- Get relative position of camera and keep to it
- Spawn(function()
- local currentRelativePos = Camera.CoordinateFrame.p - torso.Position
- while Chat.MouseOnFrame do
- Camera.CoordinateFrame = CFrame.new(torso.Position + currentRelativePos, head.Position)
- wait(0.015)
- end
- end)
- end
- end)
- self.RenderFrame.MouseLeave:connect(function()
- Camera.CameraType = 'Custom'
- self.MouseOnFrame = false
- end)
- end
- end
- -- TODO: Scrolling using Mouse wheel
- function Chat:OnScroll(speed)
- if self.MouseOnFrame then
- --
- end
- end
- -- Check if we are running on a touch device
- function Chat:IsTouchDevice()
- local touchEnabled = false
- pcall(function() touchEnabled = Game:GetService('UserInputService').TouchEnabled end)
- return touchEnabled
- end
- -- Scrolling
- function Chat:ScrollQueue(value)
- --[[for i = 1, #self.MessageQueue do
- if self.MessageQueue[i] then
- for _, label in pairs(self.MessageQueue[i]) do
- local next = self.MessageQueue[i].Next
- local previous = self.MessageQueue[i].Previous
- if label and label:IsA('TextLabel') or label:IsA('TextButton') then
- if value > 0 and previous and previous['Message'] then
- label.Position = previous['Message'].Position
- elseif value < 1 and next['Message'] then
- label.Position = previous['Message'].Position
- end
- end
- end
- end
- end ]]
- end
- -- Handles the rendering of the text objects in their appropriate places
- function Chat:UpdateQueue(field, diff)
- -- Have to do some sort of correction here
- for i = #self.MessageQueue, 1, -1 do
- if self.MessageQueue[i] then
- for _, label in pairs(self.MessageQueue[i]) do
- if label and type(label) ~= 'table' and type(label) ~= 'number' then
- if label:IsA('TextLabel') or label:IsA('TextButton') then
- if diff then
- label.Position = label.Position - UDim2.new(0, 0, diff, 0)
- else
- if field == self.MessageQueue[i] then
- label.Position = UDim2.new(self.Configuration.XScale, 0, label.Position.Y.Scale - field['Message'].Size.Y.Scale , 0)
- -- Just to show up popping effect for the latest message in chat
- coroutine.resume(coroutine.create(function()
- wait(0.05)
- local t = 0.1
- local start = tick()
- while tick() - start < t do
- local alpha = (tick() - start) / t
- label.TextTransparency = 1-alpha
- wait()
- end
- label.TextTransparency = 0
- if label == field['Message'] then
- label.TextStrokeTransparency = StrokeTransparency
- else
- label.TextStrokeTransparency = StrokeTransparency
- end
- end))
- else
- label.Position = UDim2.new(self.Configuration.XScale, 0, label.Position.Y.Scale - field['Message'].Size.Y.Scale, 0)
- end
- if label.Position.Y.Scale < -0.01 then
- -- NOTE: Remove this fix when Textbounds is fixed
- label.Visible = false
- label:Destroy()
- end
- end
- end
- end
- end
- end
- end
- end
- function Chat:CreateScrollBar()
- -- Code for scrolling is in here, partially, but scroll bar drawing isn't drawn
- -- TODO: Implement
- end
- -- For scrolling, to see if we hit the bounds so that we can stop it from scrolling anymore
- function Chat:CheckIfInBounds(value)
- if #Chat.MessageQueue < 3 then
- return true
- end
- if value > 0 and Chat.MessageQueue[1] and Chat.MessageQueue[1]['Player'] and Chat.MessageQueue[1]['Player'].Position.Y.Scale == 0 then
- return true
- elseif value < 0 and Chat.MessageQueue[1] and Chat.MessageQueue[1]['Player'] and Chat.MessageQueue[1]['Player'].Position.Y.Scale < 0 then
- return true
- else
- return false
- end
- return false
- end
- -- This is to precompute all playerName space strings
- -- This is used to offset the message by exactly this + 2 spacestrings
- function Chat:ComputeSpaceString(pLabel)
- local nString = " "
- if not self.TempSpaceLabel then
- self.TempSpaceLabel = Gui.Create'TextButton'
- {
- Size = UDim2.new(0, pLabel.AbsoluteSize.X, 0, pLabel.AbsoluteSize.Y);
- FontSize = self.Configuration.FontSize;
- Parent = self.RenderFrame;
- BackgroundTransparency = 1.0;
- Text = nString;
- Name = 'SpaceButton'
- };
- else
- self.TempSpaceLabel.Text = nString
- end
- while self.TempSpaceLabel.TextBounds.X < pLabel.TextBounds.X do
- nString = nString .. " "
- self.TempSpaceLabel.Text = nString
- end
- nString = nString .. " "
- self.CachedSpaceStrings_List[pLabel.Text] = nString
- self.TempSpaceLabel.Text = ""
- return nString
- end
- -- When the playerChatted event fires
- -- The message is what the player chatted
- function Chat:UpdateChat(cPlayer, message)
- local messageField = {
- ['Player'] = cPlayer,
- ['Message'] = message
- }
- if Chat.MessageThread == nil or coroutine.status(Chat.MessageThread) == 'dead' then
- --Chat.Messages_List = {}
- table.insert(Chat.Messages_List, messageField)
- Chat.MessageThread = coroutine.create(function()
- for i = 1, #Chat.Messages_List do
- local field = Chat.Messages_List[i]
- Chat:CreateMessage(field['Player'], field['Message'])
- end
- Chat.Messages_List = {}
- end)
- coroutine.resume(Chat.MessageThread)
- else
- table.insert(Chat.Messages_List, messageField)
- end
- end
- function Chat:RecalculateSpacing()
- --[[for i = 1, #self.MessageQueue do
- local pLabel = self.MessageQueue[i]['Player']
- local mLabel = self.MessageQueue[i]['Message']
- local prevYScale = mLabel.Size.Y.Scale
- local prevText = mLabel.Text
- mLabel.Text = prevText
- local heightField = mLabel.TextBounds.Y
- mLabel.Size = UDim2.new(1, 0, heightField/self.RenderFrame.AbsoluteSize.Y, 0)
- pLabel.Size = mLabel.Size
- local diff = mLabel.Size.Y.Scale - prevYScale
- Chat:UpdateQueue(self.MessageQueue[i], diff)
- end ]]
- end
- function Chat:ApplyFilter(str)
- --[[for _, word in pair(self.Filter_List) do
- if string.find(str, word) then
- str:gsub(word, '@#$^')
- end
- end ]]
- end
- export.SendChat = function(self, name, message, custom_color, do_not_add_to_history)
- local old_color = PLAYERLIST_CHATCOLORS[name:lower()]
- if custom_color ~= nil then
- PLAYERLIST_CHATCOLORS[name:lower()] = custom_color
- end
- print(old_color, PLAYERLIST_CHATCOLORS[name:lower()])
- local player = game.Players:FindFirstChild(name) or {
- Name = name,
- Neutral = true,
- TeamColor = Color3.new(1,1,1)
- }
- Chat:CreateMessage(player, message, do_not_add_to_history)
- -- if do_not_add_to_history ~= true then
- -- AddToChatHistory(player, message)
- -- end
- wait()
- PLAYERLIST_CHATCOLORS[name:lower()] = old_color or nil
- end
- -- NOTE: Temporarily disabled ring buffer to allow for chat to always wrap around
- function Chat:CreateMessage(cPlayer, message, do_not_add_to_history)
- if do_not_add_to_history ~= true then
- AddToChatHistory(cPlayer, message)
- end
- local pName
- if not cPlayer then
- pName = ''
- else
- pName = cPlayer.Name
- end
- message = StringTrim(message)
- local pLabel
- local mLabel
- -- Our history stores upto 50 messages that is 100 textlabels
- -- If we ever hit the mark, which would be in every popular game btw
- -- we wrap around and reuse the labels
- if #self.MessageQueue > self.Configuration.HistoryLength then
- --[[pLabel = self.MessageQueue[#self.MessageQueue]['Player']
- mLabel = self.MessageQueue[#self.MessageQueue]['Message']
- pLabel.Text = pName .. ':'
- pLabel.Name = pName
- local pColor
- if cPlayer.Neutral then
- pLabel.TextColor3 = Chat:ComputeChatColor(pName)
- else
- pLabel.TextColor3 = cPlayer.TeamColor.Color
- end
- local nString
- if not self.CachedSpaceStrings_List[pName] then
- nString = Chat:ComputeSpaceString(pLabel)
- else
- nString = self.CachedSpaceStrings_List[pName]
- end
- mLabel.Text = ""
- mLabel.Name = pName .. " - message"
- mLabel.Text = nString .. message;
- mLabel.Parent = nil
- mLabel.Parent = self.RenderFrame
- mLabel.Position = UDim2.new(0, 0, 1, 0);
- pLabel.Position = UDim2.new(0, 0, 1, 0);]]
- -- Reinserted at the beginning, ring buffer
- self.MessageQueue[#self.MessageQueue] = nil
- end
- --else
- -- Haven't hit the mark yet, so keep creating
- pLabel = Gui.Create'TextLabel'
- {
- Name = pName;
- Text = (PLAYERLIST_ALIASES[pName:lower()] or pName) .. ":";
- TextColor3 = PLAYERLIST_CHATCOLORS[pName:lower()] or pColor;
- FontSize = Chat.Configuration.FontSize;
- TextXAlignment = Enum.TextXAlignment.Left;
- TextYAlignment = Enum.TextYAlignment.Top;
- Parent = self.RenderFrame;
- TextWrapped = false;
- Size = UDim2.new(1, 0, 0.1, 0);
- BackgroundTransparency = 1.0;
- TextTransparency = 1.0;
- Position = UDim2.new(0, 0, 1, 0);
- BorderSizePixel = 0.0;
- TextStrokeColor3 = Color3.new(0, 0, 0);
- TextStrokeTransparency = StrokeTransparency;
- --Active = false;
- };
- local pColor
- if cPlayer.Neutral then
- pLabel.TextColor3 = Chat:ComputeChatColor(pName)
- else
- pLabel.TextColor3 = cPlayer.TeamColor.Color
- end
- local nString
- if not self.CachedSpaceStrings_List[pName] then
- nString = Chat:ComputeSpaceString(pLabel)
- else
- nString = self.CachedSpaceStrings_List[pName]
- end
- mLabel = Gui.Create'TextLabel'
- {
- Name = pName .. ' - message';
- -- Max is 3 lines
- Size = UDim2.new(1, 0, 0.5, 0);
- TextColor3 = Chat.Configuration.MessageColor;
- FontSize = Chat.Configuration.FontSize;
- TextXAlignment = Enum.TextXAlignment.Left;
- TextYAlignment = Enum.TextYAlignment.Top;
- Text = ""; -- this is to stop when the engine reverts the swear words to default, which is button, ugh
- Parent = self.RenderFrame;
- TextWrapped = true;
- BackgroundTransparency = 1.0;
- TextTransparency = 1.0;
- Position = UDim2.new(0, 0, 1, 0);
- BorderSizePixel = 0.0;
- TextStrokeColor3 = Color3.new(0, 0, 0);
- --TextStrokeTransparency = 0.8;
- --Active = false;
- };
- mLabel.Text = nString .. message;
- if not pName then
- pLabel.Text = ''
- mLabel.TextColor3 = Color3.new(0, 0.4, 1.0)
- end
- --end
- if self.Admins_List[pName:lower()] then
- mLabel.TextColor3 = PLAYERLIST_CHATCOLORS[pName:lower()] or self.Configuration.AdminMessageColor
- end
- pLabel.Visible = true
- mLabel.Visible = true
- -- This will give beautiful multilines as well
- local heightField = mLabel.TextBounds.Y
- mLabel.Size = UDim2.new(1, 0, heightField/self.RenderFrame.AbsoluteSize.Y, 0)
- pLabel.Size = mLabel.Size
- local yPixels = self.RenderFrame.AbsoluteSize.Y
- local yFieldSize = mLabel.TextBounds.Y
- local queueField = {}
- queueField['Player'] = pLabel
- queueField['Message'] = mLabel
- queueField['SpawnTime'] = tick() -- Used for identifying when to make the message invisible
- table.insert(self.MessageQueue, 1, queueField)
- Chat:UpdateQueue(queueField)
- end
- function Chat:ScreenSizeChanged()
- wait()
- while self.Frame.AbsoluteSize.Y > 120 do
- self.Frame.Size = self.Frame.Size - UDim2.new(0, 0, 0.005, 0)
- end
- Chat:RecalculateSpacing()
- end
- function Chat:FindButtonTree(scButton, rootList)
- local list = {}
- rootList = rootList or self.SafeChatTree
- for button, _ in pairs(rootList) do
- if button == scButton then
- list = rootList[button]
- elseif type(rootList[button]) == 'table' then
- list = Chat:FindButtonTree(scButton, rootList[button])
- end
- end
- return list
- end
- function Chat:ToggleSafeChatMenu(scButton)
- local list = Chat:FindButtonTree(scButton, self.SafeChatTree)
- if list then
- for button, _ in pairs(list) do
- if button:IsA('TextButton') or button:IsA('ImageButton') then
- button.Visible = not button.Visible
- end
- end
- return true
- end
- return false
- end
- function Chat:CreateSafeChatOptions(list, rootButton)
- local text_List = {}
- level = level or 0
- local count = 0
- text_List[rootButton] = {}
- text_List[rootButton][1] = list[1]
- rootButton = rootButton or self.SafeChatButton
- for msg, _ in pairs(list) do
- if type(msg) == 'string' then
- local chatText = Gui.Create'TextButton'
- {
- Name = msg;
- Text = msg;
- Size = UDim2.new(0, 100, 0, 20);
- TextXAlignment = Enum.TextXAlignment.Center;
- TextColor3 = Color3.new(0.2, 0.1, 0.1);
- BackgroundTransparency = 0.5;
- BackgroundColor3 = Color3.new(1, 1, 1);
- Parent = self.SafeChatFrame;
- Visible = false;
- Position = UDim2.new(0, rootButton.Position.X.Scale + 105, 0, rootButton.Position.Y.Scale - ((count - 3) * 100));
- };
- count = count + 1
- if type(list[msg]) == 'table' then
- text_List[rootButton][chatText] = Chat:CreateSafeChatOptions(list[msg], chatText)
- else
- --table.insert(text_List[chatText], true)
- end
- chatText.MouseEnter:connect(function()
- Chat:ToggleSafeChatMenu(chatText)
- end)
- chatText.MouseLeave:connect(function()
- Chat:ToggleSafeChatMenu(chatText)
- end)
- chatText.MouseButton1Click:connect(function()
- local lList = Chat:FindButtonTree(chatText)
- if lList then
- for i, v in pairs(lList) do
- end
- else
- end
- pcall(function() PlayersService:Chat(lList[1]) end)
- end)
- end
- end
- return text_List
- end
- function Chat:CreateSafeChatGui()
- self.SafeChatFrame = Gui.Create'Frame'
- {
- Name = 'SafeChatFrame';
- Size = UDim2.new(1, 0, 1, 0);
- Parent = self.Gui;
- BackgroundTransparency = 1.0;
- Gui.Create'ImageButton'
- {
- Name = 'SafeChatButton';
- Size = UDim2.new(0, 44, 0, 31);
- Position = UDim2.new(0, 1, 0.35, 0);
- BackgroundTransparency = 1.0;
- Image = 'http://www.roblox.com/asset/?id=97080365';
- };
- }
- self.SafeChatButton = self.SafeChatFrame.SafeChatButton
- -- safe chat button is the root of this tree
- self.SafeChatTree[self.SafeChatButton] = Chat:CreateSafeChatOptions(self.SafeChat_List, self.SafeChatButton)
- self.SafeChatButton.MouseButton1Click:connect(function()
- Chat:ToggleSafeChatMenu(self.SafeChatButton)
- end)
- end
- function Chat:FocusOnChatBar()
- if self.ClickToChatButton then
- self.ClickToChatButton.Visible = false
- end
- self.GotFocus = true
- if self.Frame['Background'] then
- self.Frame.Background.Visible = false
- end
- self.ChatBar:CaptureFocus()
- end
- -- For touch devices we create a button instead
- function Chat:CreateTouchButton()
- self.ChatTouchFrame = Gui.Create'Frame'
- {
- Name = 'ChatTouchFrame';
- Size = UDim2.new(0, 128, 0, 32);
- Position = UDim2.new(0, 88, 0, 0);
- BackgroundTransparency = 1.0;
- Parent = self.Gui;
- Gui.Create'ImageButton'
- {
- Name = 'ChatLabel';
- Size = UDim2.new(0, 74, 0, 28);
- Position = UDim2.new(0, 0, 0, 0);
- BackgroundTransparency = 1.0;
- ZIndex = 2.0;
- };
- Gui.Create'ImageLabel'
- {
- Name = 'Background';
- Size = UDim2.new(1, 0, 1, 0);
- Position = UDim2.new(0, 0, 0, 0);
- BackgroundTransparency = 1.0;
- Image = 'http://www.roblox.com/asset/?id=97078724'
- };
- }
- self.TapToChatLabel = self.ChatTouchFrame.ChatLabel
- self.TouchLabelBackground = self.ChatTouchFrame.Background
- self.ChatBar = Gui.Create'TextBox'
- {
- Name = 'ChatBar';
- Size = UDim2.new(1, 0, 0.2, 0);
- Position = UDim2.new(0, 0, 0.8, 800);
- Text = "";
- ZIndex = 1.0;
- BackgroundTransparency = 1.0;
- Parent = self.Frame;
- TextXAlignment = Enum.TextXAlignment.Left;
- TextColor3 = Color3.new(1, 1, 1);
- ClearTextOnFocus = false;
- };
- self.TapToChatLabel.MouseButton1Click:connect(function()
- self.TapToChatLabel.Visible = false
- --self.ChatBar.Visible = true
- --self.Frame.Background.Visible = true
- self.ChatBar:CaptureFocus()
- self.GotFocus = true
- if self.TouchLabelBackground then
- self.TouchLabelBackground.Visible = false
- end
- end)
- end
- -- Non touch devices, create the bottom chat bar
- function Chat:CreateChatBar()
- -- okay now we do
- -- local status, result = pcall(function() return GuiService.UseLuaChat end)
- -- if forceChatGUI or (status and result) then
- -- self.ClickToChatButton = Gui.Create'TextButton'
- -- {
- -- Name = 'ClickToChat';
- -- Size = UDim2.new(1, 0, 0, 20);
- -- BackgroundTransparency = 1.0;
- -- ZIndex = 2.0;
- -- Parent = self.Gui;
- -- Text = "To chat click here or press \"/\" key";
- -- TextColor3 = Color3.new(1, 1, 0.9);
- -- Position = UDim2.new(0, 0, 1, 0);
- -- TextXAlignment = Enum.TextXAlignment.Left;
- -- FontSize = Enum.FontSize.Size12;
- -- }
- --
- -- self.ChatBar = Gui.Create'TextBox'
- -- {
- -- Name = 'ChatBar';
- -- Size = UDim2.new(1, 0, 0, 20);
- -- Position = UDim2.new(0, 0, 1, 0);
- -- Text = "";
- -- ZIndex = 1.0;
- -- BackgroundColor3 = Color3.new(0, 0, 0);
- -- BackgroundTransparency = 0.25;
- -- Parent = self.Gui;
- -- TextXAlignment = Enum.TextXAlignment.Left;
- -- TextColor3 = Color3.new(1, 1, 1);
- -- FontSize = Enum.FontSize.Size12;
- -- ClearTextOnFocus = false;
- -- Text = '';
- -- };
- --
- -- -- Engine has code to offset the entire world, so if we do it by -20 pixels nothing gets in our chat's way
- -- --GuiService:SetGlobalSizeOffsetPixel(0, -20)
- -- local success, error = pcall(function() GuiService:SetGlobalGuiInset(0, 0, 0, 20) end)
- -- if not success then
- -- GuiService:SetGlobalSizeOffsetPixel(0, -20)
- -- end
- -- -- CHatHotKey is '/'
- -- GuiService:AddSpecialKey(Enum.SpecialKey.ChatHotkey)
- -- GuiService.SpecialKeyPressed:connect(function(key)
- -- if key == Enum.SpecialKey.ChatHotkey then
- -- Chat:FocusOnChatBar()
- -- end
- -- end)
- --
- -- self.ClickToChatButton.MouseButton1Click:connect(function()
- -- Chat:FocusOnChatBar()
- -- end)
- -- end
- end
- -- Create the initial Chat stuff
- -- Done only once
- function Chat:CreateGui()
- self.Gui = script.Parent
- self.Frame = Gui.Create'Frame'
- {
- Name = 'ChatFrame';
- --Size = self.Configuration.Size;
- Size = UDim2.new(0, 500, 0, 120);
- Position = UDim2.new(0, 0, 0, 5);
- BackgroundTransparency = 1.0;
- --ClipsDescendants = true;
- ZIndex = 0.0;
- Parent = self.Gui;
- Active = false;
- Gui.Create'ImageLabel'
- {
- Name = 'Background';
- Image = 'http://www.roblox.com/asset/?id=97120937'; --96551212';
- Size = UDim2.new(1.3, 0, 1.64, 0);
- Position = UDim2.new(0, 0, 0, 0);
- BackgroundTransparency = 1.0;
- ZIndex = 0.0;
- Visible = false
- };
- Gui.Create'Frame'
- {
- Name = 'Border';
- Size = UDim2.new(1, 0, 0, 1);
- Position = UDim2.new(0, 0, 0.8, 0);
- BackgroundTransparency = 0.0;
- BackgroundColor3 = Color3.new(236/255, 236/255, 236/255);
- BorderSizePixel = 0.0;
- Visible = false;
- };
- Gui.Create'Frame'
- {
- Name = 'ChatRenderFrame';
- Size = UDim2.new(1.02, 0, 1.01, 0);
- Position = UDim2.new(0, 0, 0, 0);
- BackgroundTransparency = 1.0;
- --ClipsDescendants = true;
- ZIndex = 0.0;
- Active = false;
- };
- };
- Spawn(function()
- wait(0.5)
- if IsPhone() then
- self.Frame.Size = UDim2.new(0, 280, 0, 120)
- end
- end)
- self.RenderFrame = self.Frame.ChatRenderFrame
- if Chat:IsTouchDevice() then
- self.Frame.Position = self.Configuration.Position;
- self.RenderFrame.Size = UDim2.new(1, 0, 1, 0)
- elseif self.Frame.AbsoluteSize.Y > 120 then
- Chat:ScreenSizeChanged()
- self.Gui.Changed:connect(function(property)
- if property == 'AbsoluteSize' then
- Chat:ScreenSizeChanged()
- end
- end)
- end
- if forceChatGUI or true then
- if Chat:IsTouchDevice() then
- Chat:CreateTouchButton()
- else
- Chat:CreateChatBar()
- --Chat:CreateSafeChatGui()
- end
- if self.ChatBar then
- self.ChatBar.FocusLost:connect(function(enterPressed)
- Chat.GotFocus = false
- if Chat:IsTouchDevice() then
- self.ChatBar.Visible = false
- self.TapToChatLabel.Visible = true
- if self.TouchLabelBackground then
- self.TouchLabelBackground.Visible = true
- end
- end
- if enterPressed and self.ChatBar.Text ~= "" then
- local cText = self.ChatBar.Text
- if string.sub(self.ChatBar.Text, 1, 1) == '%' then
- cText = '(TEAM) ' .. string.sub(cText, 2, #cText)
- pcall(function() PlayersService:TeamChat(cText) end)
- else
- pcall(function() PlayersService:Chat(cText) end)
- end
- if self.ClickToChatButton then
- self.ClickToChatButton.Visible = true
- end
- self.ChatBar.Text = ""
- end
- Spawn(function()
- wait(5.0)
- if not Chat.GotFocus then
- Chat.Frame.Background.Visible = false
- end
- end)
- end)
- end
- end
- end
- -- Scrolling function
- -- Applies a speed(velocity) to have nice scrolling effect
- function Input:OnMouseScroll()
- Spawn(function()
- -- How long should the speed last?
- while Input.Speed ~=0 do
- if Input.Speed > 1 then
- while Input.Speed > 0 do
- Input.Speed = Input.Speed - 1
- wait(0.25)
- end
- elseif Input.Speed < 0 then
- while Input.Speed < 0 do
- Input.Speed = Input.Speed + 1
- wait(0.25)
- end
- end
- wait(0.03)
- end
- end)
- if Chat:CheckIfInBounds(Input.Speed) then
- return
- end
- Chat:ScrollQueue()
- end
- function Input:ApplySpeed(value)
- Input.Speed = Input.Speed + value
- if not self.Simulating then
- Input:OnMouseScroll()
- end
- end
- function Input:Initialize()
- self.Mouse.WheelBackward:connect(function()
- Input:ApplySpeed(self.Configuration.DefaultSpeed)
- end)
- self.Mouse.WheelForward:connect(function()
- Input:ApplySpeed(self.Configuration.DefaultSpeed)
- end)
- end
- function Chat:FindMessageInSafeChat(message, list)
- local foundMessage = false
- for msg, _ in pairs(list) do
- if msg == message then
- return true
- end
- if type(list[msg]) == 'table' then
- foundMessage = Chat:FindMessageInSafeChat(message, list[msg])
- if foundMessage then
- return true
- end
- end
- end
- return foundMessage
- end
- -- Just a wrapper around our PlayerChatted event
- function Chat:PlayerChatted(...)
- local args = {...}
- local argCount = select('#', ...)
- local player
- local message
- -- This doesn't look very good, but what else to do?
- if args[2] then
- player = args[2]
- end
- if args[3] then
- message = args[3]
- if string.sub(message, 1, 1) == '%' then
- message = '(TEAM) ' .. string.sub(message, 2, #message)
- end
- end
- -- if PlayersService.ClassicChat then
- if string.sub(message, 1, 3) == '/e ' or string.sub(message, 1, 7) == '/emote ' then
- -- don't do anything right now
- elseif forceChatGUI or true then
- Chat:UpdateChat(player, message)
- elseif true and string.sub(message, 1, 3) == '/sc' then
- Chat:UpdateChat(player, message)
- else
- if Chat:FindMessageInSafeChat(message, self.SafeChat_List) then
- Chat:UpdateChat(player, message)
- end
- end
- -- end
- end
- -- After Chat.Configuration.Lifetime seconds of existence, the labels become invisible
- -- Runs only every 5 seconds and has to loop through 50 values
- -- Shouldn't be too expensive
- function Chat:CullThread()
- while true do
- if #self.MessageQueue > 0 then
- for _, field in pairs(self.MessageQueue) do
- if field['SpawnTime'] and field['Player'] and field['Message'] and tick() - field['SpawnTime'] > self.Configuration.LifeTime then
- field['Player'].Visible = false
- field['Message'].Visible = false
- end
- end
- end
- wait(5.0)
- end
- end
- -- RobloxLock everything so users can't delete them(?)
- function Chat:LockAllFields(gui)
- local children = gui:GetChildren()
- for i = 1, #children do
- children[i].RobloxLocked = true
- if #children[i]:GetChildren() > 0 then
- Chat:LockAllFields(children[i])
- end
- end
- end
- function Chat:CoreGuiChanged(coreGuiType,enabled)
- if coreGuiType == Enum.CoreGuiType.Chat or coreGuiType == Enum.CoreGuiType.All then
- if self.Frame then self.Frame.Visible = enabled end
- if not Chat:IsTouchDevice() and self.ChatBar then
- self.ChatBar.Visible = enabled
- if enabled then
- GuiService:SetGlobalGuiInset(0, 0, 0, 20)
- else
- GuiService:SetGlobalGuiInset(0, 0, 0, 0)
- end
- end
- end
- end
- _G.ChatHistory = _G.ChatHistory or {}
- function RunChatHistory(max)
- for i=#_G.ChatHistory-max, #_G.ChatHistory do
- local player, message = unpack(_G.ChatHistory[i] or {})
- if player ~= nil and message ~= nil then
- export:SendChat(player.Name, message, nil, true)
- end
- end
- end
- function AddToChatHistory(player, message)
- table.insert(_G.ChatHistory, {player, message})
- end
- -- Constructor
- -- This function initializes everything
- function Chat:Initialize()
- Chat:CreateGui()
- function PlayerChatted(...)
- Chat:PlayerChatted(...)
- end
- function OnPlayer(p)
- if p:IsA 'Player' then
- p.Chatted:connect(function(chat)
- PlayerChatted(
- Enum.PlayerChatType.All,
- p,
- chat,
- nil
- )
- end)
- end
- end
- for _,p in pairs(game.Players:GetPlayers()) do
- OnPlayer(p)
- end
- game.Players.ChildAdded:connect(OnPlayer)
- self.EventListener = script.ChildAdded:connect(function(...)
- -- This event has 4 callback arguments
- -- Enum.PlayerChatType.All, chatPlayer, message, targetPlayer
- -- Chat:PlayerChatted(...)
- end)
- -- Initialize input for us
- -- Input:Initialize()
- -- Eww, everytime a player is added, you have to redo the connection
- -- Seems this is not automatic
- -- -- NOTE: PlayerAdded only fires on the server, hence ChildAdded is used here
- -- PlayersService.ChildAdded:connect(function()
- -- Chat.EventListener:disconnect()
- -- self.EventListener = PlayersService.PlayerChatted:connect(function(...)
- -- -- This event has 4 callback arguments
- -- -- Enum.PlayerChatType.All, chatPlayer, message, targetPlayer
- -- Chat:PlayerChatted(...)
- -- end)
- -- end)
- Spawn(function()
- Chat:CullThread()
- end)
- -- Chat:LockAllFields(self.Frame)
- -- self.Frame.DescendantAdded:connect(function(descendant)
- ---- Chat:LockAllFields(descendant)
- -- end)
- end
- Chat:Initialize()
- RunChatHistory(10)
- _G.ChatAPI = export
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement