1696 lines
40 KiB
Plaintext
1696 lines
40 KiB
Plaintext
import "macros" as { $ }
|
|
$load $FILE
|
|
|
|
--[[
|
|
//FileName: ChatScript.LUA
|
|
//Written by: Sorcus
|
|
//Description: Code for lua side chat on Mercury. Supports Scrolling.
|
|
//NOTE: If you find any bugs or inaccuracies PM Sorcus on Roblox or @Canavus on Twitter
|
|
]]
|
|
|
|
forceChatGUI = false
|
|
|
|
-- Utility functions + Globals
|
|
WaitForChild = (parent, childName) ->
|
|
until parent\FindFirstChild(childName)?
|
|
parent.ChildAdded\wait 0.03
|
|
|
|
parent[childName]
|
|
|
|
IsPhone = ->
|
|
cGui = Game\GetService "CoreGui"
|
|
rGui = WaitForChild cGui, "RobloxGui"
|
|
if rGui.AbsoluteSize.Y < 600
|
|
return true
|
|
false
|
|
|
|
-- 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
|
|
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
|
|
str\gsub "^%s*(.-)%s*$", "%1"
|
|
|
|
until Game.Players.LocalPlayer?
|
|
wait 0.03
|
|
|
|
Player = Game.Players.LocalPlayer
|
|
until Player.Character?
|
|
wait 0.03
|
|
|
|
Camera = Game.Workspace.CurrentCamera
|
|
|
|
-- Heliodex's basic New function (basically a simplified version of melt)
|
|
New = (className, name, props) ->
|
|
if not props? -- no name was provided
|
|
props = name
|
|
name = nil
|
|
|
|
obj = Instance.new className
|
|
obj.Name = name if name
|
|
local parent
|
|
|
|
for k, v in pairs props
|
|
if type(k) == "string"
|
|
if k == "Parent"
|
|
parent = v
|
|
else
|
|
obj[k] = v
|
|
|
|
elseif type(k) == "number" and type(v) == "userdata"
|
|
v.Parent = obj
|
|
|
|
obj.Parent = parent
|
|
obj
|
|
--
|
|
|
|
-- Services
|
|
CoreGuiService = Game\GetService "CoreGui"
|
|
PlayersService = Game\GetService "Players"
|
|
GuiService = Game\GetService "GuiService"
|
|
|
|
-- Lua Enums
|
|
Enums = {}
|
|
EnumName = {} -- used as unique key for enum name
|
|
CreateEnum = (enumName) ->
|
|
(t) ->
|
|
e = [EnumName]: enumName
|
|
for i, name in pairs t
|
|
item =
|
|
Name: name
|
|
Value: i
|
|
Enum: e
|
|
[EnumName]: enumName
|
|
|
|
<call>: (@, value) ->
|
|
value == @ or value == @Name or value == @Value
|
|
<tostring>: (@) ->
|
|
"Enum.#{@[EnumName]}.#{@Name}"
|
|
|
|
e[i] = e[name] = e[item] = item
|
|
|
|
Enums[enumName] = e
|
|
setmetatable e,
|
|
__call: (@, value) ->
|
|
@[value] or @[tonumber value]
|
|
|
|
__index:
|
|
GetEnumItems: (@) ->
|
|
t = {}
|
|
for i, item in pairs @
|
|
if type(i) == "number"
|
|
t[] = item
|
|
|
|
table.sort t, (a, b) -> a.Value < b.Value
|
|
t
|
|
__tostring: (@) ->
|
|
"Enum.#{@[EnumName]}"
|
|
|
|
---------------------------------------------------
|
|
------------------ Input class --------------------
|
|
Input =
|
|
Mouse: Player\GetMouse!
|
|
Speed: 0
|
|
Simulating: false
|
|
|
|
Configuration:
|
|
DefaultSpeed: 1
|
|
|
|
UserIsScrolling: false
|
|
|
|
---------------------------------------------------
|
|
------------------ Chat class --------------------
|
|
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 = {'Sorcus', 'Shedletsky', 'Telamon', 'Tarabyte', 'StickMasterLuke', 'OnlyTwentyCharacters', 'FusRoblox', 'SolarCrane',
|
|
'HotThoth', 'JediTkacheff', 'Builderman', 'Brighteyes', 'ReeseMcblox', 'GemLocker', 'GongfuTiger', 'Erik.Cassel', 'Matt Dusek', 'Keith',
|
|
'Totbl', 'LordRugDump', 'David.Baszucki', 'Dbapostle', 'DaveYorkRBX', 'nJay', 'OstrichSized', 'TobotRobot', 'twberg', 'Mercury', 'RBAdam', 'Doughtless',
|
|
'Anaminus', 'Stravant', 'Cr3470r', 'CodeWriter', 'Games', 'AcesWayUpHigh', 'Phil'
|
|
}, --]]
|
|
Admins_List:
|
|
* "taskmanager"
|
|
* "Heliodex"
|
|
* "tako"
|
|
|
|
SafeChat_List:
|
|
"Use the Chat menu to talk to me.":
|
|
* "/sc0"
|
|
* true
|
|
"I can only see menu chats.":
|
|
* "/sc1"
|
|
* true
|
|
Hello:
|
|
Hi:
|
|
* "/sc2_0"
|
|
* true
|
|
"Hi there!": true
|
|
"Hi everyone": true
|
|
|
|
Howdy:
|
|
* "/sc2_1"
|
|
* true
|
|
"Howdy partner!": true
|
|
|
|
Greetings:
|
|
* "/sc2_2"
|
|
* true
|
|
"Greetings everyone": true
|
|
"Greetings Robloxians!": true
|
|
"Seasons greetings!": true
|
|
|
|
Welcome:
|
|
* "/sc2_3"
|
|
* true
|
|
"Welcome to my place": true
|
|
"Welcome to my barbeque": true
|
|
"Welcome to our base": true
|
|
|
|
"Hey there!":
|
|
* "/sc2_4"
|
|
* true
|
|
"What's up?":
|
|
* "/sc2_5"
|
|
* true
|
|
"How are you doing?": true
|
|
"How's it going?": true
|
|
"What's new?": true
|
|
|
|
"Good day":
|
|
* "/sc2_6"
|
|
* true
|
|
"Good morning": true
|
|
"Good evening": true
|
|
"Good afternoon": true
|
|
"Good night": true
|
|
|
|
Silly:
|
|
* "/sc2_7"
|
|
* true
|
|
"Waaaaaaaz up?!": true
|
|
"Hullo!": true
|
|
"Behold greatness, mortals!": true
|
|
"Pardon me, is this Sparta?": true
|
|
"THIS IS SPARTAAAA!": true
|
|
|
|
"Happy Holidays!":
|
|
* "/sc2_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 May Day!": true
|
|
"Happy Towel Day!": true
|
|
"Happy Mercury Day!": true
|
|
"Happy LOL Day!": true
|
|
|
|
* "/sc2"
|
|
|
|
Goodbye:
|
|
"Good Night":
|
|
* "/sc3_0"
|
|
* true
|
|
"Sweet dreams": true
|
|
"Go to sleep!": true
|
|
"Lights out!": true
|
|
Bedtime: true
|
|
"Going to bed now": true
|
|
|
|
Later:
|
|
* "/sc3_1"
|
|
* true
|
|
"See ya later": true
|
|
"Later gator!": true
|
|
"See you tomorrow": true
|
|
|
|
Bye:
|
|
* "/sc3_2"
|
|
* true
|
|
"Hasta la bye bye!": true
|
|
|
|
"I'll be right back":
|
|
* "/sc3_3"
|
|
* true
|
|
"I have to go":
|
|
* "/sc3_4"
|
|
* true
|
|
|
|
Farewell:
|
|
* "/sc3_5"
|
|
* true
|
|
"Take care": true
|
|
"Have a nice day": true
|
|
"Goodluck!": true
|
|
"Ta-ta for now!": true
|
|
|
|
Peace:
|
|
* "/sc3_6"
|
|
* true
|
|
"Peace out!": true
|
|
"Peace dudes!": true
|
|
"Rest in pieces!": true
|
|
|
|
Silly:
|
|
* "/sc3_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
|
|
|
|
* "/sc3"
|
|
|
|
Friend:
|
|
"Wanna be friends?":
|
|
* "/sc4_0"
|
|
* true
|
|
"Follow me":
|
|
* "/sc4_1"
|
|
* true
|
|
"Come to my place!": true
|
|
"Come to my base!": true
|
|
"Follow me, team!": true
|
|
"Follow me": true
|
|
|
|
"Your place is cool":
|
|
* "/sc4_2"
|
|
* true
|
|
"Your place is fun": true
|
|
"Your place is awesome": true
|
|
"Your place looks good": true
|
|
"This place is awesome!": true
|
|
|
|
"Thank you":
|
|
* "/sc4_3"
|
|
* true
|
|
"Thanks for playing": true
|
|
"Thanks for visiting": true
|
|
"Thanks for everything": true
|
|
"No, thank you": true
|
|
Thanx: true
|
|
|
|
"No problem":
|
|
* "/sc4_4"
|
|
* true
|
|
"Don't worry": true
|
|
"That's ok": true
|
|
np: true
|
|
|
|
"You are ...":
|
|
* "/sc4_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 ...":
|
|
* "/sc4_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:
|
|
* "/sc4_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
|
|
|
|
* "/sc4"
|
|
|
|
Questions:
|
|
"Who?":
|
|
* "/sc5_0"
|
|
* true
|
|
"Who wants to be my friend?": true
|
|
"Who wants to be on my team?": true
|
|
"Who made this brilliant game?": true
|
|
|
|
"What?":
|
|
* "/sc5_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?":
|
|
* "/sc5_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?":
|
|
* "/sc5_3"
|
|
* true
|
|
"Where do you want to go?": true
|
|
"Where are you going?": true
|
|
"Where am I?!": true
|
|
"Where did you go?": true
|
|
|
|
"How?":
|
|
* "/sc5_4"
|
|
* true
|
|
"How are you today?": true
|
|
"How did you make this cool place?": true
|
|
"LOLHOW?": true
|
|
|
|
"Can I...":
|
|
* "/sc5_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
|
|
|
|
* "/sc5"
|
|
|
|
Answers:
|
|
"You need help?":
|
|
* "/sc6_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 ...":
|
|
* "/sc6_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 ...":
|
|
* "/sc6_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:
|
|
* "/sc6_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:
|
|
* "/sc6_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:
|
|
* "/sc6_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":
|
|
* "/sc6_6"
|
|
* true
|
|
"Science Fiction": true
|
|
Animated:
|
|
Anime: true
|
|
Comedy: true
|
|
Romantic: true
|
|
Action: true
|
|
Fantasy: true
|
|
|
|
Music:
|
|
* "/sc6_7"
|
|
* true
|
|
Country: true
|
|
Jazz: true
|
|
Rap: true
|
|
"Hip-hop": true
|
|
Techno: true
|
|
Classical: true
|
|
Pop: true
|
|
Rock: true
|
|
|
|
Hobbies:
|
|
* "/sc6_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:
|
|
* "/sc6_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:
|
|
* "/sc6_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:
|
|
* "/sc6_11"
|
|
* true
|
|
Good: true
|
|
"Great!": true
|
|
"Not bad": true
|
|
Sad: true
|
|
Hyper: true
|
|
Chill: true
|
|
Happy: true
|
|
"Kind of mad": true
|
|
|
|
Boy:
|
|
* "/sc6_12"
|
|
* true
|
|
Girl:
|
|
* "/sc6_13"
|
|
* true
|
|
"I don't want to say boy or girl. Don't ask.":
|
|
* "/sc6_14"
|
|
* true
|
|
|
|
* "/sc6"
|
|
|
|
Game:
|
|
"Let's build":
|
|
* "/sc7_0"
|
|
* true
|
|
"Let's battle":
|
|
* "/sc7_1"
|
|
* true
|
|
"Nice one!":
|
|
* "/sc7_2"
|
|
* true
|
|
"So far so good":
|
|
* "/sc7_3"
|
|
* true
|
|
"Lucky shot!":
|
|
* "/sc7_4"
|
|
* true
|
|
"Oh man!":
|
|
* "/sc7_5"
|
|
* true
|
|
"I challenge you to a fight!":
|
|
* "/sc7_6"
|
|
* true
|
|
"Help me with this":
|
|
* "/sc7_7"
|
|
* true
|
|
"Let's go to your game":
|
|
* "/sc7_8"
|
|
* true
|
|
"Can you show me how do to that?":
|
|
* "/sc7_9"
|
|
* true
|
|
"Backflip!":
|
|
* "/sc7_10"
|
|
* true
|
|
"Frontflip!":
|
|
* "/sc7_11"
|
|
* true
|
|
"Dance!":
|
|
* "/sc7_12"
|
|
* true
|
|
"I'm on your side!":
|
|
* "/sc7_13"
|
|
* true
|
|
"Game Commands":
|
|
* "/sc7_14"
|
|
* true
|
|
regen: true
|
|
reset: true
|
|
go: true
|
|
fix: true
|
|
respawn: true
|
|
|
|
* "/sc7"
|
|
|
|
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
|
|
---------------------------------------------------
|
|
|
|
---------------------------------------------------
|
|
|
|
GetNameValue = (pName) ->
|
|
value = 0
|
|
for index = 1, #pName
|
|
cValue = string.byte string.sub pName, index, index
|
|
reverseIndex = #pName - index + 1
|
|
if #pName % 2 == 1
|
|
reverseIndex = reverseIndex - 1
|
|
if reverseIndex % 4 >= 2
|
|
cValue = -cValue
|
|
value = value + cValue
|
|
value % 8
|
|
|
|
Chat.ComputeChatColor = (pName) =>
|
|
@ChatColors[GetNameValue(pName) + 1].Color
|
|
|
|
-- This is context based scrolling
|
|
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
|
|
@MouseOnFrame = false
|
|
if @RenderFrame
|
|
@RenderFrame.MouseEnter\connect ->
|
|
character = Player.Character
|
|
torso = WaitForChild character, "Torso"
|
|
head = WaitForChild character, "Head"
|
|
if toggle
|
|
@MouseOnFrame = true
|
|
Camera.CameraType = "Scriptable"
|
|
-- Get relative position of camera and keep to it
|
|
Spawn ->
|
|
currentRelativePos = Camera.CoordinateFrame.p - torso.Position
|
|
while Chat.MouseOnFrame
|
|
Camera.CoordinateFrame = CFrame.new torso.Position + currentRelativePos, head.Position
|
|
wait 0.015
|
|
|
|
@RenderFrame.MouseLeave\connect ->
|
|
Camera.CameraType = "Custom"
|
|
@MouseOnFrame = false
|
|
|
|
-- TODO: Scrolling using Mouse wheel
|
|
-- Chat.OnScroll = (speed) =>
|
|
-- if @MouseOnFrame
|
|
-- --
|
|
-- end
|
|
-- end
|
|
|
|
-- Check if we are running on a touch device
|
|
Chat.IsTouchDevice ==>
|
|
touchEnabled = false
|
|
try
|
|
touchEnabled = Game\GetService"UserInputService".TouchEnabled
|
|
touchEnabled
|
|
|
|
-- Scrolling
|
|
-- Chat.ScrollQueue = (value) =>
|
|
-- for i = 1, #@MessageQueue
|
|
-- if @MessageQueue[i]
|
|
-- for _, label in pairs(@MessageQueue[i])
|
|
-- next = @MessageQueue[i].Next
|
|
-- previous = @MessageQueue[i].Previous
|
|
-- if label and label\IsA('TextLabel') or label\IsA('TextButton')
|
|
-- if value > 0 and previous and previous['Message']
|
|
-- label.Position = previous['Message'].Position
|
|
-- elseif value < 1 and next['Message']
|
|
-- label.Position = previous['Message'].Position
|
|
|
|
-- Handles the rendering of the text objects in their appropriate places
|
|
Chat.UpdateQueue = (field, diff) =>
|
|
-- Have to do some sort of correction here
|
|
for i = #@MessageQueue, 1, -1
|
|
if @MessageQueue[i]
|
|
for _, label in pairs @MessageQueue[i]
|
|
if label and type(label) ~= "table" and type(label) ~= "number"
|
|
if label\IsA"TextLabel" or label\IsA "TextButton"
|
|
if diff
|
|
label.Position = label.Position - UDim2.new(0, 0, diff, 0)
|
|
else
|
|
if field == @MessageQueue[i]
|
|
label.Position = UDim2.new(
|
|
@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
|
|
Spawn ->
|
|
wait 0.05
|
|
while label.TextTransparency >= 0
|
|
label.TextTransparency = label.TextTransparency - 0.2
|
|
wait 0.03
|
|
label.TextStrokeTransparency = if label == field["Message"]
|
|
0.8
|
|
else
|
|
1
|
|
else
|
|
label.Position = UDim2.new(
|
|
@Configuration.XScale,
|
|
0,
|
|
label.Position.Y.Scale - field["Message"].Size.Y.Scale,
|
|
0
|
|
)
|
|
if label.Position.Y.Scale < -0.01
|
|
-- NOTE: Remove this fix when Textbounds is fixed
|
|
label.Visible = false
|
|
label\Destroy!
|
|
|
|
Chat.CreateScrollBar ==>
|
|
-- Code for scrolling is in here, partially, but scroll bar drawing isn't drawn
|
|
-- TODO: Implement
|
|
|
|
-- For scrolling, to see if we hit the bounds so that we can stop it from scrolling anymore
|
|
Chat.CheckIfInBounds = (value) =>
|
|
if #Chat.MessageQueue < 3
|
|
return true
|
|
|
|
if value > 0 and
|
|
Chat.MessageQueue[1] and
|
|
Chat.MessageQueue[1]["Player"] and
|
|
Chat.MessageQueue[1]["Player"].Position.Y.Scale == 0
|
|
|
|
true
|
|
elseif value < 0 and
|
|
Chat.MessageQueue[1] and
|
|
Chat.MessageQueue[1]["Player"] and
|
|
Chat.MessageQueue[1]["Player"].Position.Y.Scale < 0
|
|
|
|
true
|
|
else
|
|
false
|
|
|
|
-- This is to precompute all playerName space strings
|
|
-- This is used to offset the message by exactly this + 2 spacestrings
|
|
Chat.ComputeSpaceString = (pLabel) =>
|
|
nString = " "
|
|
if not @TempSpaceLabel
|
|
@TempSpaceLabel = New "TextButton", "SpaceButton"
|
|
Size: UDim2.new 0, pLabel.AbsoluteSize.X, 0, pLabel.AbsoluteSize.Y
|
|
FontSize: @Configuration.FontSize
|
|
Parent: @RenderFrame
|
|
BackgroundTransparency: 1
|
|
Text: nString
|
|
|
|
else
|
|
@TempSpaceLabel.Text = nString
|
|
|
|
while @TempSpaceLabel.TextBounds.X < pLabel.TextBounds.X
|
|
nString ..= " "
|
|
@TempSpaceLabel.Text = nString
|
|
nString ..= " "
|
|
@CachedSpaceStrings_List[pLabel.Text] = nString
|
|
@TempSpaceLabel.Text = ""
|
|
nString
|
|
|
|
-- When the playerChatted event fires
|
|
-- The message is what the player chatted
|
|
Chat.UpdateChat = (cPlayer, message) =>
|
|
messageField =
|
|
Player: cPlayer
|
|
Message: message
|
|
|
|
if coroutine.status(Chat.MessageThread) == "dead"
|
|
--Chat.Messages_List = {}
|
|
table.insert Chat.Messages_List, messageField
|
|
Chat.MessageThread = coroutine.create ->
|
|
for i = 1, #Chat.Messages_List
|
|
field = Chat.Messages_List[i]
|
|
Chat\CreateMessage field["Player"], field["Message"]
|
|
Chat.Messages_List = {}
|
|
|
|
coroutine.resume Chat.MessageThread
|
|
else
|
|
table.insert Chat.Messages_List, messageField
|
|
|
|
-- Chat.RecalculateSpacing ==>
|
|
--[[for i = 1, #@MessageQueue
|
|
pLabel = @MessageQueue[i]['Player']
|
|
mLabel = @MessageQueue[i]['Message']
|
|
|
|
prevYScale = mLabel.Size.Y.Scale
|
|
prevText = mLabel.Text
|
|
mLabel.Text = prevText
|
|
|
|
heightField = mLabel.TextBounds.Y
|
|
|
|
mLabel.Size = UDim2.new(1, 0, heightField/@RenderFrame.AbsoluteSize.Y, 0)
|
|
pLabel.Size = mLabel.Size
|
|
|
|
diff = mLabel.Size.Y.Scale - prevYScale
|
|
|
|
Chat\UpdateQueue(@MessageQueue[i], diff)
|
|
end ]]
|
|
|
|
-- Chat.ApplyFilter = (str) =>
|
|
-- --[[for _, word in pair(@Filter_List)
|
|
-- if string.find(str, word)
|
|
-- str\gsub word, '@#$^'
|
|
-- ]]
|
|
|
|
-- NOTE: Temporarily disabled ring buffer to allow for chat to always wrap around
|
|
Chat.CreateMessage = (cPlayer, message) =>
|
|
local pName
|
|
if not cPlayer
|
|
pName = ""
|
|
else
|
|
pName = cPlayer.Name
|
|
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 #@MessageQueue > @Configuration.HistoryLength
|
|
--[[pLabel = @MessageQueue[#@MessageQueue]['Player']
|
|
mLabel = @MessageQueue[#@MessageQueue]['Message']
|
|
|
|
pLabel.Text = pName .. ':'
|
|
pLabel.Name = pName
|
|
|
|
local pColor
|
|
if cPlayer.Neutral
|
|
pLabel.TextColor3 = Chat\ComputeChatColor(pName)
|
|
else
|
|
pLabel.TextColor3 = cPlayer.TeamColor.Color
|
|
|
|
local nString
|
|
|
|
if not @CachedSpaceStrings_List[pName]
|
|
nString = Chat\ComputeSpaceString(pLabel)
|
|
else
|
|
nString = @CachedSpaceStrings_List[pName]
|
|
end
|
|
|
|
mLabel.Text = ""
|
|
mLabel.Name = pName .. " - message"
|
|
mLabel.Text = nString .. message;
|
|
|
|
mLabel.Parent = nil
|
|
mLabel.Parent = @RenderFrame
|
|
|
|
mLabel.Position = UDim2.new 0, 0, 1, 0;
|
|
pLabel.Position = UDim2.new 0, 0, 1, 0;]]
|
|
|
|
-- Reinserted at the beginning, ring buffer
|
|
@MessageQueue[#@MessageQueue] = nil
|
|
--else
|
|
-- Haven't hit the mark yet, so keep creating
|
|
pLabel = New "TextLabel", pName,
|
|
Text: pName .. ":"
|
|
-- TextColor3 = pColor
|
|
FontSize: Chat.Configuration.FontSize
|
|
TextXAlignment: Enum.TextXAlignment.Left
|
|
TextYAlignment: Enum.TextYAlignment.Top
|
|
Parent: @RenderFrame
|
|
TextWrapped: false
|
|
Size: UDim2.new 1, 0, 0.1, 0
|
|
BackgroundTransparency: 1
|
|
TextTransparency: 1
|
|
Position: UDim2.new 0, 0, 1, 0
|
|
BorderSizePixel: 0
|
|
TextStrokeColor3: Color3.new 0.5, 0.5, 0.5
|
|
TextStrokeTransparency: 0.75
|
|
--Active = false
|
|
|
|
if cPlayer.Neutral
|
|
pLabel.TextColor3 = Chat\ComputeChatColor pName
|
|
else
|
|
pLabel.TextColor3 = cPlayer.TeamColor.Color
|
|
|
|
local nString
|
|
|
|
if not @CachedSpaceStrings_List[pName]
|
|
nString = Chat\ComputeSpaceString(pLabel)
|
|
else
|
|
nString = @CachedSpaceStrings_List[pName]
|
|
|
|
mLabel = New "TextLabel", "#{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: @RenderFrame
|
|
TextWrapped: true
|
|
BackgroundTransparency: 1
|
|
TextTransparency: 1
|
|
Position: UDim2.new 0, 0, 1, 0
|
|
BorderSizePixel: 0
|
|
TextStrokeColor3: Color3.new 0, 0, 0
|
|
--TextStrokeTransparency = 0.8;
|
|
--Active = false;
|
|
|
|
mLabel.Text = nString .. message
|
|
|
|
if not pName
|
|
pLabel.Text = ""
|
|
mLabel.TextColor3 = Color3.new 0, 0.4, 1.0
|
|
--end
|
|
|
|
for _, adminName in pairs @Admins_List
|
|
if string.lower(adminName) == string.lower pName
|
|
mLabel.TextColor3 = @Configuration.AdminMessageColor
|
|
|
|
pLabel.Visible = true
|
|
mLabel.Visible = true
|
|
|
|
-- This will give beautiful multilines as well
|
|
heightField = mLabel.TextBounds.Y
|
|
|
|
mLabel.Size = UDim2.new 1, 0, heightField / @RenderFrame.AbsoluteSize.Y, 0
|
|
pLabel.Size = mLabel.Size
|
|
|
|
queueField = {}
|
|
queueField["Player"] = pLabel
|
|
queueField["Message"] = mLabel
|
|
queueField["SpawnTime"] = tick! -- Used for identifying when to make the message invisible
|
|
|
|
table.insert @MessageQueue, 1, queueField
|
|
Chat\UpdateQueue queueField
|
|
|
|
Chat.ScreenSizeChanged ==>
|
|
wait!
|
|
while @Frame.AbsoluteSize.Y > 120
|
|
@Frame.Size = @Frame.Size - UDim2.new 0, 0, 0.005, 0
|
|
-- Chat\RecalculateSpacing!
|
|
|
|
Chat.FindButtonTree = (scButton, rootList) =>
|
|
list = {}
|
|
rootList = rootList or @SafeChatTree
|
|
for button, _ in pairs rootList
|
|
if button == scButton
|
|
list = rootList[button]
|
|
elseif type(rootList[button]) == "table"
|
|
list = Chat\FindButtonTree scButton, rootList[button]
|
|
return list
|
|
|
|
Chat.ToggleSafeChatMenu = (scButton) =>
|
|
list = Chat\FindButtonTree scButton, @SafeChatTree
|
|
if list
|
|
for button, _ in pairs list
|
|
if button\IsA"TextButton" or button\IsA "ImageButton"
|
|
button.Visible = not button.Visible
|
|
return true
|
|
return false
|
|
|
|
Chat.CreateSafeChatOptions = (list, rootButton) =>
|
|
text_List = {}
|
|
count = 0
|
|
text_List[rootButton] = {}
|
|
text_List[rootButton][1] = list[1]
|
|
rootButton = rootButton or @SafeChatButton
|
|
for msg, _ in pairs list
|
|
if type(msg) == "string"
|
|
chatText = New "TextButton", 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: @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"
|
|
text_List[rootButton][chatText] = Chat\CreateSafeChatOptions list[msg], chatText
|
|
-- else
|
|
-- --table.insert(text_List[chatText], true)
|
|
chatText.MouseEnter\connect ->
|
|
Chat\ToggleSafeChatMenu chatText
|
|
|
|
chatText.MouseLeave\connect ->
|
|
Chat\ToggleSafeChatMenu chatText
|
|
|
|
chatText.MouseButton1Click\connect ->
|
|
lList = Chat\FindButtonTree chatText
|
|
-- if lList
|
|
-- for i, v in pairs lList
|
|
try
|
|
PlayersService\Chat lList[1]
|
|
return text_List
|
|
|
|
Chat.CreateSafeChatGui ==>
|
|
@SafeChatFrame = New "Frame", "SafeChatFrame"
|
|
Size: UDim2.new 1, 0, 1, 0
|
|
Parent: @Gui
|
|
BackgroundTransparency: 1
|
|
|
|
* New "ImageButton", "SafeChatButton"
|
|
Size: UDim2.new 0, 44, 0, 31
|
|
Position: UDim2.new 0, 1, 0.35, 0
|
|
BackgroundTransparency: 1
|
|
Image: "http://www.roblox.com/asset/?id=97080365"
|
|
|
|
@SafeChatButton = @SafeChatFrame.SafeChatButton
|
|
-- safe chat button is the root of this tree
|
|
@SafeChatTree[@SafeChatButton] = Chat\CreateSafeChatOptions @SafeChat_List, @SafeChatButton
|
|
|
|
@SafeChatButton.MouseButton1Click\connect ->
|
|
Chat\ToggleSafeChatMenu @SafeChatButton
|
|
|
|
Chat.FocusOnChatBar ==>
|
|
if @ClickToChatButton
|
|
@ClickToChatButton.Visible = false
|
|
|
|
@GotFocus = true
|
|
if @Frame["Background"]
|
|
@Frame.Background.Visible = false
|
|
@ChatBar\CaptureFocus!
|
|
|
|
-- For touch devices we create a button instead
|
|
Chat.CreateTouchButton ==>
|
|
@ChatTouchFrame = New "Frame", "ChatTouchFrame"
|
|
Size: UDim2.new 0, 128, 0, 32
|
|
Position: UDim2.new 0, 88, 0, 0
|
|
BackgroundTransparency: 1
|
|
Parent: @Gui
|
|
|
|
* New "ImageButton", "ChatLabel"
|
|
Size: UDim2.new 0, 74, 0, 28
|
|
Position: UDim2.new 0, 0, 0, 0
|
|
BackgroundTransparency: 1
|
|
ZIndex: 2.0
|
|
|
|
* New "ImageLabel", "Background"
|
|
Size: UDim2.new 1, 0, 1, 0
|
|
Position: UDim2.new 0, 0, 0, 0
|
|
BackgroundTransparency: 1
|
|
Image: "http://www.roblox.com/asset/?id=97078724"
|
|
|
|
@TapToChatLabel = @ChatTouchFrame.ChatLabel
|
|
@TouchLabelBackground = @ChatTouchFrame.Background
|
|
|
|
@ChatBar = New "TextBox", "ChatBar"
|
|
Size: UDim2.new 1, 0, 0.2, 0
|
|
Position: UDim2.new 0, 0, 0.8, 800
|
|
Text: ""
|
|
ZIndex: 1
|
|
BackgroundTransparency: 1
|
|
Parent: @Frame
|
|
TextXAlignment: Enum.TextXAlignment.Left
|
|
TextColor3: Color3.new 1, 1, 1
|
|
ClearTextOnFocus: false
|
|
|
|
@TapToChatLabel.MouseButton1Click\connect ->
|
|
@TapToChatLabel.Visible = false
|
|
--@ChatBar.Visible = true
|
|
--@Frame.Background.Visible = true
|
|
@ChatBar\CaptureFocus!
|
|
@GotFocus = true
|
|
if @TouchLabelBackground
|
|
@TouchLabelBackground.Visible = false
|
|
|
|
-- Non touch devices, create the bottom chat bar
|
|
Chat.CreateChatBar ==>
|
|
-- okay now we
|
|
local status, result = try
|
|
return GuiService.UseLuaChat
|
|
if forceChatGUI or (status and result)
|
|
@ClickToChatButton = New "TextButton", "ClickToChat"
|
|
Size: UDim2.new 1, 0, 0, 20
|
|
BackgroundTransparency: 1
|
|
ZIndex: 2.0
|
|
Parent: @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
|
|
|
|
@ChatBar = New "TextBox", "ChatBar"
|
|
Size: UDim2.new 1, 0, 0, 20
|
|
Position: UDim2.new 0, 0, 1, 0
|
|
Text: ""
|
|
ZIndex: 1
|
|
BackgroundColor3: Color3.new 0, 0, 0
|
|
BackgroundTransparency: 0.25
|
|
Parent: @Gui
|
|
TextXAlignment: Enum.TextXAlignment.Left
|
|
TextColor3: Color3.new 1, 1, 1
|
|
FontSize: Enum.FontSize.Size12
|
|
ClearTextOnFocus: false
|
|
|
|
-- 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 = try
|
|
GuiService\SetGlobalGuiInset 0, 0, 0, 20
|
|
if not success
|
|
GuiService\SetGlobalSizeOffsetPixel 0, -20
|
|
-- CHatHotKey is '/'
|
|
GuiService\AddSpecialKey Enum.SpecialKey.ChatHotkey
|
|
GuiService.SpecialKeyPressed\connect (key) ->
|
|
if key == Enum.SpecialKey.ChatHotkey
|
|
Chat\FocusOnChatBar!
|
|
|
|
@ClickToChatButton.MouseButton1Click\connect ->
|
|
Chat\FocusOnChatBar!
|
|
|
|
-- Create the initial Chat stuff
|
|
-- Done only once
|
|
Chat.CreateGui ==>
|
|
@Gui = WaitForChild CoreGuiService, "RobloxGui"
|
|
@Frame = New "Frame", "ChatFrame"
|
|
--Size: @Configuration.Size
|
|
Size: UDim2.new 0, 500, 0, 120
|
|
Position: UDim2.new 0, 0, 0, 5
|
|
BackgroundTransparency: 1
|
|
--ClipsDescendants: true
|
|
ZIndex: 0
|
|
Parent: @Gui
|
|
Active: false
|
|
|
|
* New "ImageLabel", "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
|
|
ZIndex: 0
|
|
Visible: false
|
|
|
|
* New "Frame", "Border"
|
|
Size: UDim2.new 1, 0, 0, 1
|
|
Position: UDim2.new 0, 0, 0.8, 0
|
|
BackgroundTransparency: 0
|
|
BackgroundColor3: Color3.new 236 / 255, 236 / 255, 236 / 255
|
|
BorderSizePixel: 0
|
|
Visible: false
|
|
|
|
* New "Frame", "ChatRenderFrame"
|
|
Size: UDim2.new 1.02, 0, 1.01, 0
|
|
Position: UDim2.new 0, 0, 0, 0
|
|
BackgroundTransparency: 1
|
|
--ClipsDescendants: true
|
|
ZIndex: 0
|
|
Active: false
|
|
|
|
Spawn ->
|
|
wait 0.5
|
|
if IsPhone!
|
|
@Frame.Size = UDim2.new 0, 280, 0, 120
|
|
|
|
@RenderFrame = @Frame.ChatRenderFrame
|
|
if Chat\IsTouchDevice!
|
|
@Frame.Position = @Configuration.Position
|
|
@RenderFrame.Size = UDim2.new 1, 0, 1, 0
|
|
elseif @Frame.AbsoluteSize.Y > 120
|
|
Chat\ScreenSizeChanged!
|
|
@Gui.Changed\connect (property) ->
|
|
if property == "AbsoluteSize"
|
|
Chat\ScreenSizeChanged!
|
|
|
|
if forceChatGUI or Player.ChatMode == Enum.ChatMode.TextAndMenu
|
|
if Chat\IsTouchDevice!
|
|
Chat\CreateTouchButton!
|
|
else
|
|
Chat\CreateChatBar!
|
|
--Chat\CreateSafeChatGui!
|
|
|
|
if @ChatBar
|
|
@ChatBar.FocusLost\connect (enterPressed) ->
|
|
Chat.GotFocus = false
|
|
if Chat\IsTouchDevice!
|
|
@ChatBar.Visible = false
|
|
@TapToChatLabel.Visible = true
|
|
|
|
if @TouchLabelBackground
|
|
@TouchLabelBackground.Visible = true
|
|
if enterPressed and @ChatBar.Text ~= ""
|
|
cText = @ChatBar.Text
|
|
if string.sub(@ChatBar.Text, 1, 1) == "%"
|
|
cText = "(TEAM) #{string.sub cText, 2, #cText}"
|
|
try
|
|
PlayersService\TeamChat cText
|
|
else
|
|
try
|
|
PlayersService\Chat cText
|
|
|
|
if @ClickToChatButton
|
|
@ClickToChatButton.Visible = true
|
|
@ChatBar.Text = ""
|
|
Spawn ->
|
|
wait 5.0
|
|
if not Chat.GotFocus
|
|
Chat.Frame.Background.Visible = false
|
|
|
|
-- Scrolling function
|
|
-- Applies a speed(velocity) to have nice scrolling effect
|
|
Input.OnMouseScroll = =>
|
|
Spawn ->
|
|
-- How long should the speed last?
|
|
while Input.Speed ~= 0
|
|
if Input.Speed > 1
|
|
while Input.Speed > 0
|
|
Input.Speed = Input.Speed - 1
|
|
wait 0.25
|
|
elseif Input.Speed < 0
|
|
while Input.Speed < 0
|
|
Input.Speed = Input.Speed + 1
|
|
wait 0.25
|
|
wait 0.03
|
|
return if Chat\CheckIfInBounds Input.Speed
|
|
Chat\ScrollQueue!
|
|
|
|
Input.ApplySpeed = (value) =>
|
|
Input.Speed = Input.Speed + value
|
|
if not @Simulating
|
|
Input\OnMouseScroll!
|
|
|
|
Input.Initialize = =>
|
|
@Mouse.WheelBackward\connect ->
|
|
Input\ApplySpeed @Configuration.DefaultSpeed
|
|
|
|
@Mouse.WheelForward\connect ->
|
|
Input\ApplySpeed @Configuration.DefaultSpeed
|
|
|
|
Chat.FindMessageInSafeChat = (message, list) =>
|
|
foundMessage = false
|
|
for msg, _ in pairs list
|
|
if msg == message
|
|
return true
|
|
if type(list[msg]) == "table"
|
|
foundMessage = Chat\FindMessageInSafeChat message, list[msg]
|
|
if foundMessage
|
|
return true
|
|
foundMessage
|
|
|
|
-- Just a wrapper around our PlayerChatted event
|
|
Chat.PlayerChatted = (...) =>
|
|
args = { ... }
|
|
-- argCount = select("#", ...)
|
|
local player, message
|
|
-- This doesn't look very good, but what else to do?
|
|
if args[2]
|
|
player = args[2]
|
|
if args[3]
|
|
message = args[3]
|
|
if string.sub(message, 1, 1) == "%"
|
|
message = "(TEAM) #{string.sub message, 2, #message}"
|
|
|
|
if PlayersService.ClassicChat
|
|
if not (string.sub(message, 1, 3) == "/e " or string.sub(message, 1, 7) == "/emote ") and
|
|
(forceChatGUI or Player.ChatMode == Enum.ChatMode.TextAndMenu) or
|
|
(Player.ChatMode == Enum.ChatMode.Menu and string.sub(message, 1, 3) == "/sc") or
|
|
Chat\FindMessageInSafeChat message, @SafeChat_List
|
|
|
|
Chat\UpdateChat player, message
|
|
|
|
-- 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
|
|
Chat.CullThread ==>
|
|
while true
|
|
if #@MessageQueue > 0
|
|
for _, field in pairs(@MessageQueue)
|
|
if field["SpawnTime"] and
|
|
field["Player"] and
|
|
field["Message"] and
|
|
tick! - field["SpawnTime"] > @Configuration.LifeTime
|
|
|
|
field["Player"].Visible = false
|
|
field["Message"].Visible = false
|
|
wait 5.0
|
|
|
|
-- RobloxLock everything so users can't delete them(?)
|
|
Chat.LockAllFields = (gui) =>
|
|
children = gui\GetChildren!
|
|
for i = 1, #children
|
|
children[i].RobloxLocked = true
|
|
if #children[i]\GetChildren! > 0
|
|
Chat\LockAllFields children[i]
|
|
|
|
Chat.CoreGuiChanged = (coreGuiType, enabled) =>
|
|
if coreGuiType == Enum.CoreGuiType.Chat or coreGuiType == Enum.CoreGuiType.All
|
|
if @Frame
|
|
@Frame.Visible = enabled
|
|
|
|
if not Chat\IsTouchDevice! and @ChatBar
|
|
@ChatBar.Visible = enabled
|
|
GuiService\SetGlobalGuiInset 0, 0, 0, if enabled
|
|
20
|
|
else
|
|
0
|
|
|
|
-- Constructor
|
|
-- This function initializes everything
|
|
Chat.Initialize ==>
|
|
Chat\CreateGui!
|
|
|
|
try
|
|
Chat\CoreGuiChanged Enum.CoreGuiType.Chat, Game.StarterGui\GetCoreGuiEnabled Enum.CoreGuiType.Chat
|
|
Game.StarterGui.CoreGuiChangedSignal\connect (coreGuiType, enabled) ->
|
|
Chat\CoreGuiChanged coreGuiType, enabled
|
|
|
|
@EventListener = PlayersService.PlayerChatted\connect (...) ->
|
|
-- This event has 4 callback arguments
|
|
-- Enum.PlayerChatType.All, chatPlayer, message, targetPlayer
|
|
Chat\PlayerChatted ...
|
|
|
|
@MessageThread = coroutine.create ->
|
|
coroutine.resume @MessageThread
|
|
|
|
-- 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 ->
|
|
Chat.EventListener\disconnect!
|
|
@EventListener = PlayersService.PlayerChatted\connect (...) ->
|
|
-- This event has 4 callback arguments
|
|
-- Enum.PlayerChatType.All, chatPlayer, message, targetPlayer
|
|
Chat\PlayerChatted ...
|
|
|
|
Spawn ->
|
|
Chat\CullThread!
|
|
|
|
@Frame.RobloxLocked = true
|
|
Chat\LockAllFields @Frame
|
|
@Frame.DescendantAdded\connect (descendant) ->
|
|
Chat\LockAllFields descendant
|
|
|
|
Chat\Initialize!
|