MainModule local gameInst = game.JobId local isOnline = (gameInst ~= "") if isOnline and game.GameId ~= 123949867 then script:Destroy() return end local dataModel = script:WaitForChild("DataModel") local framework = script:WaitForChild("Framework") local Chat = game:GetService("Chat") local InsertService = game:GetService("InsertService") local Lighting = game:GetService("Lighting") local Players = game:GetService("Players") local ServerStorage = game:GetService("ServerStorage") local StarterGui = game:GetService("StarterGui") local StarterPlayer = game:GetService("StarterPlayer") local TeleportService = game:GetService("TeleportService") local initMsg = Instance.new("Message") initMsg.Text = "INITIALIZING..." initMsg.Parent = workspace if not workspace.FilteringEnabled then initMsg.Text = "FATAL: Workspace.FilteringEnabled MUST be set to true!!!" return 0 end local override = ServerStorage:FindFirstChild("LocalGameImport") if override then if isOnline then warn("WARNING: Dev framework is present in a networked game, and it shouldn't be!!!") override:Destroy() elseif override ~= script then initMsg:Destroy() require(override) return 1 end end -- Standard Forced Settings Lighting.Outlines = false Players.CharacterAutoLoads = false StarterGui.ShowDevelopmentGui = false local sky = Lighting:FindFirstChildOfClass("Sky") if not sky then local skyProps = {"Bk", "Dn", "Ft", "Lf", "Rt", "Up"} local skyId = "rbxasset://Sky/null_plainsky512_%s.jpg" sky = Instance.new("Sky") for _,prop in pairs(skyProps) do sky["Skybox"..prop] = skyId:format(prop:lower()) end sky.Parent = Lighting end sky.SunAngularSize = 14 sky.MoonAngularSize = 6 local devProps = { DevComputerMovementMode = "KeyboardMouse"; DevComputerCameraMovementMode = "Classic"; DevTouchMovementMode = "UserChoice"; DevTouchCameraMovementMode = "Classic"; } StarterPlayer.LoadCharacterAppearance = false StarterPlayer.EnableMouseLockOption = false for prop,value in pairs(devProps) do StarterPlayer[prop] = value end for _,player in pairs(Players:GetPlayers()) do local char = player.Character if char and char:IsDescendantOf(workspace) then char:Destroy() player.Character = nil end for prop,value in pairs(devProps) do StarterPlayer[prop] = value end end -- Import the shared universe assets (scripts and stuff shared between both the main menu and the actual places) require(ServerStorage:FindFirstChild("LocalSharedImport") or 1027421176) -- Load Scripts for _,desc in pairs(dataModel:GetDescendants()) do if desc:IsA("StringValue") and desc.Name:sub(1,9) == "ScriptRef" then local scriptName = desc.Name:gsub("ScriptRef%[(.+)%]","%1") local scriptPath = desc.Value local scriptRef = framework local gotScript = true for path in scriptPath:gmatch("[^/]+") do scriptRef = scriptRef:WaitForChild(path, 1) if not scriptRef then gotScript = false warn("WARNING: Failed to load ScriptRef for", desc:GetFullName()) warn(" got stuck at:", path) break end end if gotScript then local newScript = scriptRef:Clone() newScript.Name = scriptName if newScript:IsA("BaseScript") then newScript.Disabled = false end for _,child in pairs(desc:GetChildren()) do child.Parent = newScript end newScript.Parent = desc.Parent end desc:Destroy() end end -- Load DataModel for _,rep in pairs(dataModel:GetChildren()) do local real = game:FindFirstChildWhichIsA(rep.Name, true) if not real then -- Hopefully a service that doesn't exist yet? real = game:GetService(rep.Name) end for _,child in pairs(rep:GetChildren()) do local existing = real:FindFirstChild(child.Name) if existing then existing:Destroy() end child.Parent = real end end -- Reconnect any players that may have joined during initialization. -- (or restart the PlayerScripts manually if I'm offline testing) local StarterPlayerScripts = StarterPlayer:WaitForChild("StarterPlayerScripts") if isOnline then for _,player in pairs(Players:GetPlayers()) do TeleportService:TeleportToPlaceInstance(game.PlaceId, gameInst, player) end else --[[local player = Players.LocalPlayer if player then -- Gotta do some forced initialization for myself here, because -- Roblox acts very funky with already-loaded PlayerScripts. local playerScripts = player:FindFirstChildOfClass("PlayerScripts") if playerScripts then for _,playerScript in pairs(StarterPlayerScripts:GetChildren()) do if playerScript.Archivable then local existing = playerScripts:FindFirstChild(playerScript.Name) if existing then existing:Destroy() end playerScript:Clone().Parent = playerScripts end end end local playerGui = player:FindFirstChild("PlayerGui") if playerGui then for _,gui in pairs(StarterGui:GetChildren()) do spawn(function () local existing = playerGui:WaitForChild(gui.Name, 1) if not existing then gui:Clone().Parent = playerGui end end) end end player.CanLoadCharacterAppearance = false player:LoadCharacter() wait(.5) local c = workspace.CurrentCamera local char = player.Character local humanoid = char:WaitForChild("Humanoid") if c.CameraSubject ~= humanoid then c.CameraSubject = humanoid end end]] end if Chat.LoadDefaultChat then warn("Chat.LoadDefaultChat should be set to false!") end initMsg:Destroy() return 0 ReplicatedFirst JoinScript local CollectionService = game:GetService("CollectionService") local RunService = game:GetService("RunService") local UserInputService = game:GetService("UserInputService") local TeleportService = game:GetService("TeleportService") local ReplicatedFirst = script.Parent local JointsService = game:GetService("JointsService") do local StarterGui = game:GetService("StarterGui") local function setCoreSafe(method,...) while not pcall(StarterGui.SetCore, StarterGui, method,...) do wait() end end spawn(function () setCoreSafe("ResetButtonCallback", false) end) setCoreSafe("TopbarEnabled", false) end local player = game.Players.LocalPlayer local playerGui = player:WaitForChild("PlayerGui") local mouse = player:GetMouse() if not UserInputService.TouchEnabled then mouse.Icon = "rbxassetid://334630296" end local guiRoot = script:WaitForChild("GuiRoot") guiRoot.Parent = playerGui ReplicatedFirst:RemoveDefaultLoadingScreen() if playerGui:FindFirstChild("ConnectingGui") then playerGui.ConnectingGui:Destroy() end if RunService:IsStudio() then return end local c = workspace.CurrentCamera local IS_PHONE = c.ViewportSize.Y < 600 local topbar = guiRoot:WaitForChild("Topbar") if IS_PHONE then local uiScale = Instance.new("UIScale") uiScale.Scale = 0.6 uiScale.Parent = topbar end local messageGui = guiRoot:WaitForChild("MessageGui") local message = messageGui:WaitForChild("Message") local partWatch = nil local partQueue = {} local bricks = 0 local connectors = 0 local messageFormat = "Bricks: %d Connectors: %d" --------------------------------------------------------------------- local fakeLoadTime = TeleportService:GetTeleportSetting("FakeLoadTime") local function onDescendantAdded(desc) if desc:IsA("BasePart") and not desc:IsA("Terrain") then if not CollectionService:HasTag(desc, "AxisPart") and desc.Name ~= "__negatepart" then desc.LocalTransparencyModifier = 1 partQueue[#partQueue + 1] = desc end elseif desc:IsA("Decal") then desc.LocalTransparencyModifier = 1 end end if fakeLoadTime then local descendants = workspace:GetDescendants() for _,desc in pairs(descendants) do onDescendantAdded(desc) end partWatch = workspace.DescendantAdded:Connect(onDescendantAdded) end --------------------------------------------------------------------- local c = workspace.CurrentCamera c.CameraType = "Follow" c.CameraSubject = workspace messageGui.Visible = true local bricks = 0 local connectors = 0 local lastUpdate = 0 local done = false local function stepBrickConnectorStatus() if fakeLoadTime then wait(math.random() / 4) for i = 1, math.random(30, 50) do local part = table.remove(partQueue) if part then bricks = bricks + 1 connectors = connectors + #part:GetJoints() part.LocalTransparencyModifier = 0 for _,v in pairs(part:GetDescendants()) do if v:IsA("Decal") then v.LocalTransparencyModifier = 0 end end end end done = (#partQueue == 0) else wait() done = game:IsLoaded() end end while not done do stepBrickConnectorStatus() message.Text = messageFormat:format(bricks, connectors) end if partWatch then partWatch:Disconnect() partWatch = nil end c.CameraSubject = nil message.Text = "Requesting character..." wait(1) local rep = game:GetService("ReplicatedStorage") local requestCharacter = rep:WaitForChild("RequestCharacter") requestCharacter:FireServer() message.Text = "Waiting for character..." while not player.Character do player.CharacterAdded:Wait() wait() end messageGui.Visible = false c.CameraType = "Custom" GuiRoot Topbar Buttons local topbar = script.Parent local function registerButton(btn) if btn:IsA("TextButton") and btn.Active then local function onMouseEnter() btn.BackgroundTransparency = 0 end local function onMouseLeave() btn.BackgroundTransparency = 0.5 end btn.MouseEnter:Connect(onMouseEnter) btn.MouseLeave:Connect(onMouseLeave) end end for _,v in pairs(topbar:GetChildren()) do registerButton(v) end topbar.ChildAdded:Connect(registerButton) Exit Exit local TeleportService = game:GetService("TeleportService") local GuiService = game:GetService("GuiService") local UserInputService = game:GetService("UserInputService") GuiService.AutoSelectGuiEnabled = false local btn = script.Parent local topbar = btn.Parent local root = topbar.Parent local messageGui = root:WaitForChild("MessageGui") local message = messageGui:WaitForChild("Message") local exitOverride = messageGui:WaitForChild("ExitOverride") local function onClicked() local visibleSignal = messageGui:GetPropertyChangedSignal("Visible") message.Visible = false exitOverride.Visible = true messageGui.Visible = true TeleportService:Teleport(998374377) visibleSignal:Connect(function () if not messageGui.Visible then messageGui.Visible = true end end) end if not GuiService:IsTenFootInterface() then btn.MouseButton1Down:Connect(onClicked) end local exitBuffer = "Continue holding down 'Back' to return to the menu.\nExiting in...\n%.1f" local function onInputBegan(input) if input.KeyCode == Enum.KeyCode.ButtonSelect and not exitOverride.Visible and not messageGui.Visible then messageGui.Visible = true message.Size = exitOverride.Size local success = true for i = 3,0,-.1 do if input.UserInputState ~= Enum.UserInputState.Begin then success = false break end message.Text = exitBuffer:format(i) wait(.1) end if success then onClicked() else messageGui.Visible = false end end end UserInputService.InputBegan:Connect(onInputBegan) Fullscreen Fullscreen local UserInputService = game:GetService("UserInputService") local btn = script.Parent local gameSettings = UserSettings():GetService("UserGameSettings") local player = game.Players.LocalPlayer local function onClick() if not player:FindFirstChild("FullscreenMsg") then local m = Instance.new("Message") m.Name = "FullscreenMsg" m.Text = "This button is just here for legacy aesthetics, and has no functionality." if UserInputService.MouseEnabled and UserInputService.KeyboardEnabled then m.Text = m.Text .. "\nPress F11 to toggle fullscreen!" end m.Parent = player wait(3) m:Destroy() end end local function update() if gameSettings:InFullScreen() then btn.Text = "\t\tx Fullscreen" else btn.Text = "\t\tFullscreen" end end update() gameSettings.FullscreenChanged:connect(update) btn.MouseButton1Down:Connect(onClick) Help Help local help = script.Parent local topbar = help.Parent local root = topbar.Parent local window = root:WaitForChild("HelpWindow") local close = window:WaitForChild("Close") local function onOpen() window.Visible = true end local function onClose() window.Visible = false end help.MouseButton1Down:Connect(onOpen) close.MouseButton1Down:Connect(onClose) GuiRoot true true 0 true false false null 0 Topbar false 0 0 true true 0.698039174079895 0.698039174079895 0.698039174079895 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 0 null null null null 0 80 0 -36 null 0 false null 0 660 0 27 0 0 true 1 Exit true 0 0 true false true 0.698039174079895 0.698039174079895 0.698039174079895 0.5 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 9 0 1 false null null null null 0 528 0 0 null 0 false false null 0 132 1 0 0 0 0.40392160415649414 0.40392160415649414 0.40392160415649414 true 14 0.40392160415649414 0.40392160415649414 0.40392160415649414 0.8999999761581421 0.30000001192092896 0 true 0 1 true 1 UITextSizeConstraint true 20 1 Help true 0 0 true false true 0.698039174079895 0.698039174079895 0.698039174079895 0.5 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 9 0 1 false null null null null 0 396 0 0 null 0 false false null 0 132 1 0 0 0 0.40392160415649414 0.40392160415649414 0.40392160415649414 true 14 0.40392160415649414 0.40392160415649414 0.40392160415649414 0.8999999761581421 0.30000001192092896 0 true 0 1 true 1 UITextSizeConstraint true 20 1 Fullscreen true 0 0 true false true 0.698039174079895 0.698039174079895 0.698039174079895 0.5 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 9 0 1 false null null null null 0 264 0 0 null 0 false false null 0 132 1 0 0 0 0.40392160415649414 0.40392160415649414 0.40392160415649414 true 14 0.40392160415649414 0.40392160415649414 0.40392160415649414 0.8999999761581421 0.30000001192092896 0 true 0 1 true 1 UITextSizeConstraint true 20 1 Insert false 0 0 true false true 0.698039174079895 0.698039174079895 0.698039174079895 0.5 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 9 0 1 false null null null null 0 132 0 0 null 0 true false null 0 132 1 0 0 0 0.6274510025978088 0.6274510025978088 0.6274510025978088 true 14 0.6274510025978088 0.6274510025978088 0.6274510025978088 0.8999999761581421 0.30000001192092896 0 true 0 1 true 1 UITextSizeConstraint true 20 1 Tools false 0 0 true false true 0.698039174079895 0.698039174079895 0.698039174079895 0.5 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 9 0 1 false null null null null 0 0 0 0 null 0 true false null 0 132 1 0 0 0 0.6274510025978088 0.6274510025978088 0.6274510025978088 true 14 0.6274510025978088 0.6274510025978088 0.6274510025978088 0.8999999761581421 0.30000001192092896 0 true 0 1 true 1 UITextSizeConstraint true 20 1 MessageGui false 0.5 0.5 true true 0.7058823704719543 0.7058823704719543 0.7058823704719543 0.5 1 1 1 0 3 false false 0 null null null null 0.5 0 0.5 0 null 0 false null 0.6000000238418579 0 1 0 0 0 false 1 Message false 0 0.5 true true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false 9 0 1 null null null null 0 0 0.5 0 null 0 false null 1 0 0.125 0 0 Connecting to server... 1 1 1 true 14 1 1 1 0.75 0 0 true 2 1 true 1 UIAspectRatioConstraint true 3 0 1 ExitOverride false 0 0.5 true true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false 9 0 1 null null null null 0 0 0.5 0 null 0 false null 1 0 0.25 0 0 You are now being returned to the main menu. Please hold... 1 1 1 true 14 1 1 1 0.75 0 0 true 2 1 false 1 HelpWindow true 0.5 0.5 true true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false true rbxassetid://1041546985 1 1 1 0 0 0 0 0 0 null null null null 0.5 0 0.5 0 null 0 1 false null 0.800000011920929 0 0.699999988079071 0 0 4 30 304 130 1 1 0 1 0 false 1 Help false 0 0 true true 1 1 1 0 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false rbxassetid://1041647615 1 1 1 0 0 0 0 0 0 null null null null 0 4 0 31 null 0 0 false null 1 -8 1 -36 0 0 0 0 0 1 1 0 1 0 true 1 UIAspectRatioConstraint true 2.75 0 0 Title false 0 0 true true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false 2 0 1 null null null null 0 5 0 0 null 0 false null 0.8999999761581421 -10 0 30 0 ROBLOX Help 1 1 1 false 14 0.498039186000824 0.498039186000824 0.498039186000824 0.6000000238418579 0 0 false 0 1 true 2 Stroke false 0 0 true true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false 2 0 1 null null null null 0 1 0 1 null 0 false null 1 0 1 0 0 ROBLOX Help 0 0 0 false 14 1 1 1 1 0 0 false 0 1 true 1 Close true 1 0 true true true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false rbxassetid://1041651899 1 1 1 0 0 0 0 0 0 true null null null null 1 -5 0 5 null 0 0 true false null 0 22 0 22 1 0 0 0 0 1 0 1 0 1 0 true 1 UIAspectRatioConstraint true 2.5 0 0 ReplicatedStorage SafeChatTree local safeChatTree = { Label = "ROOT"; Branches = {}; } do local mTreeData = script:WaitForChild("RawTreeData") local treeData = require(mTreeData) local stack = {} stack[0] = safeChatTree for line in treeData:gmatch("[^\n]+") do if #line > 0 then local stackIndex = 0 while line:sub(1,1) == "\t" do stackIndex = stackIndex + 1 line = line:sub(2) end local tree = stack[stackIndex] assert(tree,"Bad safechat tree setup at depth " .. stackIndex .. ": " .. line) local branch = {} branch.Label = line branch.Branches = {} table.insert(tree.Branches,branch) stack[stackIndex+1] = branch end end end return safeChatTree RawTreeData return [==[ Hello Hi Hi there! Hi everyone Howdy Howdy partner! Greetings Greetings everyone Greetings robloxians! Seasons greetings! Welcome Welcome to my place Welcome to our base Welcome to my barbecque Hey there! What's up? How are you doing? How's it going? What's new? Good day Good morning Good afternoon Good evening Good night Silly Waaaaaaaz up?! Hullo! Behold greatness, mortals! Holidays Happy New Year! Happy Valentine's Day! Beware the Ides of March! Happy Easter! Happy 4th of July! Happy Thanksgiving! Happy Halloween! Happy Hanukkah! Merry Christmas! Happy Holidays! Goodbye Good Night Sweet dreams Go to sleep! Lights out! Bedtime Later See ya later Later gator! See you tomorrow Bye Hasta la bye bye! I'll be right back I have to go Farewell Take care Have a nice day Goodluck! Ta-ta for now! Peace Peace out! Peace dudes! Rest in pieces! Silly To the batcave! Over and out! Happy trails! I've got to book it! Tootles! Smell you later! GG! My house is on fire! gtg. Friend Wanna be friends? Follow me Come to my place! Come to my base! Follow me, team! Your place is cool Your place is fun Your place is awesome Your place looks good Thank you Thanks for playing Thanks for visiting Thanks for everything No thank you No problem Don't worry That's ok You are ... You are great! You are good! You are cool! You are funny! You are silly! You are awesome! I like ... I like your name I like your shirt I like your place I like your style Sorry My bad! I'm sorry Whoops! Please forgive me I forgive you Questions Who? Who wants to be my friend? Who wants to be on my team? Who made this brilliant game? What? What is your favorite animal? What is your favorite game? What is your favorite movie? What is your favorite TV show? What is your favorite music? What are your hobbies? When? When are you online? When is the new version coming out? When can we play again? When will your place be done? Where? Where do you want to go? Where are you going? Where am I?! How? How are you today? How did you make this cool place? Can I... Can I have a tour? Can I be on your team? Can I be your friend? Can I try something? Answers You need help? Check out the news section Check out the help section Read the wiki! All the answers are in the wiki! Some people ... Me Not me You All of us Everyone but you Builderman! Telamon! Time ... In the morning In the afternoon At night Tomorrow This week This month Sometime Sometimes Whenever you want Never Animals Cats Lion Tiger Leopard Cheetah Dogs Wolves Beagle Collie Dalmatian Poodle Spaniel Shepherd Terrier Retriever Horses Ponies Stallions Reptiles Dinosaurs Lizards Snakes Turtles! Hamster Monkey Bears Fish Goldfish Sharks Sea Bass Halibut Birds Eagles Penguins Turkeys Elephants Mythical Beasts Dragons Unicorns Sea Serpents Sphinx Cyclops Minotaurs Goblins Honest Politicians Ghosts Scylla and Charybdis Games Roblox BrickBattle Community Building Roblox Minigames Action Puzzle Strategy Racing RPG Board games Chess Checkers Settlers of Catan Tigris and Euphrates El Grande Stratego Carcassonne Sports Hockey Soccer Football Baseball Basketball Volleyball Tennis Watersports Surfing Swimming Water Polo Winter sports Skiing Snowboarding Sledding Skating Adventure Rock climbing Hiking Fishing Wacky Foosball Calvinball Croquet Cricket Dodgeball Squash Movies/TV Science Fiction Animated Anime Comedy Romantic Action Fantasy Music Country Jazz Rap Hip-hop Techno Classical Pop Rock Hobbies Computers Building computers Videogames Coding Hacking The Internet lol. teh internets! Dance Gynastics Martial Arts Karate Judo Taikwon Do Wushu Street fighting Listening to music Music lessons Playing in my band Playing piano Playing guitar Playing violin Playing drums Playing a weird instrument Arts and crafts Location USA West Alaska Arizona California Colorado Hawaii Idaho Montana Nevada New Mexico Oregon Utah Washington Wyoming Midwest Illinois Indiana Iowa Kansas Michigan Minnesota Missouri Nebraska North Dakota Ohio South Dakota Wisconsin Northeast Connecticut Delaware Maine Maryland Massachusetts New Hampshire New Jersey New York Pennsylvania Rhode Island Vermont Virginia West Virginia South Alabama Arkansas Florida Georgia Kentucky Louisiana Mississippi North Carolina Oklahoma South Carolina Tennessee Texas Canada Alberta British Columbia Manitoba New Brunswick Newfoundland Northwest Territories Nova Scotia Nunavut Ontario Prince Edward Island Quebec Saskatchewan Yukon Mexico Central America Europe Great Britain England Scotland Wales Northern Ireland France Germany Spain Italy Poland Switzerland Greece Romania Asia China India Japan Korea South America Argentina Brazil Africa Eygpt Swaziland Australia Middle East Antarctica Age Rugrat Kid Teen Twenties Old Ancient Mesozoic Mood Good Great! Not bad Sad Hyper Chill Boy Girl Game Let's build Let's battle Nice one! So far so good! Lucky shot! Oh man! Silly Muahahahaha! 1337 i r teh pwnz0r! w00t! z0mg h4x! ub3rR0xXorzage! all your base are belong to me! Yes Absolutely! Rock on! Totally! Juice! No Ummm. No. ... Ok Well... ok Sure :-) :-( :D :-O lol ]==] ServerScriptService Badges local ServerStorage = game:GetService("ServerStorage") local BadgeService = game:GetService("BadgeService") local AssetService = game:GetService("AssetService") local Players = game:GetService("Players") local usingLeaderboard = true if ServerStorage:FindFirstChild("TrackCombatBadges") then usingLeaderboard = ServerStorage.TrackCombatBadges.Value elseif ServerStorage:FindFirstChild("LoadLeaderboard") then usingLeaderboard = ServerStorage.LoadLeaderboard.Value end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local playerDataGet = require(ServerStorage:WaitForChild("PlayerDataStore")) if not playerDataGet.Success then warn("Failed to load PlayerData, badges will not be awarded") return end local playerData = playerDataGet.DataStore ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local placeCount = 0 local function iterPageItems(pages) return coroutine.wrap(function () local pageNum = 1 while true do for _, item in ipairs(pages:GetCurrentPage()) do coroutine.yield(item, pageNum) end if pages.IsFinished then break end pages:AdvanceToNextPageAsync() pageNum = pageNum + 1 end end) end for place in iterPageItems(AssetService:GetGamePlacesAsync()) do if not place.Name:lower():find("devtest") and not place.Name:find("Super Nostalgia Zone") then placeCount = placeCount + 1 end end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local badges = { CombatInitiation = 1020931358; Warrior = 1020932933; Bloxxer = 1021012898; Inviter = 1021010468; Friendship = 1021024465; Ambassador = 1021056315; } local inviterBadgeStatus = {} local lastWipeout = {} local function giveBadge(player,badge) warn("AWARDING BADGE", badge, "TO", player) if not BadgeService:UserHasBadge(player.UserId,badge) then BadgeService:AwardBadge(player.UserId,badge) end end local function onHumanoidDied(humanoid, victim) local player do local char = humanoid.Parent if char then player = Players:GetPlayerFromCharacter(char) end end local myLastWipeout = lastWipeout[victim.Name] or 0 local now = tick() if (now - myLastWipeout) > 5 then local creator = humanoid:FindFirstChild("creator") if creator then local killer = creator.Value if killer and killer.UserId > 0 and killer ~= player then local killerData = playerData:GetSaveData(killer) local knockOuts = killerData:Get("Knockouts") or 0 knockOuts = knockOuts + 1 killerData:Set("Knockouts",knockOuts) if knockOuts > 250 then local wipeOuts = killerData:Get("Wipeouts") or 0 if wipeOuts < knockOuts then giveBadge(killer,badges.Bloxxer) end elseif knockOuts > 100 then giveBadge(killer,badges.Warrior) elseif knockOuts > 10 then giveBadge(killer,badges.CombatInitiation) end end end local myData = playerData:GetSaveData(victim) local wipeOuts = myData:Get("Wipeouts") or 0 myData:Set("Wipeouts", wipeOuts + 1) lastWipeout[victim.Name] = now end end local function onCharacterAdded(char) local player = game.Players:GetPlayerFromCharacter(char) local humanoid = char:WaitForChild("Humanoid") humanoid.Died:Connect(function () onHumanoidDied(humanoid,player) end) end local function handleSocialBadges(player) -- Set up our inviter status from scratch. inviterBadgeStatus[player.Name] = { Counted = 0; Queried = {}; } -- Check the status of other players, and see if we can give them the inviter badge. local myData = playerData:GetSaveData(player) for _,otherPlayer in pairs(Players:GetPlayers()) do if player ~= otherPlayer and player:IsFriendsWith(otherPlayer.UserId) then local theirName = otherPlayer.Name local theirStatus = inviterBadgeStatus[theirName] if theirStatus and not theirStatus.Queried[player.Name] then theirStatus.Queried[player.Name] = true theirStatus.Counted = theirStatus.Counted + 1 if theirStatus.Counted >= 3 then giveBadge(otherPlayer,badges.Inviter) end end -- Also increment the friendship encounters for these two. local myFrEncs = myData:Get("FriendEncounters") or 0 myFrEncs = myFrEncs + 1 myData:Set("FriendEncounters",myFrEncs) if myFrEncs >= 10 then giveBadge(player,badges.Friendship) end local theirData = playerData:GetSaveData(otherPlayer) local theirFrEncs = theirData:Get("FriendEncounters") or 0 theirFrEncs = theirFrEncs + 1 theirData:Set("FriendEncounters",theirFrEncs) if theirFrEncs >= 10 then giveBadge(otherPlayer,badges.Friendship) end end end end local function onPlayerAdded(player) if player.UserId > 0 then -- Hook up combat badge listeners if usingLeaderboard then if player.Character and player.Character:IsDescendantOf(workspace) then onCharacterAdded(player.Character) end player.CharacterAdded:Connect(onCharacterAdded) end -- Handle social badges handleSocialBadges(player) -- Handle ambassador badge local myData = playerData:GetSaveData(player) local myPlaceVisits = myData:Get("PlacesVisited") if myPlaceVisits == nil then myPlaceVisits = { Count = 0; Record = {}; } end local placeId = tostring(game.PlaceId) if not myPlaceVisits.Record[placeId] then myPlaceVisits.Record[placeId] = true myPlaceVisits.Count = myPlaceVisits.Count + 1 end if myPlaceVisits.Count >= placeCount then giveBadge(player, badges.Ambassador) end myData:Set("PlacesVisited", myPlaceVisits) end end for _,v in pairs(Players:GetPlayers()) do onPlayerAdded(v) end Players.PlayerAdded:Connect(onPlayerAdded) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Bevels ------------------------------------------------------------------------------------------------ -- Initialization ------------------------------------------------------------------------------------------------ local CollectionService = game:GetService("CollectionService") local Debris = game:GetService("Debris") local Players = game:GetService("Players") local RunService = game:GetService("RunService") local ServerStorage = game:GetService("ServerStorage") local function getFlag(name) local flag = ServerStorage:FindFirstChild(name) return (flag and flag:IsA("BoolValue") and flag.Value) end local enableBevels = getFlag("EnableBevels") local debugMode = getFlag("DevTestMode") local bevelCache = ServerStorage:FindFirstChild("BevelCache") local bevelsReady = bevelCache:FindFirstChild("BevelsReady") if not bevelCache then bevelCache = Instance.new("Folder") bevelCache.Name = "BevelCache" bevelCache.Parent = ServerStorage end if not bevelsReady then bevelsReady = Instance.new("BoolValue") bevelsReady.Name = "BevelsReady" bevelsReady.Parent = bevelCache bevelsReady.Archivable = false end if not enableBevels then bevelsReady.Value = true return end do local coreBevelCache = ServerStorage:WaitForChild("CoreBevelCache") for _,bevel in pairs(coreBevelCache:GetChildren()) do if not bevelCache:FindFirstChild(bevel.Name) then bevel.Parent = bevelCache bevel.Archivable = false end end coreBevelCache:Destroy() end local regen = ServerStorage:FindFirstChild("Regeneration") if regen then local ready = regen:WaitForChild("Ready") while not ready.Value do ready.Changed:Wait() end end local loadBuildTools = ServerStorage:FindFirstChild("LoadBuildTools") local hasBuildTools = (loadBuildTools ~= nil) ------------------------------------------------------------------------------------------------ local edgeDepth = 1 / 15 local cornerDepth = edgeDepth * math.sqrt(8 / 3) local mirrorProps = { "Anchored", "CanCollide", "CastShadow", "CFrame", "CollisionGroupId", "CustomPhysicalProperties", "Color", "Locked", "Material", "Name", "Reflectance", "RotVelocity", "Transparency", "Velocity", } local surfaceProps = { "ParamA", "ParamB", "Surface", "SurfaceInput" } local bevelHash = "%.2f ~ %.2f ~ %.2f" local isStudio = RunService:IsStudio() local negateBase = Instance.new("Part") negateBase.Name = "__negateplane" negateBase.CanCollide = false negateBase.BottomSurface = 0 negateBase.Transparency = 1 negateBase.Anchored = true negateBase.TopSurface = 0 negateBase.Locked = true CollectionService:AddTag(negateBase, "NoBevels") for _,normalId in pairs(Enum.NormalId:GetEnumItems()) do local name = normalId.Name for _,surfaceProp in pairs(surfaceProps) do table.insert(mirrorProps, name .. surfaceProp) end end ------------------------------------------------------------------------------------------------ local overload = 0 local threshold = Vector3.new(30, 30, 30) if ServerStorage:FindFirstChild("BevelThreshold") then threshold = ServerStorage.BevelThreshold.Value end local function debugPrint(...) if debugMode then warn("[BEVELS DEBUG]:", ...) end end local function isPartOfHumanoid(object) local model = object:FindFirstAncestorOfClass("Model") if model then if model:FindFirstChildOfClass("Humanoid") then return true else return isPartOfHumanoid(model) end end return false end local function canGiveBevels(part) if part.Parent and part:IsA("Part") and not CollectionService:HasTag(part, "NoBevels") then if not isPartOfHumanoid(part) and not part:FindFirstChildWhichIsA("DataModelMesh") then local inThreshold = false local diff = threshold - part.Size if diff.X >= 0 and diff.Y >= 0 and diff.Z >= 0 then inThreshold = true end if inThreshold then if CollectionService:HasTag(part, "ForceBevels") then return true else return part.Shape.Name == "Block" and part.Transparency < 1 end end end end return false end local function createProxyPart(part, name, tag, sizeChange) local proxyPart = Instance.new("Part") proxyPart.Name = name proxyPart.Locked = true proxyPart.TopSurface = 0 proxyPart.Massless = true proxyPart.Transparency = 1 proxyPart.BottomSurface = 0 proxyPart.CanCollide = false proxyPart.CFrame = part.CFrame local size = part.Size if sizeChange then size = size + sizeChange end local proxyWeld = Instance.new("Weld") proxyWeld.Name = "ProxyWeld" proxyWeld.Part1 = proxyPart proxyWeld.Part0 = part if hasBuildTools then local mesh = Instance.new("SpecialMesh") mesh.Scale = size * 20 mesh.MeshType = "Brick" mesh.Offset = part.Size mesh.Parent = proxyPart proxyPart.Size = Vector3.new(.05, .05, .05) proxyWeld.C0 = CFrame.new(-mesh.Offset) else proxyPart.Size = part.Size end CollectionService:AddTag(proxyPart, tag) CollectionService:AddTag(proxyPart, "NoBevels") CollectionService:AddTag(proxyWeld, "GorillaGlue") proxyWeld.Parent = proxyPart proxyPart.Parent = part return proxyPart end local function createBevels(part, initializing) if not canGiveBevels(part) or isPartOfHumanoid(part) then return end local size = part.Size local sx, sy, sz = size.X, size.Y, size.Z local bevelKey = bevelHash:format(sx, sy, sz) local debugBox if debugMode then debugBox = Instance.new("BoxHandleAdornment") debugBox.Color3 = Color3.new(0, 2, 2) debugBox.AlwaysOnTop = true debugBox.Name = "DebugBox" debugBox.Size = size debugBox.ZIndex = 0 debugBox.Adornee = part debugBox.Parent = part end if not bevelCache:FindFirstChild(bevelKey) then local halfSize = size / 2 local planeScale = math.max(sx, sy, sz) local planes = {} local solverPart = part:Clone() solverPart.CFrame = CFrame.new() solverPart.BrickColor = BrickColor.new(-1) debugPrint("Solving:", bevelKey) for x = -1, 1 do local x0 = (x == 0) for y = -1, 1 do local y0 = (y == 0) for z = -1, 1 do local z0 = (z == 0) local isCenter = (x0 and y0 and z0) local isFace = ((x0 and y0) or (y0 and z0) or (z0 and x0)) if not (isCenter or isFace) then local isCorner = (not x0 and not y0 and not z0) local depth = isCorner and cornerDepth or edgeDepth local offset = Vector3.new(x, y, z) local cornerPos = (halfSize * offset) local plane = negateBase:Clone() plane.CFrame = CFrame.new(cornerPos, cornerPos + offset) plane.Size = Vector3.new(planeScale, planeScale, depth) plane.Parent = part table.insert(planes, plane) end end end end local success, union = pcall(function () return solverPart:SubtractAsync(planes, "Box") end) if success then union.Name = bevelKey union.UsePartColor = true union.Parent = bevelCache CollectionService:AddTag(union, "HasBevels") if debugBox then debugBox.Color3 = Color3.new(0, 2, 0) end elseif debugBox then debugBox.Color3 = Color3.new(2, 0, 0) end for _,plane in pairs(planes) do plane:Destroy() end overload = 0 else if debugBox then debugBox.Color3 = Color3.new(2, 0, 2) end overload = overload + 1 if overload % 10 == 0 then RunService.Heartbeat:Wait() end end local baseUnion = bevelCache:FindFirstChild(bevelKey) if baseUnion then local archivable = baseUnion.Archivable baseUnion.Archivable = true local union = baseUnion:Clone() baseUnion.Archivable = archivable for _,prop in ipairs(mirrorProps) do union[prop] = part[prop] end for _,joint in pairs(part:GetJoints()) do if joint:IsA("JointInstance") or joint:IsA("WeldConstraint") then if joint.Part0 == part then joint.Part0 = union elseif joint.Part1 == part then joint.Part1 = union end end end for _,child in pairs(part:GetChildren()) do if not child:IsA("TouchTransmitter") and not child:IsA("Texture") then if child:IsA("BaseScript") then child.Disabled = true end child.Parent = union if child:IsA("BaseScript") then child.Disabled = false end end end if not initializing then wait() end if CollectionService:HasTag(part, "DoUnlock") then union.Locked = false end if part.ClassName ~= "Part" then local holder = Instance.new("Weld") holder.Part0 = part holder.Part1 = union holder.Parent = part union.Anchored = false union.Massless = true union.Parent = part part.Transparency = 1 CollectionService:AddTag(holder, "GorillaGlue") else local parent = part.Parent part:Destroy() union.Parent = parent end elseif debugBox then debugBox.Color3 = Color3.new(2, 0, 0) end if debugBox then debugBox.Transparency = 0.5 Debris:AddItem(debugBox, 2) end end ------------------------------------------------------------------------------------------------ do local waitForPlayer = getFlag("BevelsWaitForPlayer") if waitForPlayer then -- Wait for a player to spawn local playerSpawned = false while not playerSpawned do for _,player in pairs(Players:GetPlayers()) do if player.Character and player.Character:IsDescendantOf(workspace) then playerSpawned = true break end end workspace.ChildAdded:Wait() end end warn("Solving bevels...") -- Collect all blocks currently in the workspace. local initialPass = {} local debugHint for _,desc in pairs(workspace:GetDescendants()) do if canGiveBevels(desc) then if not desc.Locked then CollectionService:AddTag(desc, "DoUnlock") desc.Locked = true end table.insert(initialPass, desc) end end if waitForPlayer then -- Sort the blocks by the sum of their distances from players in the game. local samplePoints = {} for _,player in pairs(Players:GetPlayers()) do local char = player.Character if char then local root = char.PrimaryPart if root then local rootPos = root.Position table.insert(samplePoints, rootPos) end end end table.sort(initialPass, function (a, b) local distSumA = 0 local distSumB = 0 local posA = a.Position local posB = b.Position for _,rootPos in pairs(samplePoints) do local distA = (rootPos - posA).Magnitude distSumA = distSumA + distA local distB = (rootPos - posB).Magnitude distSumB = distSumB + distB end if distSumA ~= distSumB then return distSumA < distSumB end if posA.Y ~= posB.Y then return posA.Y < posB.Y end if posA.X ~= posB.X then return posA.X < posB.X end if posA.Z ~= posB.Z then return posA.Z < posB.Z end return 0 end) end if debugMode then debugHint = Instance.new("Hint") debugHint.Text = "Generating Bevels..." debugHint.Parent = workspace end -- Run through the initial bevel creation phase. for _,block in ipairs(initialPass) do createBevels(block, true) end if debugHint then debugHint:Destroy() end end -- Listen for new parts being added. workspace.DescendantAdded:Connect(createBevels) -- Allow regeneration to request bevel solving local bevelSolver = bevelCache:FindFirstChild("RequestSolve") if not bevelSolver then bevelSolver = Instance.new("BindableFunction") bevelSolver.Name = "RequestSolve" bevelSolver.Parent = bevelCache bevelSolver.Archivable = false end function bevelSolver.OnInvoke(inst) for _,desc in pairs(inst:GetDescendants()) do if desc:IsA("Part") then createBevels(desc) end end end if RunService:IsStudio() then local exportBin = Instance.new("Folder") exportBin.Name = "ExportBin" exportBin.Parent = ServerStorage for _,v in pairs(bevelCache:GetChildren()) do if v:IsA("TriangleMeshPart") and v.Archivable then v:Clone().Parent = exportBin end end wait(.1) for _,v in pairs(exportBin:GetChildren()) do if v:FindFirstChild("LOD") then v.LOD:Destroy() end end end -- Ready! warn("Bevels ready!") bevelsReady.Value = true ------------------------------------------------------------------------------------------------ BuildTools local CollectionService = game:GetService("CollectionService") local HttpService = game:GetService("HttpService") local Players = game:GetService("Players") local ReplicatedStorage = game:GetService("ReplicatedStorage") local ServerStorage = game:GetService("ServerStorage") local loadBuildTools = ServerStorage:FindFirstChild("LoadBuildTools") if not (loadBuildTools and loadBuildTools.Value) then return end local looseBranches = ServerStorage:FindFirstChild("LooseBranches") if looseBranches and looseBranches:IsA("BoolValue") then looseBranches = looseBranches.Value else looseBranches = false end local toolList = loadBuildTools.Value if toolList == true then -- If it's a BoolValue, load all of them. toolList = "GameTool;Clone;Delete" end local DraggerService = Instance.new("Folder") DraggerService.Name = "DraggerService" DraggerService.Parent = ReplicatedStorage local draggerGateway = Instance.new("RemoteFunction") draggerGateway.Name = "DraggerGateway" draggerGateway.Parent = DraggerService local submitUpdate = Instance.new("RemoteEvent") submitUpdate.Name = "SubmitUpdate" submitUpdate.Parent = DraggerService local draggerScript = script:WaitForChild("Dragger") local activeKeys = {} local playerToKey = {} local partToKey = {} local debounce = {} local SIMULATE_TAG = "SimulateAfterDrag" local NO_BREAK_TAG = "GorillaGlue" local function assertClass(obj, class) assert(obj) assert(typeof(obj) == "Instance") assert(obj:IsA(class)) end local function canGiveKey(player, part) if part.Locked then return false end local playerHasKey = playerToKey[player] if playerHasKey then return false end local partHasKey = partToKey[part] if partHasKey then return false end return true end local function claimAssembly(player, part) if part:CanSetNetworkOwnership() then part:SetNetworkOwner(player) end end local function validJointsOf(part) return coroutine.wrap(function () for _,joint in pairs(part:GetJoints()) do if not CollectionService:HasTag(joint, NO_BREAK_TAG) then coroutine.yield(joint) end end end) end local function breakJoints(part) for joint in validJointsOf(part) do if not CollectionService:HasTag(joint, NO_BREAK_TAG) then joint:Destroy() end end end local function makeJoints(part) -- Connect this part to a nearby surface workspace:JoinToOutsiders({part}, "Surface") end local function removePartKey(key) local data = activeKeys[key] if data then local player = data.Player if player then playerToKey[player] = nil end local part = data.Part if part then makeJoints(part) if CollectionService:HasTag(part, SIMULATE_TAG) then data.Anchored = false CollectionService:RemoveTag(part, SIMULATE_TAG) end part.Anchored = data.Anchored claimAssembly(player, part) partToKey[part] = nil end activeKeys[key] = nil end end local function restoreJointUpstream(part) local collectedParts = {} if part and CollectionService:HasTag(part, SIMULATE_TAG) then CollectionService:RemoveTag(part, SIMULATE_TAG) part.Anchored = false makeJoints(part) for joint in validJointsOf(part) do local part0 = joint.Part0 local part1 = joint.Part1 if part0 and part ~= part0 then collectedParts[part0] = true restoreJointUpstream(part0) end if part1 and part ~= part1 then collectedParts[part1] = true restoreJointUpstream(part1) end end end return collectedParts end local function collapseJointUpstream(part) if part and not (part.Locked or CollectionService:HasTag(part, SIMULATE_TAG)) then CollectionService:AddTag(part, SIMULATE_TAG) part.Anchored = true for joint in validJointsOf(part) do local part0 = joint.Part0 local part1 = joint.Part1 if part0 and part ~= part0 then collapseJointUpstream(part0) end if part1 and part ~= part1 then collapseJointUpstream(part1) end end breakJoints(part) end end function draggerGateway.OnServerInvoke(player, request, ...) if request == "GetKey" then local part, asClone = ... assertClass(part, "BasePart") if asClone then local newPart = part:Clone() newPart.Parent = workspace breakJoints(newPart) newPart.CFrame = CFrame.new(part.Position + Vector3.new(0, part.Size.Y, 0)) local copySound = Instance.new("Sound") copySound.SoundId = "rbxasset://sounds/electronicpingshort.wav" copySound.PlayOnRemove = true copySound.Parent = newPart wait() part = newPart copySound:Destroy() end if canGiveKey(player, part) then local key = HttpService:GenerateGUID(false) claimAssembly(player, part) playerToKey[player] = key partToKey[part] = key local collected = restoreJointUpstream(part) local anchored = part.Anchored part.Anchored = true breakJoints(part) for otherPart in pairs(collected) do if otherPart:IsGrounded() then collapseJointUpstream(otherPart) end end activeKeys[key] = { Player = player; Part = part; Anchored = anchored; } return true, key, part else return false end elseif request == "ClearKey" then local key = ... if not key then key = playerToKey[player] end if key then local data = activeKeys[key] if data then local owner = data.Player if player == owner then removePartKey(key) end end end elseif request == "RequestDelete" then if not debounce[player] then local part = ... assertClass(part, "BasePart") debounce[player] = true if canGiveKey(player, part) then local e = Instance.new("Explosion") e.BlastPressure = 0 e.Position = part.Position e.Parent = workspace local s = Instance.new("Sound") s.SoundId = "rbxasset://sounds/collide.wav" s.Volume = 1 s.PlayOnRemove = true s.Parent = part local connectedParts = restoreJointUpstream(part) part:Destroy() for otherPart in pairs(connectedParts) do if otherPart:IsGrounded() then collapseJointUpstream(otherPart) end end end wait(.1) debounce[player] = false end end end local function onChildAdded(child) if child:IsA("Backpack") then for draggerTool in toolList:gmatch("[^;]+") do local tool = Instance.new("Tool") tool.Name = draggerTool tool.RequiresHandle = false local newDragger = draggerScript:Clone() newDragger.Parent = tool newDragger.Disabled = false tool.Parent = child end end end local function onPlayerAdded(player) for _, v in pairs(player:GetChildren()) do onChildAdded(v) end player.ChildAdded:Connect(onChildAdded) end local function onPlayerRemoved(player) local key = playerToKey[player] if key then removePartKey(key) end end local function onSubmitUpdate(player, key, cframe) local keyData = activeKeys[key] if keyData then local owner = keyData.Player if owner == player then local part = keyData.Part if part and part:IsDescendantOf(workspace) then breakJoints(part) part.CFrame = cframe end end end end for _, player in pairs(game.Players:GetPlayers()) do onPlayerAdded(player) end submitUpdate.OnServerEvent:Connect(onSubmitUpdate) Players.PlayerAdded:Connect(onPlayerAdded) Players.PlayerRemoving:Connect(onPlayerRemoved) -- Garbage Collection while wait(5) do for part, key in pairs(partToKey) do if not part:IsDescendantOf(workspace) then removePartKey(key) end end end Dragger local CollectionService = game:GetService("CollectionService") local RunService = game:GetService("RunService") local UserInputService = game:GetService("UserInputService") local ReplicatedStorage = game:GetService("ReplicatedStorage") local SoundService = game:GetService("SoundService") local Dragger = Instance.new("Dragger") local tool = script.Parent local selection = Instance.new("SelectionBox") selection.Parent = tool selection.Transparency = 1 local icon = Instance.new("StringValue") icon.Name = "IconOverride" icon.Parent = tool local mode = tool.Name local draggerService = ReplicatedStorage:WaitForChild("DraggerService") local gateway = draggerService:WaitForChild("DraggerGateway") local submitUpdate = draggerService:WaitForChild("SubmitUpdate") ---------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Connections ---------------------------------------------------------------------------------------------------------------------------------------------------------------- local cons = {} local function addConnections(connections) for event, func in pairs(connections) do local con = event:Connect(func) table.insert(cons, con) end end local function clearCons() while #cons > 0 do local connection = table.remove(cons) connection:Disconnect() end end ---------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Keys ---------------------------------------------------------------------------------------------------------------------------------------------------------------- local keyLocks = {} local function onInputEnded(input) if keyLocks[input.KeyCode.Name] then keyLocks[input.KeyCode.Name] = nil end end local function isKeyDown(key) if UserInputService:IsKeyDown(key) and not keyLocks[key] then keyLocks[key] = true return true end return false end UserInputService.InputEnded:Connect(onInputEnded) ---------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Tool Style ---------------------------------------------------------------------------------------------------------------------------------------------------------------- local style = { GameTool = { Icon = "rbxassetid://1048129653"; HoverColor = Color3.fromRGB(25,153,255); Cursors = { Idle = ""; Hover = "rbxasset://textures/DragCursor.png"; Grab = "rbxasset://textures/GrabRotateCursor.png"; }; }; Clone = { Icon = "rbxasset://textures/Clone.png"; HoverColor = Color3.fromRGB(25,153,255); Cursors = { Idle = "rbxasset://textures/CloneCursor.png"; Hover = "rbxassetid://1048136830"; Grab = "rbxasset://textures/GrabRotateCursor.png"; } }; Delete = { Icon = "rbxasset://textures/Hammer.png"; HoverColor = Color3.new(1,0.5,0); CanShowWithHover = true; Cursors = { Idle = "rbxasset://textures/HammerCursor.png"; Hover = "rbxasset://textures/HammerOverCursor.png"; } } } local function getIcon(iconType) return style[mode].Cursors[iconType] end tool.TextureId = style[mode].Icon selection.Color3 = style[mode].HoverColor if style[mode].CanShowWithHover then selection.Transparency = 0 end ---------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Dragger ---------------------------------------------------------------------------------------------------------------------------------------------------------------- local mouse local currentKey local down = false local debounce = false local function onIdle() if not down and mouse then local mousePart = mouse.Target if mousePart and not mousePart.Locked then selection.Adornee = mousePart icon.Value = getIcon("Hover") return end selection.Adornee = nil icon.Value = getIcon("Idle") end end local function draggerRotate(axis) if down then Dragger:AxisRotate(axis) end end local function startDraggerAction(mPart) if mode == "Delete" then gateway:InvokeServer("RequestDelete",mPart) return end local pointOnMousePart = mPart.CFrame:ToObjectSpace(mouse.Hit).Position local canDrag, dragKey, mousePart = gateway:InvokeServer("GetKey", mPart, mode == "Clone") if canDrag then selection.Adornee = mousePart selection.Transparency = 0 down = true currentKey = dragKey icon.Value = getIcon("Grab") Dragger:MouseDown(mousePart, pointOnMousePart, {mousePart}) local lastSubmit = 0 while down do local now = tick() local joints = {} for _,joint in pairs(mousePart:GetJoints()) do if CollectionService:HasTag(joint, "GorillaGlue") then joints[joint] = joint.Parent joint.Parent = nil end end --local mousePart = selection.Adornee if down then Dragger:MouseMove(mouse.UnitRay) end if mousePart and currentKey then if isKeyDown("R") then draggerRotate("Z") elseif isKeyDown("T") then draggerRotate("X") end if now - lastSubmit > 0.03 then submitUpdate:FireServer(currentKey, mousePart.CFrame) lastSubmit = now end end for joint, parent in pairs(joints) do joint.Parent = parent end RunService.Heartbeat:Wait() end selection.Transparency = 1 gateway:InvokeServer("ClearKey", dragKey) currentKey = nil end end local function onButton1Down() if not debounce then debounce = true local mousePart = selection.Adornee if mousePart and not down then startDraggerAction(mousePart) end debounce = false end end local function onButton1Up() if down then down = false Dragger:MouseUp() end end ---------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Tool ---------------------------------------------------------------------------------------------------------------------------------------------------------------- local function onEquipped(newMouse) mouse = newMouse addConnections { [mouse.Button1Down] = onButton1Down; [mouse.Button1Up] = onButton1Up; [mouse.Idle] = onIdle; } end local function onUnequipped() onButton1Up() clearCons() selection.Adornee = nil mouse = nil end tool.Equipped:Connect(onEquipped) tool.Unequipped:Connect(onUnequipped) ---------------------------------------------------------------------------------------------------------------------------------------------------------------- CaptureTheFlag local Players = game:GetService("Players") local CollectionService = game:GetService("CollectionService") local Teams = game:GetService("Teams") local FlagInstance = "FlagInstance" local FlagStandInstance = "FlagStandInstance" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -- Flags ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ local function restoreFlag(flag) local owner = flag:FindFirstChild("FlagStand") local flagStand = owner and owner.Part0 if owner and flagStand then for _,joint in pairs(flag:GetJoints()) do if joint.Name == "RightGrip" then joint:Destroy() end end if flag.Name == "Handle" then local tool = flag.Parent if tool:IsA("Tool") then flag.Name = tool.Name tool.Parent = nil end end flag.CFrame = flagStand.CFrame flag.Parent = flagStand.Parent wait() flag.Velocity = Vector3.new() flag.RotVelocity = Vector3.new() owner.Part1 = flag flag.Anchored = false end end local function mountFlagAsTool(flag, humanoid) local owner = flag:FindFirstChild("FlagStand") local teamColor = flag:FindFirstChild("TeamColor") if not (owner and teamColor) or flag.Name == "Handle" then return end local grip = CFrame.new(0.25, 0, 0) * CFrame.Angles(0, -math.pi / 2, 0) local tool = Instance.new("Tool") tool.Name = flag.Name tool.Grip = grip local deathCon local function onDied() local char = humanoid.Parent if char and tool.Parent == char then humanoid:UnequipTools() end if deathCon then deathCon:Disconnect() deathCon = nil end end local function onUnequipped() if deathCon then deathCon:Disconnect() deathCon = nil end if humanoid then local rootPart = humanoid.RootPart if rootPart then local cf = rootPart.CFrame * CFrame.new(0, 4, -8) flag.RotVelocity = Vector3.new(1, 1, 1) flag.Position = cf.Position end end if flag.Parent == tool then flag.Parent = workspace end flag.Name = tool.Name spawn(function () tool:Destroy() end) end tool.Unequipped:Connect(onUnequipped) CollectionService:AddTag(tool, "Flag") tool.Parent = workspace owner.Part1 = nil flag.Name = "Handle" flag.Parent = tool humanoid:EquipTool(tool) deathCon = humanoid.Died:Connect(onDied) end local function onFlagAdded(flag) if not flag:IsA("BasePart") then return end -- Mount TeamColor local teamColor = flag:FindFirstChild("TeamColor") if not teamColor then teamColor = Instance.new("BrickColorValue") teamColor.Value = flag.BrickColor teamColor.Name = "TeamColor" teamColor.Parent = flag end -- Mount FlagStand local flagStand, owner for _,part in pairs(flag:GetConnectedParts()) do if CollectionService:HasTag(part, FlagStandInstance) then flagStand = part break end end if flagStand then owner = Instance.new("Weld") owner.C0 = flagStand.CFrame:ToObjectSpace(flag.CFrame) owner.Name = "FlagStand" owner.Part0 = flagStand owner.Parent = flag for _,joint in pairs(flag:GetJoints()) do if joint ~= owner then joint:Destroy() end end owner.Part1 = flag CollectionService:AddTag(owner, "GorillaGlue") end spawn(function () -- Try to keep the flag from falling out of the world. local deathPlane = workspace.FallenPartsDestroyHeight while flag:IsDescendantOf(workspace) do if flag.Position.Y < deathPlane + 200 then local tool = flag.Parent if tool:IsA("Tool") then tool.Parent = workspace wait() end restoreFlag(flag) end wait() end end) local function onTouched(hit) local char = hit.Parent if char then local player = Players:GetPlayerFromCharacter(char) local humanoid = char:FindFirstChildOfClass("Humanoid") if player and humanoid then if player.Neutral then return end if player.TeamColor == teamColor.Value then if owner.Part1 ~= flag then restoreFlag(flag) end else mountFlagAsTool(flag, humanoid) end end end end flag.Touched:Connect(onTouched) end for _,flag in pairs(CollectionService:GetTagged(FlagInstance)) do onFlagAdded(flag) end local flagAdded = CollectionService:GetInstanceAddedSignal(FlagInstance) flagAdded:Connect(onFlagAdded) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -- Flag Stands ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ local function onFlagStandAdded(flagStand) if not flagStand:IsA("BasePart") then return end local debounce = false local teamColor = flagStand:FindFirstChild("TeamColor") local flagCaptured = flagStand:FindFirstChild("FlagCaptured") if not teamColor then teamColor = Instance.new("BrickColorValue") teamColor.Value = flagStand.BrickColor teamColor.Name = "TeamColor" teamColor.Parent = flagStand end if not flagCaptured then flagCaptured = Instance.new("BindableEvent") flagCaptured.Name = "FlagCaptured" flagCaptured.Parent = flagStand end local function onTouched(hit) if debounce then return end local char = hit.Parent if char then local player = Players:GetPlayerFromCharacter(char) if player then if player.Neutral then return end if player.TeamColor ~= teamColor.Value then return end local tool = char:FindFirstChildOfClass("Tool") local handle = tool and tool:FindFirstChild("Handle") if handle and CollectionService:HasTag(handle, FlagInstance) then debounce = true print("flag captured!") flagCaptured:Fire(player) restoreFlag(handle) tool:Destroy() wait(1) debounce = false end end end end flagStand.Touched:Connect(onTouched) end local function onFlagStandRemoved(flagStand) local teamColor = flagStand:FindFirstChild("TeamColor") local flagCaptured = flagStand:FindFirstChild("FlagCaptured") if teamColor then teamColor:Destroy() end if flagCaptured then flagCaptured:Destroy() end end for _,flagStand in pairs(CollectionService:GetTagged(FlagStandInstance)) do onFlagStandAdded(flagStand) end local flagStandAdded = CollectionService:GetInstanceAddedSignal(FlagStandInstance) flagStandAdded:Connect(onFlagStandAdded) local flagStandRemoved = CollectionService:GetInstanceRemovedSignal(FlagStandInstance) flagStandRemoved:Connect(onFlagStandRemoved) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Characters local CollectionService = game:GetService("CollectionService") local Players = game:GetService("Players") local InsertService = game:GetService("InsertService") local ReplicatedStorage = game:GetService("ReplicatedStorage") local ServerStorage = game:GetService("ServerStorage") local hats = ServerStorage:WaitForChild("ServerHatCache") local requestCharacter = ReplicatedStorage:WaitForChild("RequestCharacter") local assetUtil = require(ReplicatedStorage:WaitForChild("AssetUtil")) local itemData = ReplicatedStorage:WaitForChild("ItemData") local hatData = require(itemData:WaitForChild("Hat")) local playerDataGet = { Success = false } pcall(function () playerDataGet = require(ServerStorage:WaitForChild("PlayerDataStore")) end) if not playerDataGet.Success then warn("Failed to get PlayerData. Avatars will not be loaded.") end local playerDataStore = playerDataGet.DataStore local limbs = {"Head", "Torso", "LeftArm", "RightArm", "LeftLeg", "RightLeg"} local function preBufferHat(hatId) local hat = hats:FindFirstChild(hatId) if not hat then local success, import = assetUtil:SafeCall(InsertService, "LoadAsset", tonumber(hatId)) if success then hat = import:FindFirstChildWhichIsA("Accoutrement") if hat then hat.Name = hatId hat.Parent = hats end end end return hat end local function safeDestroy(obj) spawn(function () obj:Destroy() end) end local function onCharacterAdded(char) local player = Players:GetPlayerFromCharacter(char) local bodyColors = script.BodyColors:Clone() CollectionService:AddTag(bodyColors, "RespectCharacterAsset") local graphic = script.ShirtGraphic:Clone() local shirt = char:FindFirstChildWhichIsA("Shirt") if not shirt then shirt = script.Shirt:Clone() end local pants = char:FindFirstChildWhichIsA("Pants") if not pants then pants = script.Pants:Clone() end local faceId = 1104210678 local tshirtId = 131792587 local humanoid = char:WaitForChild("Humanoid") CollectionService:AddTag(humanoid, "Animator") local function onDied() if char:FindFirstChild("HumanoidRootPart") then char.HumanoidRootPart:Destroy() end wait(5) local player = game.Players:GetPlayerFromCharacter(char) if player then player:LoadCharacter() end end local function onDescendantAdded(desc) if desc:IsA("CharacterMesh") and not desc.Name:sub(1, 3) == "CL_" then safeDestroy(desc) elseif desc:IsA("Accoutrement") then -- Safe way to deter non-game accessories, since I name them by their AssetId if not tonumber(desc.Name) then safeDestroy(desc) end elseif desc:IsA("SpecialMesh") and desc.Parent.Name == "Head" then if desc.Name ~= "HeadMesh" then wait() local override = Instance.new("SpecialMesh") override.Name = "HeadMesh" override.Scale = Vector3.new(1.25, 1.25, 1.25) override.Parent = desc.Parent safeDestroy(desc) end elseif desc:IsA("BodyColors") and desc ~= bodyColors and not CollectionService:HasTag(bodyColors, "RespectCharacterAsset") then safeDestroy(desc) bodyColors.Parent = nil wait() bodyColors.Parent = char end end for _,v in pairs(char:GetDescendants()) do onDescendantAdded(v) end char.DescendantAdded:Connect(onDescendantAdded) humanoid.Died:Connect(onDied) if player.UserId > 0 and playerDataStore then local playerData = playerDataStore:GetSaveData(player) local colorData = playerData:Get("BodyColors") if colorData then for _,limb in pairs(limbs) do local num = colorData[limb] if num then bodyColors[limb.."Color"] = BrickColor.new(num) end end end local loadout = playerData:Get("Loadout") if loadout then local shirtId = loadout.Shirt if shirtId then shirt.ShirtTemplate = "rbxassetid://" .. shirtId end local pantsId = loadout.Pants if pantsId then pants.PantsTemplate = "rbxassetid://" .. pantsId end faceId = loadout.Face or faceId spawn(function () local hatId = loadout.Hat or 0 if hatId > 0 then local hatSrc = preBufferHat(hatId) local hat = hatSrc:Clone() hat.Parent = char end end) end tshirtId = playerData:Get("TShirt") or tshirtId end if tshirtId > 0 then local success,img = assetUtil:RequestImage(tshirtId) if success and img then graphic.Graphic = img graphic.Parent = char end end bodyColors.Parent = char shirt.Parent = char pants.Parent = char local head = char:WaitForChild("Head") local face = head:WaitForChild("face") face.Texture = "rbxhttp://Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&aid=" .. faceId end local function onRequestCharacter(player) if not player.Character then player:LoadCharacter() end end local function onPlayerAdded(player) player.CanLoadCharacterAppearance = false player.CharacterAdded:connect(onCharacterAdded) if player.Character then onCharacterAdded(player.Character) end if game.JobId == "" then player:LoadCharacter() end end for _,v in pairs(Players:GetPlayers()) do onPlayerAdded(v) end Players.PlayerAdded:connect(onPlayerAdded) requestCharacter.OnServerEvent:Connect(onRequestCharacter) Chat local Players = game:GetService("Players") local TextService = game:GetService("TextService") local Chat = game:GetService("Chat") local ReplicatedStorage = game:GetService("ReplicatedStorage") local chatRemote = ReplicatedStorage:WaitForChild("ChatRemote") local mSafeChatTree = ReplicatedStorage:WaitForChild("SafeChatTree") local safeChatTree = require(mSafeChatTree) local filterCache = {} local maxChatLength = 128 local function onServerEvent(player, message) assert(typeof(message) == "string", "bad input passed") assert(#message <= maxChatLength, "Chat message was too long!") if message:sub(1,3) == "/sc" then local tree = safeChatTree for t in message:gmatch("%d+") do local i = tonumber(t) + 1 tree = tree.Branches[i] if not tree then break end end message = tree and tree.Label or " " end local asciiMessage = "" for p, c in utf8.codes(message) do if c > 0x1F600 then asciiMessage = asciiMessage .. "??" else asciiMessage = asciiMessage .. utf8.char(c) end end message = asciiMessage local userId = player.UserId if not filterCache[userId] then filterCache[userId] = {} end local filterResult = filterCache[userId][message] if not filterResult then filterResult = TextService:FilterStringAsync(message,userId) filterCache[userId][message] = filterResult end for _,receiver in pairs(Players:GetPlayers()) do spawn(function () pcall(function () local filtered = filterResult:GetChatForUserAsync(receiver.UserId) chatRemote:FireClient(receiver, player, filtered, filtered ~= message) end) end) end end chatRemote.OnServerEvent:Connect(onServerEvent) Cylinders CylinderSurface true null false true true 100 100 false true 1 0 50 true null 0 0 0 0 Frame false 0.5 0.5 true true 0.32549020648002625 0.32549020648002625 0.32549020648002625 0 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 0 null null null null 0.5 0 0.5 0 null 0 false null 0 20 0.699999988079071 0 0 0 true 1 Frame false 0.5 0.5 true true 0.32549020648002625 0.32549020648002625 0.32549020648002625 0 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 0 null null null null 0.5 0 0.5 0 null 0 false null 0.699999988079071 0 0 20 0 0 true 1 Explosions local CollectionService = game:GetService("CollectionService") local Debris = game:GetService("Debris") local ServerStorage = game:GetService("ServerStorage") local FORCE_GRANULARITY = 2 local allowTeamDamage = false local teamDamage = ServerStorage:FindFirstChild("TeamDamage") if teamDamage then allowTeamDamage = teamDamage.Value end local function processExplosion(explosion) local BLAST_RADIUS = explosion.BlastRadius local BLAST_PRESSURE = explosion.BlastPressure if explosion:FindFirstChild("BLAST_PRESSURE") then BLAST_PRESSURE = explosion.BLAST_PRESSURE.Value end if BLAST_PRESSURE > 0 then local damagedPlayerSet = {} local blastCenter = explosion.Position local function onExplosionHit(p, dist) if explosion:FindFirstChild("Owner") then local player = explosion.Owner.Value if player then local char = player.Character if char and p:IsDescendantOf(char) then return end end end local isInCharacter = false if p.Size.Magnitude / 2 < 20 then --world->ticklePrimitive(p, true); local doBreakjoints = true local hitCharacter = p:FindFirstAncestorWhichIsA("Model") local hitHumanoid = hitCharacter:FindFirstChild("Humanoid") if hitCharacter and hitHumanoid then -- flag as character isInCharacter = true -- don't breakjoints characters doBreakjoints = false -- work out what damage to do local hitPlayer = game.Players:GetPlayerFromCharacter(hitCharacter) local creatorTag = explosion:FindFirstChild("creator") local myPlayer if creatorTag then myPlayer = creatorTag.Value end if hitPlayer and not damagedPlayerSet[hitPlayer] then local doDamage = true if not allowTeamDamage then if myPlayer and hitPlayer ~= myPlayer then if hitPlayer.Team and myPlayer.Team and hitPlayer.Team == myPlayer.Team then doDamage = false end end end if doDamage then -- flag as damaged damagedPlayerSet[hitPlayer] = true -- assume the torso is a massless frictionless unit ball in a perfect vaccum dist = math.min(math.max(dist - 0.8, 0), 1) -- damage to do local frac = (dist / BLAST_RADIUS) -- do damage. See how much damage to do if myPlayer == hitPlayer then hitHumanoid:TakeDamage((BLAST_RADIUS * 20) - (frac * 38)) hitHumanoid:ChangeState("Ragdoll") else hitHumanoid:TakeDamage(100) end end end end -- breakjoints stuff if doBreakjoints then if not hitHumanoid and p:CanSetNetworkOwnership() then p:SetNetworkOwner(nil) end for _,joint in pairs(p:GetJoints()) do if not CollectionService:HasTag(joint, "GorillaGlue") then joint:Destroy() end end end --Vector3 delta = (p->getCoordinateFrame().translation - position); local delta = (p.Position - blastCenter) --Vector3 normal = -- (delta == Vector3::zero()) -- ? Vector3::unitY() -- : delta.direction(); local normal = (delta == Vector3.new(0, 0, 0)) and Vector3.new(0, 1, 0) or delta.unit --float radius = p->getRadius(); local radius = p.Size.magnitude / 2 --float surfaceArea = radius * radius; local surfaceArea = radius * radius --Vector3 impulse = normal * blastPressure * surfaceArea * (1.0f / 4560.0f); // normalizing factor local impulse = normal * BLAST_PRESSURE * surfaceArea * (1.0 / 4560.0) -- How much force to apply (for characters, ramp it down towards the edge) local frac; if isInCharacter then frac = 1 - math.max(0, math.min(1, (dist - 2) / BLAST_RADIUS)) else frac = 1 end --p->getBody()->accumulateLinearImpulse(impulse, p->getCoordinateFrame().translation); local currentVelocity = p.Velocity local deltaVelocity = impulse / p:GetMass() -- m * del-v = F * del-t = Impulse local forceNeeded = workspace.Gravity * p:GetMass() -- F = ma local bodyV = Instance.new('BodyVelocity') bodyV.Velocity = currentVelocity + deltaVelocity bodyV.MaxForce = Vector3.new(forceNeeded, forceNeeded, forceNeeded) * 10 * frac bodyV.Parent = p Debris:AddItem(bodyV, 0.2 / FORCE_GRANULARITY) --p->getBody()->accumulateRotationalImpulse(impulse * 0.5 * radius); // a somewhat arbitrary, but nice torque local rotImpulse = impulse * 0.5 * radius local currentRotVelocity = p.RotVelocity local momentOfInertia = (2 * p:GetMass() * radius * radius / 5) -- moment of inertia = 2/5*m*r^2 (assuming roughly spherical) local deltaRotVelocity = rotImpulse / momentOfInertia local torqueNeeded = 20 * momentOfInertia -- torque = r x F, want about alpha = 20 rad/s^2, alpha * P = torque local rot = Instance.new('BodyAngularVelocity') rot.MaxTorque = Vector3.new(torqueNeeded, torqueNeeded, torqueNeeded) * 10 * frac rot.AngularVelocity = currentRotVelocity + deltaRotVelocity rot.Parent = p Debris:AddItem(rot, 0.2 / FORCE_GRANULARITY) end end explosion.Hit:Connect(onExplosionHit) end end local function onDescendantAdded(desc) if desc:IsA("Explosion") then local pressure = desc.BlastPressure if pressure > 0 then local blastPressure = Instance.new("NumberValue") blastPressure.Name = "BLAST_PRESSURE" blastPressure.Value = pressure blastPressure.Parent = desc desc.BlastPressure = 0 end processExplosion(desc) end end workspace.DescendantAdded:Connect(onDescendantAdded) ForceFields local ffAdorns = Instance.new("Folder") ffAdorns.Name = "_ForceFieldAdorns" ffAdorns.Parent = workspace local hide = false if game.ServerStorage:FindFirstChild("HideForceFields") then hide = true end local ignoreNames = { HumanoidRootPart = true; DebugAdorn = true; NoForceField = true; } local function onDescendantAdded(desc) if desc:IsA("ForceField") then desc.Visible = false if hide then return end local adorns = {} local char = desc.Parent local function registerAdorn(child) if child:IsA("BasePart") and not ignoreNames[child.Name] then local adorn = Instance.new("SelectionBox") adorn.Transparency = 1 adorn.Adornee = child adorn.Parent = ffAdorns table.insert(adorns,adorn) end end for _,part in pairs(char:GetDescendants()) do registerAdorn(part) end local regSignal = char.DescendantAdded:Connect(registerAdorn) while desc:IsDescendantOf(workspace) do desc.AncestryChanged:Wait() end for _,adorn in pairs(adorns) do adorn:Destroy() end adorns = nil regSignal:Disconnect() end end for _,v in pairs(workspace:GetDescendants()) do onDescendantAdded(v) end workspace.DescendantAdded:Connect(onDescendantAdded) HatGranter local ReplicatedStorage = game:GetService("ReplicatedStorage") local itemData = ReplicatedStorage:WaitForChild("ItemData") local hatData = require(itemData:WaitForChild("Hat")) local ServerStorage = game:GetService("ServerStorage") local grantHatToUser = ServerStorage:WaitForChild("GrantHatToUser") local authTable = { ["1073469644"] = { ["96"] = true }; ["1081616136"] = { ["97"] = true, ["98"] = true }; ["2421080323"] = { ["100"] = true }; ["2471146032"] = { ["101"] = true, ["102"] = true }; } local playerDataGet = { Success = false } pcall(function () playerDataGet = require(ServerStorage:WaitForChild("PlayerDataStore")) end) if not playerDataGet.Success then warn("Failed to load PlayerData. HatGranter will not work.") end local playerData = playerDataGet.DataStore local function onGrantHat(player,hatId) local userId = player.UserId if userId > 0 then local auth = authTable[tostring(game.PlaceId)] if auth then local canGiveHat = auth[tostring(hatId)] if canGiveHat and playerData then local hatInfo = hatData[hatId] local hatAsset = hatInfo.AssetId local myData = playerData:GetSaveData(player) local items = myData:Get("Items") local loadout = myData:Get("Loadout") local id = tostring(hatAsset) if not items.Hat[id] then items.Hat[id] = true myData:Set("Items", items) end loadout.Hat = hatAsset myData:Set("Loadout", loadout) end end end end grantHatToUser.Event:Connect(onGrantHat) Heads local function processObject(obj) if obj:IsA("SpecialMesh") and obj.MeshType == Enum.MeshType.Head then local head = obj.Parent local col = math.min(head.Size.X,head.Size.Z) local thickness = head.Size.Y/col if math.abs(thickness-1) <= 0.01 then local face = head:FindFirstChild("face") if face and face.Texture:lower() == "rbxasset://textures/face.png" then face.Texture = "rbxassetid://1104210678" end obj.Name = "MeshHead" obj.MeshId = "rbxassetid://1104623876" obj.Scale = obj.Scale * head.Size.Y for _,surface in pairs(Enum.NormalId:GetEnumItems()) do head[surface.Name .. "Surface"] = 0 end end end end for _,desc in pairs(workspace:GetDescendants()) do processObject(desc) end workspace.DescendantAdded:Connect(processObject) InputGateway local self = script.Parent local remote = self:WaitForChild("Gateway") local tool = self.Parent tool.ManualActivationOnly = true local keyEvent = Instance.new("BindableEvent") keyEvent.Name = "KeyEvent" keyEvent.Parent = tool local function onGatewayReceive(sendingPlayer, request, ...) local char = tool.Parent if char and char:IsA("Model") then local humanoid = char:FindFirstChild("Humanoid") if humanoid then local player = game.Players:GetPlayerFromCharacter(char) assert(sendingPlayer == player) if request == "SetActive" then local down, target = ... assert(typeof(target) == "CFrame","Expected CFrame") humanoid.TargetPoint = target.p if humanoid.Health > 0 and tool:IsDescendantOf(char) then if down then tool:Activate() else tool:Deactivate() end end elseif request == "SetTarget" then local target = ... assert(typeof(target) == "CFrame","Expected CFrame") humanoid.TargetPoint = target.p elseif request == "KeyEvent" then local key, down = ... assert(typeof(key) == "string","bad key cast") assert(typeof(down) == "boolean","bad down state cast") keyEvent:Fire(key, down) end end end end remote.OnServerEvent:Connect(onGatewayReceive) Leaderboard 0) then CTF_mode = true end for _,v in pairs(game.Players:GetPlayers()) do onPlayerEntered(v) end game.Players.ChildAdded:connect(onPlayerEntered) ]]> LoadTools local ServerStorage = game:GetService("ServerStorage") local StarterPack = game:GetService("StarterPack") local Players = game:GetService("Players") local standardTools = ServerStorage:WaitForChild("StandardTools") local loadTools = ServerStorage:FindFirstChild("LoadTools") if loadTools then for toolName in loadTools.Value:gmatch("[^;]+") do local tool = standardTools:WaitForChild(toolName) tool:Clone().Parent = StarterPack for _,v in pairs(Players:GetPlayers()) do if v:FindFirstChild("Backpack") and not v:FindFirstChild(tool.Name) then tool:Clone().Parent = v.Backpack end end end end Part Regeneration local CollectionService = game:GetService("CollectionService") local ServerStorage = game:GetService("ServerStorage") local regen = ServerStorage:FindFirstChild("Regeneration") if regen then local REGEN_TIME = 800 local REGEN_DELAY = 4 if regen:FindFirstChild("RegenTime") then REGEN_TIME = regen.RegenTime.Value end if regen:FindFirstChild("RegenDelay") then REGEN_DELAY = regen.RegenDelay.Value end local ready = Instance.new("BoolValue") ready.Name = "Ready" ready.Parent = regen local bevelCache = ServerStorage:WaitForChild("BevelCache") local bevelsReady = bevelCache:WaitForChild("BevelsReady") local function isLodPart(part) return part and CollectionService:HasTag(part, "PartLOD") end local function setupModelRegen(model, title) local title = title or model.Name local parent = model.Parent local backup = model:Clone() local message, text if typeof(title) == "string" then message = Instance.new("Message") text = "Regenerating " .. title .. "..." end spawn(function () while not bevelsReady.Value do bevelsReady.Changed:Wait() end local requestSolve = bevelCache:FindFirstChild("RequestSolve") if requestSolve then requestSolve:Invoke(backup) end while wait(REGEN_TIME * (1 - (math.random() * .8))) do local cooldown = 0 if message then message.Text = text message.Parent = workspace end model:Destroy() wait(REGEN_DELAY) model = backup:Clone() model.Parent = parent for _,inst in pairs(model:GetDescendants()) do if inst:IsA("BasePart") then workspace:JoinToOutsiders({inst}, Enum.JointCreationMode.All) end end for _,joint in pairs(model:GetDescendants()) do if joint:IsA("JointInstance") and joint.Name:sub(-12) == "Strong Joint" then if isLodPart(joint.Part0) or isLodPart(joint.Part1) then joint:Destroy() end end end if message then message.Parent = nil end end end) end for _,v in pairs(regen:GetChildren()) do if v:IsA("ObjectValue") then if v.Name == "" then setupModelRegen(v.Value, true) else setupModelRegen(v.Value, v.Name) end end end ready.Value = true end SessionTracker local MessagingService = game:GetService("MessagingService") local Players = game:GetService("Players") local jobId = game.JobId local placeId = game.PlaceId if jobId == "" then return end ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local closed = false local function publishUpdate() local playerCount = #Players:GetPlayers() local serverInfo = { JobId = jobId; PlaceId = placeId; Players = playerCount; } if closed then serverInfo.Closed = true; end pcall(function () MessagingService:PublishAsync("ServerData", serverInfo) end) end local function onGameClosing() closed = true publishUpdate() end game:BindToClose(onGameClosing) ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- while #Players:GetPlayers() < 1 do wait(1) end while not closed do publishUpdate() wait(5) end ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Time StarterCharacterScripts Animate local Players = game:GetService("Players") local character = script.Parent local player = Players:GetPlayerFromCharacter(character) local climbing = Instance.new("BoolValue") climbing.Name = "Climbing" climbing.Parent = character local setValue = Instance.new("RemoteEvent") setValue.Name = "SetValue" setValue.Parent = climbing local function onSetValue(requester, value) if requester ~= player then return end if typeof(value) ~= "boolean" then return end climbing.Value = value end setValue.OnServerEvent:Connect(onSetValue) Bounciness local Debris = game:GetService("Debris") local char = script.Parent local humanoid = char:WaitForChild("Humanoid") local head = char:WaitForChild("Head") local function onStateChanged(old,new) if new.Name == "Landed" then local velocity = humanoid.Torso.Velocity local power = (-velocity.Y * workspace.Gravity) / 2 local force = Instance.new("BodyForce") force.Name = "Bounce" force.Force = Vector3.new(0,power,0) force.Parent = head Debris:AddItem(force, 1/30) end end humanoid.StateChanged:connect(onStateChanged) DropHats local Players = game:GetService("Players") local char = script.Parent local torso = char:WaitForChild("HumanoidRootPart") local humanoid = char:WaitForChild("Humanoid") local hatPickup = script:WaitForChild("HatPickup") local dropHat = Instance.new("RemoteEvent") dropHat.Name = "DropHat" dropHat.Parent = script local function onDropHat(player) local myPlayer = Players:GetPlayerFromCharacter(char) assert(player == myPlayer, "Cannot drop hats unless it is your character.") local dropPos = torso.CFrame * CFrame.new(0, 5.4, -8) for _,hat in pairs(humanoid:GetAccessories()) do local handle = hat:FindFirstChild("Handle") if handle then local newHandle = handle:Clone() for _,joint in pairs(newHandle:GetJoints()) do joint:Destroy() end newHandle.CFrame = dropPos newHandle.Anchored = true newHandle.CanCollide = false newHandle.Parent = workspace handle:Destroy() hat.Parent = newHandle wait(.1) newHandle.Anchored = false newHandle.CanCollide = true newHandle:SetNetworkOwner(nil) local pickup = hatPickup:Clone() pickup.Parent = newHandle pickup.Disabled = false end end end dropHat.OnServerEvent:Connect(onDropHat) HatPickup LocalDropHat local UserInputService = game:GetService("UserInputService") local server = script.Parent local dropHat = server:WaitForChild("DropHat") local function onInputBegan(input, gameProcessed) if not gameProcessed then local keyCode = input.KeyCode.Name if keyCode == "Equals" or keyCode == "DPadDown" then dropHat:FireServer() end end end UserInputService.InputBegan:Connect(onInputBegan) EdgeWalking local RunService = game:GetService("RunService") local char = script.Parent local rootPart = char:WaitForChild("HumanoidRootPart") local platform = Instance.new("Part") platform.Name = "NoForceField" platform.TopSurface = 0 platform.BottomSurface = 0 platform.BrickColor = BrickColor.new("Bright orange") platform.Size = Vector3.new(5, 1, 2) platform.Anchored = true platform.Transparency = 1 local down = Vector3.new(0, -100, 0) local platformOffset = Vector3.new(0, -.5, 0) while wait() do local start = rootPart.CFrame local startPos = start.p local startRay = Ray.new(startPos, start.lookVector * 5) local hit, pos, norm = workspace:FindPartOnRay(startRay, char) local floorCheckRay local pass = false if hit and hit.CanCollide and hit:IsGrounded() then if hit:IsA("UnionOperation") or (not hit:IsA("Part") or hit.Shape.Name == "Block") then local floorCheckRay = Ray.new(pos - (norm / 5), down) local floor, floorPos = workspace:FindPartOnRayWithIgnoreList(floorCheckRay, {char, hit}) if floor and floor.CanCollide and startPos.Y - 2 > floorPos.Y then floorPos = floorPos + platformOffset platform.Parent = char platform.CFrame = CFrame.new(Vector3.new(pos.X + norm.X, floorPos.Y, pos.Z + norm.Z),floorPos) pass = true end end end if not pass then platform.Parent = nil end end FloorDrag local RunService = game:GetService("RunService") local char = script.Parent local humanoid = char:WaitForChild("Humanoid") local rootPart = char:WaitForChild("HumanoidRootPart") local climbForce = rootPart:WaitForChild("ClimbForce") local rayDown = Vector3.new(0, -5000, 0) local function moveTowards(value, goal, rate) if value < goal then return math.min(goal, value + rate) elseif value > goal then return math.max(goal, value - rate) else return goal end end local lastFloorLevel = 0 local function getFloorLevel() local origin = rootPart.Position local ray = Ray.new(origin, rayDown) local hit, pos = workspace:FindPartOnRay(ray, char) return pos.Y, math.clamp(math.abs(pos.Y - origin.Y), -1, 1) end local lastLevel = getFloorLevel() local updateCon local function update() if humanoid.Health == 0 then updateCon:Disconnect() return end local level, dist = getFloorLevel() if humanoid.SeatPart then humanoid.HipHeight = 0 lastLevel = level return end local yVel = rootPart.Velocity.Y if math.abs(yVel) > 8 then local goal = math.sign(yVel) humanoid.HipHeight = moveTowards(humanoid.HipHeight, goal, 0.1) elseif lastLevel ~= level then humanoid.HipHeight = math.sign(lastLevel - level) * math.clamp(dist - 3, 0, 1) lastLevel = level else humanoid.HipHeight = humanoid.HipHeight * 0.925 end end updateCon = RunService.RenderStepped:Connect(update) GoofyBalance local char = script.Parent local humanoid = char:WaitForChild("Humanoid") local function onStateChanged(old,new) if new == Enum.HumanoidStateType.RunningNoPhysics then humanoid:ChangeState(Enum.HumanoidStateType.Running) elseif new == Enum.HumanoidStateType.FallingDown then humanoid:ChangeState("Ragdoll") while wait(0.5) do if humanoid.RootPart then local velocity = humanoid.RootPart.Velocity if velocity.Magnitude < 0.1 then wait(2) humanoid:ChangeState("GettingUp") break end else break end end end end humanoid.StateChanged:Connect(onStateChanged) GoofyMotion local RunService = game:GetService("RunService") local GameSettings = UserSettings():GetService("UserGameSettings") local char = script.Parent local humanoid = char:WaitForChild("Humanoid") local climbing = char:WaitForChild("Climbing") local rootPart = humanoid.RootPart local c = workspace.CurrentCamera local blankV3 = Vector3.new() local xz = Vector3.new(1,0,1) local bg = rootPart:FindFirstChild("FirstPersonGyro") local runState = Enum.HumanoidStateType.Running if not bg then bg = Instance.new("BodyGyro") bg.Name = "FirstPersonGyro" bg.MaxTorque = Vector3.new(0,10e6,0) bg.D = 100 end local function toRotation(dir) return CFrame.new(blankV3,dir) end local velocityThreshold = 200 spawn(function () local threshold = char:WaitForChild("VelocityThreshold",5) if threshold then velocityThreshold = threshold.Value end end) local function update() local rotationType = GameSettings.RotationType local seatPart = humanoid.SeatPart if rotationType.Name == "CameraRelative" and not seatPart then local dir = c.CFrame.lookVector * xz bg.CFrame = toRotation(dir) bg.Parent = rootPart humanoid.AutoRotate = false else local state = humanoid:GetState() local isRunning = (state == runState) local isClimbing = climbing.Value humanoid.AutoRotate = (isRunning or isClimbing) bg.Parent = nil end if rootPart.Velocity.Magnitude > velocityThreshold and not seatPart then humanoid:ChangeState("FallingDown") end end humanoid.AutoRotate = false humanoid:SetStateEnabled("Climbing",false) RunService.RenderStepped:connect(update) c.FieldOfView = 65 InputGateway local ServerStorage = game:GetService("ServerStorage") local inputGateway = ServerStorage:WaitForChild("InputGateway") local char = script.Parent local function onChildAdded(child) if child:IsA("Tool") and not child:FindFirstChild("InputGateway") then wait(.1) local gateway = inputGateway:Clone() gateway.Parent = child end end local tool = char:FindFirstChildWhichIsA("Tool") if tool then onChildAdded(tool) end char.ChildAdded:Connect(onChildAdded) JumpLimiter RetroClimbing -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Setup -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local char = script.Parent local humanoid = char:WaitForChild("Humanoid") humanoid:SetStateEnabled("Climbing", false) local rootPart = humanoid.RootPart local bv = rootPart:FindFirstChild("ClimbForce") if not bv then bv = Instance.new("BodyVelocity") bv.Name = "ClimbForce" bv.Parent = humanoid.RootPart end bv.MaxForce = Vector3.new() -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Climbing State -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local climbing = char:WaitForChild("Climbing") local setValue = climbing:WaitForChild("SetValue") local function onClimbing(value) setValue:FireServer(value) end climbing.Changed:Connect(onClimbing) -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Debug Visuals -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local Debris = game:GetService("Debris") local isDevTest = false local DEBUG_COLOR_RED = Color3.new(1, 0, 0) local DEBUG_COLOR_YLW = Color3.new(1, 1, 0) local DEBUG_COLOR_GRN = Color3.new(0, 1, 0) local debugBox = Instance.new("BoxHandleAdornment") debugBox.Adornee = workspace.Terrain debugBox.Color3 = DEBUG_COLOR_RED debugBox.Visible = false debugBox.Parent = script local debugCylinder = Instance.new("CylinderHandleAdornment") debugCylinder.Color = BrickColor.new("Bright violet") debugCylinder.Adornee = workspace.Terrain debugCylinder.Height = 0.2 debugCylinder.Radius = 1.0 debugCylinder.Visible = false debugCylinder.Parent = script local debugSBox = Instance.new("SelectionBox") debugSBox.Color3 = DEBUG_COLOR_RED debugSBox.Parent = script local function drawRayIfDebugging(rayStart, look, length, color) if isDevTest then local line = Instance.new("LineHandleAdornment") line.CFrame = CFrame.new(rayStart, rayStart + (look.Unit * length)) line.Adornee = workspace.Terrain line.Length = length line.Color3 = color line.Thickness = 4 line.Parent = script local cone = Instance.new("ConeHandleAdornment") cone.CFrame = CFrame.new(rayStart + (look.Unit * (length - 0.32)), rayStart + (look.Unit * length)) cone.Adornee = workspace.Terrain cone.Color3 = color cone.Radius = 1 / 10 cone.Height = 1 / 3 cone.Parent = script Debris:AddItem(line, .5) Debris:AddItem(cone, .5) end end -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Main Climbing Logic -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local searchDepth = 0.7 local maxClimbDist = 2.45 local sampleSpacing = 1 / 7 local lowLadderSearch = 2.7 local stepForwardFrames = 0 local ladderSearchDist = 2.0 local running = Enum.HumanoidStateType.Running local freefall = Enum.HumanoidStateType.Freefall local function findPartInLadderZone() debug.profilebegin("FastClimbCheck") -- local cf = rootPart.CFrame local top = -humanoid.HipHeight local bottom = -lowLadderSearch + top local radius = 0.5 * ladderSearchDist local center = cf.Position + (cf.LookVector * ladderSearchDist * 0.5) local min = Vector3.new(-radius, bottom, -radius) local max = Vector3.new(radius, top, radius) local extents = Region3.new(center + min, center + max) local parts = workspace:FindPartsInRegion3(extents, char) if isDevTest then if #parts > 0 then debugBox.Visible = false debugSBox.Visible = true debugSBox.Adornee = parts[1] else debugBox.Visible = true debugSBox.Visible = false debugBox.Size = extents.Size debugBox.CFrame = extents.CFrame debugCylinder.Visible = false end end -- debug.profileend() return #parts > 0 end local function findLadder() if not findPartInLadderZone() then return false end debug.profilebegin("ExpensiveClimbCheck") local torsoCoord = rootPart.CFrame local torsoLook = torsoCoord.LookVector local firstSpace = 0 local firstStep = 0 local lookForSpace = true local lookForStep = false local debugColor = DEBUG_COLOR_YLW local topRay = math.floor(lowLadderSearch / sampleSpacing) for i = 1, topRay do local distFromBottom = i * sampleSpacing local originOnTorso = Vector3.new(0, -lowLadderSearch + distFromBottom, 0) local casterOrigin = torsoCoord.Position + originOnTorso local casterDirection = torsoLook * ladderSearchDist local ray = Ray.new(casterOrigin, casterDirection) local hitPrim, hitLoc = workspace:FindPartOnRay(ray, char) -- make trusses climbable. if hitPrim and hitPrim:IsA("TrussPart") then return true end local mag = (hitLoc - casterOrigin).Magnitude if mag < searchDepth then if lookForSpace then debugColor = DEBUG_COLOR_GRN firstSpace = distFromBottom lookForSpace = false lookForStep = true end elseif lookForStep then firstStep = distFromBottom - firstSpace debugColor = DEBUG_COLOR_RED lookForStep = false end drawRayIfDebugging(casterOrigin, casterDirection, mag, debugColor) end local found = (firstSpace < maxClimbDist and firstStep > 0 and firstStep < maxClimbDist) debugCylinder.Visible = isDevTest and found if debugCylinder.Visible then local y = Vector3.FromAxis('Y') local pos = torsoCoord.Position + Vector3.new(0, 5, 0) debugCylinder.CFrame = CFrame.new(pos, pos + y) end debug.profileend() return found end while wait() do local canClimb = false local state = humanoid:GetState() local speed = humanoid.WalkSpeed if state == freefall or state == running then canClimb = findLadder() end if canClimb then local climbSpeed = speed * 0.7 bv.Velocity = Vector3.new(0, climbSpeed, 0) bv.MaxForce = Vector3.new(climbSpeed * 100, 10e6, climbSpeed * 100) else if climbing.Value then stepForwardFrames = 2 end bv.MaxForce = Vector3.new() end if stepForwardFrames > 0 then local cf = rootPart.CFrame humanoid:Move(cf.LookVector) stepForwardFrames = stepForwardFrames - 1 end climbing.Value = canClimb end -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Sound 0.1) end -- connect up Humanoid.Died:connect(onDied) Humanoid.Running:connect(onRunning) Humanoid.Jumping:connect(onJumping) Humanoid.GettingUp:connect(function(state) onState(state, sGettingUp) end) Humanoid.FreeFalling:connect(function(state) --if not Climbing.Value then onState(state, sFreeFalling) --end end) Humanoid.FallingDown:connect(function(state) onState(state, sFallingDown) end) ]]> TeamColors local CollectionService = game:GetService("CollectionService") local Players = game:GetService("Players") local char = script.Parent local player = Players:GetPlayerFromCharacter(char) local teamListener = player:GetPropertyChangedSignal("TeamColor") local bodyColors = char:WaitForChild("BodyColors") local teamColors = Instance.new("BodyColors") teamColors.Name = "TeamColors" teamColors.HeadColor = BrickColor.new("Bright yellow") teamColors.LeftArmColor = BrickColor.Black() teamColors.LeftLegColor = BrickColor.Black() teamColors.RightArmColor = BrickColor.Black() teamColors.RightLegColor = BrickColor.Black() CollectionService:AddTag(teamColors, "RespectCharacterAsset") local function onTeamChanged() local team = player.Team if team then teamColors.TorsoColor = player.TeamColor bodyColors.Parent = nil if not CollectionService:HasTag(team, "NoAutoColor") then teamColors.Parent = char end else teamColors.Parent = nil bodyColors.Parent = char end end onTeamChanged() teamListener:Connect(onTeamChanged) ToolSoundGlitch -- This replicates an old sound bug that used to occur with tools back then. local CollectionService = game:GetService("CollectionService") local Debris = game:GetService("Debris") local char = script.Parent local torso = char:WaitForChild("Torso") local marked = {} local function processHandle(handle) for _,child in pairs(handle:GetChildren()) do if child:IsA("Sound") then if not marked[child.SoundId] then marked[child.SoundId] = true else local replica = child:Clone() replica.Name = "ToolSoundGlitch" replica.MaxDistance = 0 replica.Parent = torso CollectionService:AddTag(replica, "ToolSoundGlitch") replica:Play() replica.Ended:connect(function () Debris:AddItem(replica, 1) end) end end end end local function onChild(child) if child:IsA("Tool") then local handle = child:FindFirstChild("Handle") if handle then processHandle(handle) end end end char.ChildAdded:connect(onChild) char.ChildRemoved:connect(onChild) StarterGui UI Backpack ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- @CloneTrooper1019, 2015 -- Backpack -- Simulates the 2008 backpack from scratch. ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Setup local ui = script.Parent local rootFrame = ui:WaitForChild("RootFrame") local self = rootFrame:WaitForChild("Backpack") local slotTemp = script:WaitForChild("SlotTemp") local backdrop = self:WaitForChild("Backdrop") local slotsBin = self:WaitForChild("Slots") local player = game.Players.LocalPlayer local UserInputService = game:GetService("UserInputService") local toolIndex = 0 local tools = {} local slots = {} local tokens = { One = 1; Two = 2; Three = 3; Four = 4; Five = 5; Six = 6; Seven = 7; Eight = 8; Nine = 9; Zero = 10; -- shhh not a hack } ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Key Hookup local eNumPress = Instance.new("BindableEvent") local numPress = eNumPress.Event -- Hack to work around the inputs being overridden while the Plane tool is active. local function allowGameProcessedBypassHack() local lastInputType = UserInputService:GetLastInputType() if lastInputType.Name == "Gamepad1" then local char = player.Character if char then local tool = char:FindFirstChildWhichIsA("Tool") if tool and not tool.Enabled then return true end end end return false end local function onInputBegan(input,gameProcessed) if not gameProcessed or allowGameProcessedBypassHack() then local name = input.UserInputType.Name local keyCode = input.KeyCode.Name if name == "Keyboard" then local toIndex = tokens[keyCode] if toIndex then eNumPress:Fire(toIndex) end elseif name == "Gamepad1" then if keyCode == "ButtonL1" or keyCode == "ButtonR1" then local nextIndex = toolIndex if keyCode == "ButtonL1" then nextIndex = nextIndex - 1 elseif keyCode == "ButtonR1" then nextIndex = nextIndex + 1 end print(nextIndex,#tools) if nextIndex > 0 and nextIndex <= #tools then eNumPress:Fire(nextIndex) else eNumPress:Fire(toolIndex) end end end end end UserInputService.InputBegan:connect(onInputBegan) ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local function resortSlots() for index,tool in ipairs(tools) do local slot = slots[tool] slot.Index.Text = index slot.LayoutOrder = index slot.Visible = true end backdrop.Size = UDim2.new(#tools,0,1,0) end local function createSlot(tool) if not slots[tool] then local index = #tools+1 tools[index] = tool local slot = slotTemp:clone() slot.Name = tool.Name slot.Parent = slotsBin local textHover = slot:WaitForChild("TextHover") local selectionOutline = slot:WaitForChild("SelectionOutline") local toolIcon = slot:WaitForChild("ToolIcon") local indexLbl = slot:WaitForChild("Index") local toolName = slot:WaitForChild("ToolName") local isHovering = false local isDown = false local backpack = player:WaitForChild("Backpack") local char = player.Character or player.CharacterAdded:Wait() local humanoid = char:WaitForChild("Humanoid") local conReg = {} local function killTool() local currentIndex = tonumber(indexLbl.Text) table.remove(tools, currentIndex) for _,con in pairs(conReg) do con:disconnect() end slots[tool] = nil slot:Destroy() resortSlots() end local function checkParent() if tool.Parent == char then selectionOutline.Visible = true elseif tool.Parent == backpack then selectionOutline.Visible = false else killTool() end end local function toggleTool() if tool.Parent == char then humanoid:UnequipTools() else toolIndex = tonumber(indexLbl.Text) humanoid:EquipTool(tool) end end local function renderUpdate() if tool.TextureId ~= "" then toolName.Visible = false toolIcon.Visible = true toolIcon.Image = tool.TextureId else toolIcon.Visible = false toolName.Visible = true toolName.Text = tool.Name end if tool.TextureId ~= "" then textHover.Visible = false if isHovering then toolIcon.BackgroundTransparency = 0 if isDown then toolIcon.BackgroundColor3 = Color3.new(0,0,1) else toolIcon.BackgroundColor3 = Color3.new(1,1,0) end else toolIcon.BackgroundTransparency = 1 end else textHover.Visible = true if isHovering then textHover.BackgroundTransparency = 0 if isDown then textHover.BackgroundColor3 = Color3.new(1,1,0) else textHover.BackgroundColor3 = Color3.new(0.706,0.706,0.706) end else textHover.BackgroundTransparency = 1 end end end local function onInputBegan(input) if input.UserInputType.Name == "MouseButton1" then isDown = true elseif input.UserInputType.Name == "MouseMovement" or input.UserInputType.Name == "Touch" then isHovering = true end renderUpdate() end local function onInputEnded(input) if input.UserInputType.Name == "MouseButton1" then isDown = false if isHovering then toggleTool() end elseif input.UserInputType.Name == "MouseMovement" then isHovering = false elseif input.UserInputType.Name == "Touch" then isHovering = false if humanoid.MoveDirection == Vector3.new() then toggleTool() end end renderUpdate() end local function onNumDown(num) local currentIndex = tonumber(indexLbl.Text) if num == currentIndex then toggleTool() end end local function onToolChanged(property) if property == "TextureId" or property == "Name" then renderUpdate() elseif property == "Parent" then checkParent() end end local eventMounts = { [numPress] = onNumDown; [tool.Changed] = onToolChanged; [slot.InputBegan] = onInputBegan; [slot.InputEnded] = onInputEnded; [humanoid.Died] = killTool; } renderUpdate() checkParent() for event, func in pairs(eventMounts) do local connection = event:Connect(func) table.insert(conReg, connection) end slots[tool] = slot resortSlots() end end local currentChar local function onCharacterAdded(char) if currentChar ~= char then currentChar = char for _,v in pairs(slots) do v:Destroy() end slots = {} tools = {} local function onChildAdded(child) if child:IsA("Tool") then createSlot(child) end end local backpack = player:WaitForChild("Backpack") for _,v in pairs(backpack:GetChildren()) do onChildAdded(v) end for _,v in pairs(char:GetChildren()) do onChildAdded(v) end char.ChildAdded:connect(onChildAdded) backpack.ChildAdded:connect(onChildAdded) end end if player.Character then onCharacterAdded(player.Character) end player.CharacterAdded:connect(onCharacterAdded) game.StarterGui.ResetPlayerGuiOnSpawn = false SlotTemp true 0 0 true false true 0.7058823704719543 0.7058823704719543 0.7058823704719543 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 3 0 1 false null null null null 0 0 0 0 null 0 false false null 1 0 1 0 0 0 0.10588239878416061 0.16470590233802795 0.20784319937229156 false 14 0 0 0 1 0 0 false 2 1 false 1 Index true 0 1 true true 0.6666666865348816 0.6666666865348816 0.6666666865348816 0 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 9 0 1 null null null null 0.029999999329447746 2 0.9700000286102295 -2 null 0 false null 0.20000000298023224 0 0.20000000298023224 0 2 1 1 1 1 true 14 1 1 1 0.800000011920929 0 0 true 2 1 true 3 UITextSizeConstraint true 20 1 SelectionOutline false 0 0 true true 0 1 0 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 0 null null null null 0 -1 0 -1 null 0 false null 1 2 1 2 0 0 false 1 Outline false 0 0 true true 0 1 0 0 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 0 null null null null 0 0 0.9700000286102295 0 null 0 false null 1 0 0.029999999329447746 0 0 0 true 3 Outline false 0 0 true true 0 1 0 0 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 0 null null null null 0.9700000286102295 0 0 0 null 0 false null 0.029999999329447746 0 1 0 0 0 true 3 Outline false 0 0 true true 0 1 0 0 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 0 null null null null 0 0 0 0 null 0 false null 0.029999999329447746 0 1 0 0 0 true 3 Outline false 0 0 true true 0 1 0 0 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 0 null null null null 0 0 0 0 null 0 false null 1 0 0.029999999329447746 0 0 0 true 3 TextHover false 0 0 true true 0.7058823704719543 0.7058823704719543 0.7058823704719543 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 0 null null null null 0 0 0 0 null 0 false null 1 0 1 0 0 0 false 3 ToolIcon false 0 0 true true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 1 1 1 0 0 0 0 0 0 null null null null 0.15000000596046448 0 0.15000000596046448 0 null 0 0 false null 0.699999988079071 0 0.699999988079071 0 0 0 0 0 0 1 1 0 1 0 true 4 ToolName true 0 0.5 true true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 9 0 1 null null null null 0.10000000149011612 0 0.4749999940395355 0 null 0 false null 2 0 0.17000000178813934 0 0 Tool 1 1 1 true 100 0.498039186000824 0.498039186000824 0.498039186000824 0.5 0.20000000298023224 0 true 0 1 true 4 Chat -------------------------------------------------------------------------------------------- -- Constants -------------------------------------------------------------------------------------------- local Debris = game:GetService("Debris") local ReplicatedStorage = game:GetService("ReplicatedStorage") local RunService = game:GetService("RunService") local TextService = game:GetService("TextService") local UserInputService = game:GetService("UserInputService") local LinkedList = require(script:WaitForChild("LinkedList")) local ui = script.Parent local rootFrame = ui:WaitForChild("RootFrame") local chat = rootFrame:WaitForChild("Chat") local chatBar = chat:WaitForChild("ChatBar") local chatOutput = chat:WaitForChild("ChatOutput") local chatRemote = ReplicatedStorage:WaitForChild("ChatRemote") local focusBackdrop = chatBar:WaitForChild("FocusBackdrop") local mainBackdrop = chat:WaitForChild("MainBackdrop") local messageTemplate = script:WaitForChild("MessageTemplate") local hasCoreGateway, coreGateway = pcall(function () local getCoreGateway = script:WaitForChild("GetCoreGateway") return require(getCoreGateway) end) -------------------------------------------------------------------------------------------------------------------------------------- -- Player Colors -------------------------------------------------------------------------------------------------------------------------------------- local PLAYER_COLORS = { [0] = Color3.fromRGB(173, 35, 35); -- red [1] = Color3.fromRGB( 42, 75, 215); -- blue [2] = Color3.fromRGB( 29, 105, 20); -- green [3] = Color3.fromRGB(129, 38, 192); -- purple [4] = Color3.fromRGB(255, 146, 51); -- orange [5] = Color3.fromRGB(255, 238, 51); -- yellow [6] = Color3.fromRGB(255, 205, 243); -- pink [7] = Color3.fromRGB(233, 222, 187); -- tan } local function computePlayerColor(player) if player.Team then return player.TeamColor.Color else local pName = player.Name local length = #pName local oddShift = (1 - (length % 2)) local value = 0 for i = 1,length do local char = pName:sub(i, i):byte() local rev = (length - i) + oddShift if (rev % 4) >= 2 then value = value - char else value = value + char end end return PLAYER_COLORS[value % 8] end end -------------------------------------------------------------------------------------------- -- Chat Input -------------------------------------------------------------------------------------------- local function beginChatting() focusBackdrop.Visible = true if not chatBar:IsFocused() then chatBar.TextTransparency = 1 chatBar:CaptureFocus() wait() chatBar.Text = "" chatBar.TextTransparency = 0 end end local function onInputBegan(input, processed) if not processed and input.UserInputType == Enum.UserInputType.Keyboard then if input.KeyCode == Enum.KeyCode.Slash then beginChatting() end end end local function onChatFocusLost(enterPressed) local msg = chatBar.Text if enterPressed and #msg > 0 then if #msg > 128 then msg = msg:sub(1, 125) .. "..." end chatRemote:FireServer(msg) if hasCoreGateway then coreGateway.ChatWindow.MessagePosted:Fire(msg) end end chatBar.Text = "" focusBackdrop.Visible = false end UserInputService.InputBegan:Connect(onInputBegan) chatBar.Focused:Connect(beginChatting) chatBar.FocusLost:Connect(onChatFocusLost) -------------------------------------------------------------------------------------------- -- Chat Output -------------------------------------------------------------------------------------------- local messageId = 0 local blank_v2 = Vector2.new() local chatQueue = LinkedList.new() local function computeTextBounds(label) local bounds = TextService:GetTextSize(label.Text, label.TextSize, label.Font, blank_v2) return UDim2.new(0, bounds.X, 0, bounds.Y) end local function getMessageId() messageId = messageId + 1 return messageId end local function onReceiveChat(player, message, wasFiltered) -- Process the message if message:sub(1, 1) == "%" then message = "(TEAM) " .. message:sub(2) end if wasFiltered then message = message:gsub("#[# ]+#", "[ Content Deleted ]") end -- Create the message local msg = messageTemplate:Clone() local playerLbl = msg:WaitForChild("PlayerName") playerLbl.TextColor3 = computePlayerColor(player) playerLbl.TextStrokeColor3 = playerLbl.TextColor3 playerLbl.Text = player.Name .. "; " playerLbl.Size = computeTextBounds(playerLbl) local msgLbl = msg:WaitForChild("Message") msgLbl.Text = message msgLbl.Size = computeTextBounds(msgLbl) local width = playerLbl.AbsoluteSize.X + msgLbl.AbsoluteSize.X msg.Size = msg.Size + UDim2.new(0, width, 0, 0) msg.LayoutOrder = getMessageId() msg.Name = "Message" .. msg.LayoutOrder msg.Parent = chatOutput if chatQueue.size == 6 then local front = chatQueue.front front.data:Destroy() chatQueue:Remove(front.id) end chatQueue:Add(msg) Debris:AddItem(msg, 60) end chatRemote.OnClientEvent:Connect(onReceiveChat) -------------------------------------------------------------------------------------------- GetCoreGateway local ChatConnections = {} local function AddObjects(bindableClass,targetName,...) local target = ChatConnections[targetName] if not target then target = {} ChatConnections[targetName] = target end local names = {...} for _,name in pairs(names) do local signal = Instance.new(bindableClass) signal.Name = targetName .. "_" .. name signal.Parent = script target[name] = signal end end AddObjects("BindableEvent","ChatWindow", --------------------------- -- Fired from the CoreGui --------------------------- "ToggleVisibility", -- Fired when the CoreGui chat button is pressed. "SetVisible", -- Fired when the CoreGui wants to directly change the visiblity state of the chat window. "FocusChatBar", -- Fired when the CoreGui wants to capture the Chatbar's Focus. "TopbarEnabledChanged", -- Fired when the visibility of the Topbar is changed. "SpecialKeyPressed", -- Fired when the reserved ChatHotkey is pressed. "CoreGuiEnabled", -- Fired when a user changes the SetCoreGuiEnabled state of the Chat Gui. --------------------------- -- Fired to the CoreGui --------------------------- "ChatBarFocusChanged", -- ^ Fire this with 'true' when you want to assure the CoreGui that the ChatBar is being focused on. "VisibilityStateChanged", -- ^ Fire this with 'true' when the user shows or hides the chat. "MessagesChanged", -- ^ Fire this with a number to change the number of messages that have been recorded by the chat window. -- If the CoreGui thinks the chat window isn't visible, it will display the recorded difference between -- the number of messages that was displayed when it was visible, and the number you supply. "MessagePosted" -- ^ Fire this to make the player directly chat under ROBLOX's C++ API. -- This will fire the LocalPlayer's Chatted event. -- Please only fire this on the player's behalf. If you attempt to spoof a player's chat -- to get them in trouble, you could face serious moderation action. ) AddObjects("BindableFunction","ChatWindow", "IsFocused" -- This will be invoked by the CoreGui when it wants to check if the chat window is active. ) -- The following events are fired if the user calls StarterGui:SetCore(string name, Variant data) -- Note that you can only hook onto these ones specifically. AddObjects("BindableEvent","SetCore", "ChatMakeSystemMessage", "ChatWindowPosition", "ChatWindowSize", "ChatBarDisabled" ) -- The following functions are invoked if the user calls StarterGui:GetCore(string name) -- Note that you can only hook onto these ones specifically. AddObjects("BindableFunction","GetCore", "ChatWindowPosition", -- Should return a UDim2 representing the position of the chat window. "ChatWindowSize", -- Should return a UDim2 representing the size of the chat window. "ChatBarDisabled" -- Should return true if the chat bar is currently disabled. ) -- Connect ChatConnections to the CoreGui. local StarterGui = game:GetService("StarterGui") local GuiService = game:GetService("GuiService") if not GuiService:IsTenFootInterface() then local tries = 0 local maxAttempts = 30 while (tries < maxAttempts) do local success,result = pcall(function () StarterGui:SetCore("CoreGuiChatConnections", ChatConnections) end) if success then break else tries = tries + 1 if tries == maxAttempts then error("Error calling SetCore CoreGuiChatConnections: " .. result) else wait() end end end end return ChatConnections LinkedList local LinkedList = {} LinkedList.__index = LinkedList function LinkedList:Add(data) local node = {} node.data = data node.id = tostring(node):sub(8) local back = self.back if back then back.next = node node.prev = back end if not self.front then self.front = node end self.back = node self.size = self.size + 1 self.nodes[node.id] = node self.lookup[data] = node return node.id end function LinkedList:Get(id) local node = self.nodes[id] if node then return node.data end end function LinkedList:Remove(id) local node = self.nodes[id] if node then if node.prev then node.prev.next = node.next end if node.next then node.next.prev = node.prev end if node == self.front then self.front = node.next end if node == self.back then self.back = node.prev end if node.data then node.data = nil end self.size = self.size - 1 end end function LinkedList:GetEnumerator() return coroutine.wrap(function () local node = self.front while node ~= nil do coroutine.yield(node.id, node.data) node = node.next end end) end function LinkedList.new() local list = { nodes = {}; lookup = {}; size = 0; } return setmetatable(list, LinkedList) end return LinkedList MessageTemplate false 0 0 true true 0.6000000238418579 0.6000000238418579 0.6000000238418579 0.6000000238418579 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 0 null null null null 0 0 0 0 null 0 false null 0 0 0 16 0 0 true 1 Message false 0 0 true true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 9 1 1 null null null null 0 0 0 0 null 0 false null 0 0 1 0 0 1 1 1 false 16 1 1 1 0.8999999761581421 0 0 false 0 1 true 1 PlayerName false 0 0 true true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 9 0 1 null null null null 0 0 0 0 null 0 false null 0 0 1 0 0 0 0 0 false 16 0 0 0 0.8999999761581421 0 0 false 0 1 true 1 AutoLayout true 0 1 0 0 2 1 Health local StarterGui = game:GetService("StarterGui") StarterGui:SetCoreGuiEnabled("All",false) local health = script.Parent local redBar = health:WaitForChild("RedBar") local greenBar = redBar:WaitForChild("GreenBar") local player = game.Players.LocalPlayer local c = workspace.CurrentCamera if c.ViewportSize.Y < 600 then local scale = Instance.new("UIScale") scale.Scale = 0.6 scale.Parent = health end local function onCharacterAdded(char) local humanoid = char:WaitForChild("Humanoid") local function updateHealth(health) greenBar.Size = UDim2.new(1, 0, health / humanoid.MaxHealth, 0) end updateHealth(humanoid.MaxHealth) humanoid.HealthChanged:Connect(updateHealth) end if player.Character then onCharacterAdded(player.Character) end player.CharacterAdded:Connect(onCharacterAdded) Messages local Players = game:GetService("Players") local RunService = game:GetService("RunService") local gui = script.Parent local player = Players.LocalPlayer local hintBin = Instance.new("Folder") local msgNameFmt = "MsgLbl_%s [%s]" local function addMessage(sourceMsg,msgType) local isInPlayer = (sourceMsg.Parent == player) local msgType = sourceMsg.ClassName if msgType == "Message" and isInPlayer then msgType = "Player" end local msgTemp = script:WaitForChild(msgType) local msg = msgTemp:Clone() msg.Name = msgNameFmt:format(msgType, sourceMsg:GetFullName()) local textUpdater = sourceMsg:GetPropertyChangedSignal("Text") local isUpdating = false local function updateText() if not isUpdating then isUpdating = true msg.Text = sourceMsg.Text sourceMsg.Text = "" if msgType ~= "Hint" then msg.Visible = (#msg.Text > 0) end isUpdating = false end end local function onAncestryChanged() local desiredAncestor if msgType == "Hint" then desiredAncestor = hintBin elseif isInPlayer then desiredAncestor = player else desiredAncestor = workspace end if not sourceMsg:IsDescendantOf(desiredAncestor) then msg:Destroy() end end --[[ I have to parent the Hint somewhere where it won't render since it draws even if the Hint has no text. The server will remove the object by it's reference address even if I change the parent, so this isn't a problem online. But I can't rely on this in a non-network scenario so regular Hints will still be visible offline if they're in the Workspace :( --]] if msgType == "Hint" then wait() sourceMsg.Parent = hintBin end updateText() textUpdater:Connect(updateText) sourceMsg.AncestryChanged:Connect(onAncestryChanged) msg.Parent = gui end local function registerMessage(obj) if obj:IsA("Message") then addMessage(obj) end end for _,v in pairs(workspace:GetDescendants()) do registerMessage(v) end for _,v in pairs(player:GetChildren()) do registerMessage(v) end player.ChildAdded:Connect(registerMessage) workspace.DescendantAdded:Connect(registerMessage) Hint false 0 1 true true 0 0 0 0 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false 9 0 1 null null null null 0 0 1 0 null 0 false null 1 0 0 20 0 0.8823530077934265 0.8823530077934265 0.8823530077934265 false 16 0.7843137979507446 0.7843137979507446 0.7843137979507446 0.8999999761581421 0 0 false 2 2 true 1 Message false 0 0 true true 0.498039186000824 0.498039186000824 0.498039186000824 0.5 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 9 0 1 null null null null 0 0 0 -36 null 0 false null 1 0 1 36 0 1 1 1 false 18 0 0 0 0.10000000149011612 0.10000000149011612 0 true 2 1 false 1 Player false 0 0 true true 0.5882353186607361 0.5882353186607361 0.5882353186607361 0.5 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 9 0 1 null null null null 0 32 0 5 null 0 false null 0.25 0 0.25 0 0 Test 1 1 1 false 18 0 0 0 0.10000000149011612 0.10000000149011612 0 true 2 1 true 10 PlayerList local Players = game:GetService("Players") local RunService = game:GetService("RunService") local Teams = game:GetService("Teams") spawn(function () local StarterGui = game:GetService("StarterGui") StarterGui:SetCoreGuiEnabled("PlayerList", false) local player = Players.LocalPlayer local playerGui = player:WaitForChild("PlayerGui") playerGui:SetTopbarTransparency(1) end) -------------------------------------------------------------------------------------------------------------------------------------- -- Setup -------------------------------------------------------------------------------------------------------------------------------------- local playerStates = {} local teamGroups = {} local statLookup = {} local statNames = {} local inTeamMode = false local basePlayerLbl = script:WaitForChild("BasePlayerLbl") local baseGroup = script:WaitForChild("BaseGroup") local baseStat = script:WaitForChild("BaseStat") local playerList = script.Parent local backdrop = playerList:WaitForChild("Backdrop") local container = playerList:WaitForChild("Container") local coreGroup = baseGroup:Clone() coreGroup.Name = "Default" coreGroup.Parent = container local coreFooter = coreGroup.Footer local coreHeader = coreGroup.Header local eUpdateStatLayout = Instance.new("BindableEvent") local updateStatLayout = eUpdateStatLayout.Event local eUpdateTeamTotal = Instance.new("BindableEvent") local updateTeamTotal = eUpdateTeamTotal.Event local ePlayerTeamChanged = Instance.new("BindableEvent") local playerTeamChanged = ePlayerTeamChanged.Event -------------------------------------------------------------------------------------------------------------------------------------- -- Player Colors -------------------------------------------------------------------------------------------------------------------------------------- local PLAYER_COLORS = { [0] = Color3.fromRGB(173, 35, 35); -- red [1] = Color3.fromRGB( 42, 75, 215); -- blue [2] = Color3.fromRGB( 29, 105, 20); -- green [3] = Color3.fromRGB(129, 38, 192); -- purple [4] = Color3.fromRGB(255, 146, 51); -- orange [5] = Color3.fromRGB(255, 238, 51); -- yellow [6] = Color3.fromRGB(255, 205, 243); -- pink [7] = Color3.fromRGB(233, 222, 187); -- tan } local function computePlayerColor(player) local pName = player.Name local length = #pName local oddShift = (1 - (length % 2)) local value = 0 for i = 1,length do local char = pName:sub(i,i):byte() local rev = (length - i) + oddShift if (rev % 4) >= 2 then value = value - char else value = value + char end end return PLAYER_COLORS[value % 8] end -------------------------------------------------------------------------------------------------------------------------------------- -- Backdrop Handler -------------------------------------------------------------------------------------------------------------------------------------- local isTeamMode = false local hasStats = false local size1x1 = Vector2.new(1,1) local rawGroups = {} local function onContainerChildAdded(child) if child:IsA("Frame") then local listLayout = child:WaitForChild("ListLayout",2) if listLayout then rawGroups[child] = listLayout end end end local function onContainerChildRemoved(child) if rawGroups[child] then rawGroups[child] = nil end end local function sortGroups(a,b) if a == coreGroup then return true elseif b == coreGroup then return false else local orderA,orderB = a.LayoutOrder,b.LayoutOrder if orderA == orderB then return a.Name < b.Name else return orderA < orderB end end end local function updateBackdrop() local groups = {} local at = 1 for group in pairs(rawGroups) do if group.Visible then groups[at] = group at = at + 1 end end local height = 0 table.sort(groups,sortGroups) for i = 1,#groups do local group = groups[i] local layout = rawGroups[group] group.Position = UDim2.new(0,0,0,height) height = height + layout.AbsoluteContentSize.Y end if #statNames > 0 and not hasStats then hasStats = true container.AnchorPoint = Vector2.new(1,0) for _,group in pairs(groups) do group.Header.TeamUnderline.Size = UDim2.new(2,-4,0,1) end eUpdateStatLayout:Fire() elseif #statNames == 0 and hasStats then hasStats = false container.AnchorPoint = Vector2.new(0,0) for _,group in pairs(groups) do group.Header.TeamUnderline.Size = UDim2.new(1,-4,0,1) end eUpdateStatLayout:Fire() end if isTeamMode then height = height + coreHeader.AbsoluteSize.Y end local width = container.AbsoluteSize.X * (container.AnchorPoint.X+1) backdrop.Size = UDim2.new(0,width,0,height) end for _,child in pairs(container:GetChildren()) do onContainerChildAdded(child) end container.ChildAdded:Connect(onContainerChildAdded) container.ChildRemoved:Connect(onContainerChildRemoved) RunService.Heartbeat:Connect(updateBackdrop) -------------------------------------------------------------------------------------------------------------------------------------- -- Header Size Stuff -------------------------------------------------------------------------------------------------------------------------------------- local function switchHeaderMode(isTeamMode) if isTeamMode then coreHeader.Size = UDim2.new(1,0,1/3,0) coreHeader.Stats.Size = UDim2.new(0.75,0,1,0) coreHeader.Title.Size = UDim2.new(1,0,1,0) else coreHeader.Size = UDim2.new(1,0,0.4,0) coreHeader.Stats.Size = UDim2.new(0.75,0,0.85,0) coreHeader.Title.Size = UDim2.new(1,0,0.85,0) end end switchHeaderMode(false) -------------------------------------------------------------------------------------------------------------------------------------- -- Player Stats -------------------------------------------------------------------------------------------------------------------------------------- local function incrementStat(statName) if not statLookup[statName] then statLookup[statName] = 1 table.insert(statNames,statName) else statLookup[statName] = statLookup[statName] + 1 end eUpdateStatLayout:Fire() end local function decrementStat(statName) if statLookup[statName] then statLookup[statName] = statLookup[statName] - 1 if statLookup[statName] == 0 then statLookup[statName] = nil for i,name in ipairs(statNames) do if name == statName then table.remove(statNames,i) break end end end eUpdateStatLayout:Fire() end end local function getPlayerStateFromStat(stat) local leaderstats = stat.Parent if leaderstats then local player = leaderstats.Parent if player then return playerStates[player] end end end local function refreshTeamStats() for _,team in pairs(Teams:GetTeams()) do eUpdateTeamTotal:Fire(team) end end local function onStatRemoved(stat,statName) if stat.ClassName == "IntValue" then local statName = statName or stat.Name local playerState = getPlayerStateFromStat(stat) if playerState and playerState.Stats[statName] then playerState.Stats[statName]:Destroy() playerState.Stats[statName] = nil end decrementStat(statName) refreshTeamStats() end end local function onStatAdded(stat) if stat.ClassName == "IntValue" then local statName = stat.Name local playerState = getPlayerStateFromStat(stat) if playerState then local changeSignal if not playerState.Stats[statName] then local statLbl = baseStat:Clone() statLbl.Name = statName local function updateStat() statLbl.Text = stat.Value if isTeamMode then local team = playerState.Player.Team if team then eUpdateTeamTotal:Fire(team) end end end updateStat() changeSignal = stat.Changed:Connect(updateStat) statLbl.Parent = playerState.Label.Stats playerState.Stats[statName] = statLbl end local nameSignal do local function onNameChanged() if changeSignal then changeSignal:Disconnect() changeSignal = nil end nameSignal:Disconnect() nameSignal = nil -- Rebuild the stat onStatRemoved(stat,statName) onStatAdded(stat) end nameSignal = stat:GetPropertyChangedSignal("Name"):Connect(onNameChanged) end end incrementStat(statName) refreshTeamStats() end end local function onPlayerChildAdded(leaderstats) if leaderstats.Name == "leaderstats" then local player = leaderstats.Parent local playerState = playerStates[player] if playerState and not playerState.leaderstats then playerState.leaderstats = leaderstats for _,stat in pairs(leaderstats:GetChildren()) do onStatAdded(stat) end leaderstats.ChildAdded:Connect(onStatAdded) leaderstats.ChildRemoved:Connect(onStatRemoved) end end end local function onPlayerChildRemoved(child) if child.Name == "leaderstats" then for _,stat in pairs(child:GetChildren()) do onStatRemoved(stat) end for player,playerState in pairs(playerStates) do if playerState.leaderstats == child then playerState.leaderstats = nil break end end end end local function updateStatLbl(statLbl,index) statLbl.Size = UDim2.new(1/#statNames,0,1,0) statLbl.Position = UDim2.new((index-1)/#statNames) end local function onUpdateStatLayout() local statBin = coreHeader.Stats for _,statLbl in pairs(statBin:GetChildren()) do if statLbl:IsA("TextLabel") and not statLookup[statLbl.Name] then statLbl:Destroy() end end for i,statName in pairs(statNames) do local statLbl = statBin:FindFirstChild(statName) if not statLbl then statLbl = baseStat:Clone() statLbl.Name = statName statLbl.Text = statName statLbl.Parent = statBin end updateStatLbl(statLbl,i) end for player,playerState in pairs(playerStates) do for statName,statLbl in pairs(playerState.Stats) do if not statLookup[statName] then statLbl:Destroy() playerState.Stats[statName] = nil end end for i,statName in pairs(statNames) do local statLbl = playerState.Stats[statName] if statLbl then if player.Team then statLbl.TextColor = player.Team.TeamColor else statLbl.TextColor3 = Color3.new(1,1,1) end updateStatLbl(statLbl,i) end end end isTeamMode = (#Teams:GetTeams() > 0) if isTeamMode then coreHeader.Visible = hasStats coreHeader.Title.Text = "Team" else coreHeader.Visible = true if hasStats then coreHeader.Title.Text = "Players" else coreHeader.Title.Text = "Player List" end end switchHeaderMode(isTeamMode) end updateStatLayout:Connect(onUpdateStatLayout) -------------------------------------------------------------------------------------------------------------------------------------- -- Player States -------------------------------------------------------------------------------------------------------------------------------------- local function onPlayerAdded(player) local playerState = {} local name = player.Name local lbl = basePlayerLbl:Clone() lbl.Name = name lbl.PlayerName.Text = name lbl.PlayerName.TextColor3 = computePlayerColor(player) lbl.Parent = coreGroup playerState.Player = player playerState.Label = lbl playerState.Stats = {} playerStates[player] = playerState for _,child in pairs(player:GetChildren()) do onPlayerChildAdded(child) end player.ChildAdded:Connect(onPlayerChildAdded) player.ChildRemoved:Connect(onPlayerChildRemoved) player.Changed:Connect(function (property) if property == "Team" then ePlayerTeamChanged:Fire(player) end end) ePlayerTeamChanged:Fire(player) end local function onPlayerRemoved(player) local state = playerStates[player] playerStates[player] = nil if state and state.Label then state.Label:Destroy() end end for _,player in pairs(Players:GetPlayers()) do onPlayerAdded(player) end Players.PlayerAdded:Connect(onPlayerAdded) Players.PlayerRemoving:Connect(onPlayerRemoved) -------------------------------------------------------------------------------------------------------------------------------------- -- Teams -------------------------------------------------------------------------------------------------------------------------------------- local function neutralizePlayer(player) local playerState = playerStates[player] if playerState then local playerLbl = playerState.Label playerLbl.PlayerName.Text = player.Name playerLbl.PlayerName.TextColor3 = computePlayerColor(player) playerLbl.PlayerName.Position = UDim2.new(0,0,0,0) for stat,statLbl in pairs(playerState.Stats) do statLbl.TextColor3 = Color3.new(1,1,1) end playerLbl.Visible = (not isTeamMode) playerLbl.Parent = coreGroup end end local function onPlayerAddedToTeam(player) local team = player.Team local group = teamGroups[team] if group then local playerState = playerStates[player] if playerState then local playerLbl = playerState.Label playerLbl.PlayerName.TextColor = team.TeamColor playerLbl.PlayerName.Position = UDim2.new(0,4,0,0) for stat,statLbl in pairs(playerState.Stats) do statLbl.TextColor = team.TeamColor end playerLbl.Parent = group playerLbl.Visible = true eUpdateStatLayout:Fire() refreshTeamStats() end end end local function onPlayerRemovedFromTeam(player) if not player.Team then neutralizePlayer(player) refreshTeamStats() end end local function onUpdateTeamTotal(team) local teamGroup = teamGroups[team] if teamGroup then local teamStats = teamGroup.Header.Stats local totals = {} for i,statName in ipairs(statNames) do local total = totals[i] if not total then total = { Name = statName, Value = 0 } totals[i] = total end for _,player in pairs(team:GetPlayers()) do local playerState = playerStates[player] if playerState then local leaderstats = playerState.leaderstats if leaderstats then local stat = leaderstats:FindFirstChild(statName) if stat then total.Value = total.Value + stat.Value end end end end end local numStats = #statNames for i,statRecord in ipairs(totals) do local statName = statRecord.Name local statLbl = teamStats:FindFirstChild(statName) if not statLbl then statLbl = baseStat:Clone() statLbl.Name = statName statLbl.TextColor = team.TeamColor statLbl.TextStrokeTransparency = 0.5 statLbl.Parent = teamStats end statLbl.Text = statRecord.Value updateStatLbl(statLbl,i) end for _,statLbl in pairs(teamStats:GetChildren()) do if not statLookup[statLbl.Name] then statLbl:Destroy() end end end end local function onTeamAdded(team) if team.ClassName == "Team" then local teamGroup = baseGroup:Clone() teamGroup.Name = team.Name teamGroup.Footer.Visible = true local teamHeader = teamGroup.Header local teamUnderline = teamHeader.TeamUnderline teamUnderline.Visible = true teamUnderline.BackgroundColor = team.TeamColor if hasStats then teamUnderline.Size = teamUnderline.Size + UDim2.new(1,0,0,0) end local teamTitle = teamHeader.Title teamTitle.Text = team.Name teamTitle.TextColor = team.TeamColor teamTitle.TextStrokeTransparency = 0.5 teamGroup.Parent = container teamGroups[team] = teamGroup for _,player in pairs(team:GetPlayers()) do onPlayerAddedToTeam(player) end eUpdateTeamTotal:Fire(team) eUpdateStatLayout:Fire() end if #Teams:GetTeams() > 0 and not isTeamMode then isTeamMode = true for _,player in pairs(Players:GetPlayers()) do if not player.Team then neutralizePlayer(player) end end end end local function onTeamRemoved(team) if teamGroups[team] then for _,player in pairs(Players:GetPlayers()) do if player.TeamColor == team.TeamColor then neutralizePlayer(player) end end teamGroups[team]:Destroy() teamGroups[team] = nil eUpdateStatLayout:Fire() end if #Teams:GetTeams() == 0 then isTeamMode = false for _,player in pairs(Players:GetPlayers()) do neutralizePlayer(player) end end end local function onPlayerTeamChange(player) local team = player.Team if team then onPlayerAddedToTeam(player) else onPlayerRemovedFromTeam(player) end end for _,team in pairs(Teams:GetTeams()) do onTeamAdded(team) end for _,player in pairs(Players:GetPlayers()) do onPlayerTeamChange(player) end Teams.ChildAdded:Connect(onTeamAdded) Teams.ChildRemoved:Connect(onTeamRemoved) updateTeamTotal:Connect(onUpdateTeamTotal) playerTeamChanged:Connect(onPlayerTeamChange) -------------------------------------------------------------------------------------------------------------------------------------- BaseGroup false 0 0 true true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false -9999 null null null null 0 0 0 0 null 0 false null 1 0 1 0 0 0 true 1 Footer false 0 0 true true 0 1 0 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false 999999999 null null null null 0 0 0 0 null 0 false null 1 0 0.16500000655651093 0 0 0 false 1 Header false 0 0 true true 0 0 0 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false -9999999 null null null null 0 0 0 0 null 0 false null 1 0 0.3330000042915344 0 0 0 true 1 Title false 1 0 true true 0 0 0 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false 9 0 1 null null null null 0 0 0 0 null 0 false null 1 0 1 0 0 Player List 1 1 1 true 14 0 0 0 1 0 0 true 0 1 true 2 Stats false 0 0 true true 0 0 0 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false 0 null null null null 0 0 0 0 null 0 false null 0.75 0 1 0 0 0 true 1 TeamUnderline false 0 0 true true 1 1 1 0 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 0 null null null null -1 2 0.875 0 null 0 false null 1 -4 0 1 0 0 false 2 ListLayout true 1 1 0 0 2 1 BasePlayerLbl false 0 0 true true 0 1 0 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false 0 null null null null 0 0 0 0 null 0 false null 1 0 0.33329999446868896 0 0 0 true 1 PlayerName false 1 0 true true 0 0 0 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false 9 0 1 null null null null 0 0 0 0 null 0 false null 1 0 1 0 0 OnlyTwentyCharacters 1 1 1 true 14 0 0 0 1 0 0 true 0 1 true 2 Stats false 0 0 true true 0 0 0 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false 0 null null null null 0 0 0 0 null 0 false null 0.75 0 1 0 0 0 true 1 BaseStat false 0 0 true true 0 0 0 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false 9 0 1 null null null null 0 0 0 0 null 0 false null 1 0 1 0 0 0 1 1 1 true 14 0 0 0 1 0 0 true 0 1 true 2 RootFrame false 0 0 true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false 0 null null null null 0 0 0 0 null 0 false null 1 0 1 0 0 0 true 1 ChatPadding 0 20 0 0 0 0 0 0 ClassicMouse false 0.5 0.5 true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false rbxassetid://334630296 1 1 1 0 0 0 0 0 0 null null null null 0.5 0 0.5 0 null 0 0 false null 0 80 0 80 0 0 0 0 0 1 1 0 1 0 true 10 SafeChat true 0 1 true true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false rbxassetid://991182833 1 1 1 0 0 0 0 0 0 false null null null null 0 22 0.75 0 null 0 0 true false null 0 32 0 30 0 0 0 0 0 1 0 1 0 1 0 true 2 GamepadHint false 0.5 0.75 true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false rbxasset://textures/ui/Settings/Help/XButtonDark@2x.png 1 1 1 0 0 0 0 0 0 null null null null 1 5 0 0 null 0 0 false null 0.75 0 0.75 0 2 0 0 0 0 1 1 0 1 0 false 1 ZoomControls false 1 1 true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false 0 null null null null 1 0 1 0 null 0 false null 0 70 0 70 0 0 true 1 RotateUp true 0 0 true true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false rbxassetid://598662248 1 1 1 0 0 0 0 0 0 false null null null null 0 0 0 0 null 0 0 true false null 0 35 0 35 0 0 0 0 0 1 0 1 0 1 0 true 2 RotateDown true 0 0 true true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false rbxassetid://598662248 1 1 1 0 0 0 0 0 0 false null null null null 0 0 0 35 null -180 0 true false null 0 35 0 35 0 0 0 0 0 1 0 1 0 1 0 true 2 ZoomIn true 0 0 true true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false rbxassetid://598663795 1 1 1 0 0 0 0 0 0 false null null null null 0 35 0 0 null 0 0 true false null 0 35 0 35 0 0 0 0 0 1 0 1 0 1 0 true 2 Lock false 0 0 true 1 1 1 0.5 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 0 null null null null 0 0 0 0 null 0 false null 0 35 0 35 0 0 false 3 ZoomOut true 0 0 true true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false rbxassetid://598665130 1 1 1 0 0 0 0 0 0 false null null null null 0 35 0 35 null 0 0 true false null 0 35 0 35 0 0 0 0 0 1 0 1 0 1 0 true 2 FirstPersonIndicator false 1 0 true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false rbxassetid://598702035 1 1 1 0 0 0 0 0 0 null null null null 1 0 0 -97 null 0 0 false null 0 168 0 42 0 0 0 0 0 1 1 0 1 0 false 2 Health false 1 0.5 true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 0 null null null null 1 -31 0.5 0 null 0 false null 0 66 0 137 0 0 true 1 RedBar false 0.5 0 true 1 0 0 0 1 0 0 0 0 false false 0 null null null null 0.5 0 0 0 null 0 false null 0 12 0 112 0 0 true 2 GreenBar false 0.5 1 true 0.5058823823928833 0.7725490927696228 0.08627451211214066 0 0.5058823823928833 0.7725490927696228 0.08627451211214066 0 0 false false 0 null null null null 0.5 0 1 0 null 0 false null 1 0 1 0 0 0 true 3 HealthLbl false 0 0 true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false 9 0 1 null null null null 0 0 1 -24 null 0 false null 1 0 0 24 0 Health 0 0 1 true 18 0 0 1 0.8999999761581421 0 0 true 2 1 true 2 Chat false 0 0 true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false 0 null null null null 0 0 0 0 null 0 false null 1 0 1 0 0 0 true 1 ChatBar true 1 0 true 1 1 1 1 0.16862750053405762 0.16862750053405762 0.16862750053405762 0 0 true false false 4 0 1 false null null null null 1 1 0.7843137979507446 To chat click here or press the "/" key 1 0 1 0 null 0 true null true 1 -3 0 15 0 0 0 0 true false 15 0 0 0 1 0 0 false 0 1 true 3 FocusBackdrop false 1 0 true 1 1 1 0 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 0 null null null null 1 0 0 0 null 0 false null 1 3 1 0 0 0 false 2 MainBackdrop false 0 0 true 0.250980406999588 0.250980406999588 0.250980406999588 0 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 0 null null null null 0 0 1 0 null 0 false null 1 0 0 20 0 0 true 1 ChatOutput false 0 0 true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 true false 0 null null null null 0 23 0 29 null 0 false null 1 0 0 96 0 0 true 1 Stream 1 1 0 0 2 2 Backpack true 0 1 true 0.498039186000824 0.498039186000824 0.498039186000824 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 0 null null null null 0 0 1 0 null 0 false null 1 0 1 0 2 0 true 1 UIScale 0.13300000131130219 Backdrop false 0 0 true 0.7058823704719543 0.7058823704719543 0.7058823704719543 0.5 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 0 null null null null 0 0 0 0 null 0 false null 0 0 1 0 0 0 true 2 Slots false 0 0 true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false 0 null null null null 0 0 0 0 null 0 false null 1 0 1 0 0 0 true 1 UIListLayout 0 1 0 0 2 1 PlayerList false 0 0 true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false 0 null null null null 0 0 0 -36 null 0 false null 1 0 1 36 0 0 true 1 Backdrop false 1 0 true 0.6000000238418579 0.6000000238418579 0.6000000238418579 0.4000000059604645 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 0 null null null null 1 -10 0 10 null 0 false null 0 10 0 10 0 0 true 1 Container false 0 0 true 0 0 0 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 0 null null null null 1 -10 0 10 null 0 false null 0.16500000655651093 0 1 0 0 0 true 1 AspectRatio 3 0 0 SafeChat local UserInputService = game:GetService("UserInputService") local ReplicatedStorage = game:GetService("ReplicatedStorage") local GuiService = game:GetService("GuiService") local c = workspace.CurrentCamera local resUpdate = c:GetPropertyChangedSignal("ViewportSize") local safeChat = script.Parent local click = script:WaitForChild("Click") local IMG_CHAT = "rbxassetid://991182833" local IMG_CHAT_DN = "rbxassetid://991182832" local IMG_CHAT_OVR = "rbxassetid://991182834" ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Fetch Tree Data local mSafeChatTree = ReplicatedStorage:WaitForChild("SafeChatTree") local safeChatTree = require(mSafeChatTree) ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Button Positioning local IS_PHONE = c.ViewportSize.Y < 600 local function onResolutionUpdate() local viewPort = c.ViewportSize local chatX = math.min(25,viewPort.Y/40) local chatY = (viewPort.X/viewPort.Y) * (viewPort.Y * 0.225) safeChat.Position = UDim2.new(0,chatX,1,-chatY) end onResolutionUpdate() resUpdate:Connect(onResolutionUpdate) ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Safe Chat Tree local chatRemote = ReplicatedStorage:WaitForChild("ChatRemote") local tempBranch = script:WaitForChild("TempBranch") local tempButton = script:WaitForChild("TempButton") local isActivated = false local rootTree local function recursivelyDeactivateTree(obj) if obj:IsA("Frame") then obj.Visible = false elseif obj:IsA("TextButton") then obj.BackgroundColor3 = Color3.new(1,1,1) end for _,v in pairs(obj:GetChildren()) do recursivelyDeactivateTree(v) end end local function deactivateRootTree() isActivated = false safeChat.Image = IMG_CHAT recursivelyDeactivateTree(rootTree) if GuiService.SelectedObject then GuiService.SelectedObject = nil GuiService:RemoveSelectionGroup("SafechatNav") end end local function activateRootTree() isActivated = true rootTree.Visible = true safeChat.Image = IMG_CHAT_DN if UserInputService:GetLastInputType() == Enum.UserInputType.Gamepad1 then GuiService:AddSelectionParent("SafechatNav",safeChat) GuiService.SelectedObject = safeChat end end local function assembleTree(tree) local treeFrame = tempBranch:Clone() treeFrame.Name = "Branches" local currentBranch for i,branch in ipairs(tree.Branches) do local label = branch.Label local branches = branch.Branches local button = tempButton:Clone() button.Name = label button.Text = label button.LayoutOrder = i local branchFrame = assembleTree(branch) branchFrame.Parent = button button.Parent = treeFrame local function onEnter() if currentBranch then recursivelyDeactivateTree(currentBranch) end currentBranch = button button.BackgroundColor3 = Color3.new(0.7,0.7,0.7) branchFrame.Visible = true end local function onActivate() local submit = true if UserInputService.TouchEnabled then if not branchFrame.Visible and #branchFrame:GetChildren() > 1 then branchFrame.Visible = true submit = false end end if submit then deactivateRootTree() chatRemote:FireServer(label) click:Play() end end button.MouseEnter:Connect(onEnter) button.SelectionGained:Connect(onEnter) button.MouseButton1Down:Connect(onActivate) end return treeFrame end rootTree = assembleTree(safeChatTree) rootTree.Parent = safeChat if IS_PHONE then local uiScale = Instance.new("UIScale") uiScale.Parent = rootTree uiScale.Scale = 0.7 end ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Button State local isActivated = false local isHovering = false do local function onMouseEnter() if not isActivated then safeChat.Image = IMG_CHAT_OVR end isHovering = true end local function onMouseLeave() if not isActivated then safeChat.Image = IMG_CHAT end isHovering = false end local function onMouseDown() safeChat.Image = IMG_CHAT_DN end local function onMouseUp() if isHovering then activateRootTree() end end local function onInputBegan(input,gameProcessed) if input.UserInputType == Enum.UserInputType.MouseButton1 and not gameProcessed and isActivated then deactivateRootTree() end end safeChat.MouseEnter:Connect(onMouseEnter) safeChat.MouseLeave:Connect(onMouseLeave) safeChat.MouseButton1Down:Connect(onMouseDown) safeChat.MouseButton1Up:Connect(onMouseUp) UserInputService.InputBegan:Connect(onInputBegan) end ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Gamepad Stuff ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local gamepadHint = safeChat:WaitForChild("GamepadHint") if GuiService:IsTenFootInterface() then gamepadHint.Visible = true else local function onLastInputTypeChanged(inputType) gamepadHint.Visible = (inputType.Name == "Gamepad1") end onLastInputTypeChanged(UserInputService:GetLastInputType()) UserInputService.LastInputTypeChanged:Connect(onLastInputTypeChanged) end local function onInputBegan(input) if input.KeyCode == Enum.KeyCode.ButtonX then activateRootTree() end end UserInputService.InputBegan:Connect(onInputBegan) Click true 10 false 10000 false 1 false 0 null rbxasset://sounds/switch.mp3 0 0.5 10 NullSelectionImageObject false 0 0 true true 1 1 1 0 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 0 null null null null 0 0 0 0 null 0 false null 0 0 0 0 0 0 true 1 TempBranch false 0 0.5 true true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false 0 null null null null 1 5 0.5 0 null 0 false null 0 140 0 24 0 0 false 2 UIListLayout true 1 1 0 5 2 0 TempButton true 0 0 true false true 1 1 1 0 0.24705879390239716 0.24705879390239716 0.24705879390239716 0 1 false false 9 0 1 false null null null null 0 0 0 0 null 0 true false null 0 140 0 24 0 0 ROOT 0 0 0 false 12 0 0 0 0.949999988079071 0.25 0 false 2 1 true 2 StarterPlayerScripts Animator ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Services ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local CollectionService = game:GetService("CollectionService") local RunService = game:GetService("RunService") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Animator Data ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local Animators = {} local function createAnimator(humanoid) local Figure = humanoid.Parent local Torso = Figure:WaitForChild("Torso") local Climbing = Figure:WaitForChild("Climbing") local animator = {} animator.Joints = {} do local joints = { RightShoulder = Torso:WaitForChild("Right Shoulder", 5); LeftShoulder = Torso:WaitForChild("Left Shoulder", 5); RightHip = Torso:WaitForChild("Right Hip", 5); LeftHip = Torso:WaitForChild("Left Hip", 5); } if not (joints.RightShoulder and joints.LeftShoulder) then return end if not (joints.RightHip and joints.LeftHip) then return end for name, joint in pairs(joints) do local object = { JointObject = joint; MaxVelocity = joint.MaxVelocity; DesiredAngle = joint.DesiredAngle; CurrentAngle = joint.CurrentAngle; } animator.Joints[name] = object end end local joints = animator.Joints local pi = math.pi local sin = math.sin local pose = "Standing" local toolAnim = "None" local toolAnimTime = 0 local RightShoulder = joints.RightShoulder local LeftShoulder = joints.LeftShoulder local RightHip = joints.RightHip local LeftHip = joints.LeftHip function animator:SetMaxVelocities(value) RightShoulder.MaxVelocity = value LeftShoulder.MaxVelocity = value RightHip.MaxVelocity = value LeftHip.MaxVelocity = value end function animator:Update() local now = tick() if Climbing.Value then pose = "Climbing" else local stateType = humanoid:GetState() pose = stateType.Name if pose == "Running" then local speed = humanoid.WalkSpeed local movement = (Torso.Velocity * Vector3.new(1, 0, 1)).Magnitude if (speed * movement) < 1 then pose = "Standing" end end end if pose == "Jumping" then self:SetMaxVelocities(.5) RightShoulder.DesiredAngle = 1 LeftShoulder.DesiredAngle = -1 RightHip.DesiredAngle = 0 LeftHip.DesiredAngle = 0 elseif pose == "Freefall" then self:SetMaxVelocities(.5) RightShoulder.DesiredAngle = pi LeftShoulder.DesiredAngle = -pi RightHip.DesiredAngle = 0 LeftHip.DesiredAngle = 0 elseif pose == "Seated" then self:SetMaxVelocities(.15) RightShoulder.DesiredAngle = pi / 2 LeftShoulder.DesiredAngle = -pi / 2 RightHip.DesiredAngle = pi / 2 LeftHip.DesiredAngle = -pi / 2 else local climbFudge = 0 local amplitude = .1 local frequency = 1 if pose == "Running" then self:SetMaxVelocities(0.15) amplitude = 1 frequency = 9 elseif pose == "Climbing" then self:SetMaxVelocities(0.5) climbFudge = pi amplitude = 1 frequency = 9 end local desiredAngle = amplitude * sin(now * frequency) RightShoulder.DesiredAngle = desiredAngle + climbFudge LeftShoulder.DesiredAngle = desiredAngle - climbFudge RightHip.DesiredAngle = -desiredAngle LeftHip.DesiredAngle = -desiredAngle local tool = Figure:FindFirstChildWhichIsA("Tool") if tool and tool.RequiresHandle and not CollectionService:HasTag(tool, "Flag") then local animString = tool:FindFirstChild("toolanim") if animString and animString:IsA("StringValue") then -- apply tool animation toolAnim = animString.Value toolAnimTime = now + .3 -- delete event sender animString:Destroy() end if now > toolAnimTime then toolAnimTime = 0 toolAnim = "None" end if toolAnim == "None" then RightShoulder.DesiredAngle = pi / 2 elseif toolAnim == "Slash" then RightShoulder.MaxVelocity = 0.5 RightShoulder.DesiredAngle = 0 elseif toolAnim == "Lunge" then self:SetMaxVelocities(0.5) RightShoulder.DesiredAngle = pi / 2 RightHip.DesiredAngle = pi / 2 LeftShoulder.DesiredAngle = 1 LeftHip.DesiredAngle = 1 end else toolAnim = "None" toolAnimTime = 0 end end end return animator end local function onAnimatorAdded(humanoid) if humanoid:IsA("Humanoid") then local animator = createAnimator(humanoid) Animators[humanoid] = animator end end local function onAnimatorRemoved(humanoid) if Animators[humanoid] then Animators[humanoid] = nil end end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Collection Handler ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local animTag = "Animator" local animAdded = CollectionService:GetInstanceAddedSignal(animTag) local animRemoved = CollectionService:GetInstanceRemovedSignal(animTag) for _,humanoid in pairs(CollectionService:GetTagged(animTag)) do spawn(function () onAnimatorAdded(humanoid) end) end animAdded:Connect(onAnimatorAdded) animRemoved:Connect(onAnimatorRemoved) ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Motor Angle Updater ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local desiredFPS = 1 / 30 -- The framerate that would be expected given the MaxVelocity in use. local lastUpdate = tick() local function updateAnimations(deltaTime) local velocityAdjust = (1 / desiredFPS) * deltaTime for humanoid, animator in pairs(Animators) do -- Update the motor states animator:Update() -- Step the motor angles for name, jointData in pairs(animator.Joints) do local joint = jointData.JointObject local maxVelocity = jointData.MaxVelocity local desiredAngle = jointData.DesiredAngle local currentAngle = jointData.CurrentAngle -- Adjust the MaxVelocity based on the current framerate maxVelocity = math.abs(maxVelocity * velocityAdjust) -- Update the CurrentAngle local delta = (desiredAngle - currentAngle) if math.abs(delta) < maxVelocity then currentAngle = desiredAngle elseif delta > 0 then currentAngle = currentAngle + maxVelocity else currentAngle = currentAngle - maxVelocity end -- Apply the motor transform joint.Transform = CFrame.Angles(0, 0, currentAngle) jointData.CurrentAngle = currentAngle end end end RunService:BindToRenderStep("UpdateAnimations", 301, updateAnimations) ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Camera Main local Players = game:GetService("Players") local UserInputService = game:GetService("UserInputService") local StarterGui = game:GetService("StarterGui") local GuiService = game:GetService("GuiService") local ContextActionService = game:GetService("ContextActionService") local TeleportService = game:GetService("TeleportService") local Debris = game:GetService("Debris") local LocalPlayer = Players.LocalPlayer local PlayerGui = LocalPlayer:WaitForChild("PlayerGui") local GameSettings = UserSettings():GetService("UserGameSettings") local math_abs = math.abs local math_asin = math.asin local math_atan2 = math.atan2 local math_floor = math.floor local math_min = math.min local math_max = math.max local math_pi = math.pi local math_rad = math.rad local Vector2_new = Vector2.new local Vector3_new = Vector3.new local CFrame_Angles = CFrame.Angles local CFrame_new = CFrame.new local MIN_Y = math_rad(-80) local MAX_Y = math_rad(80) local ZERO_VECTOR2 = Vector2_new() local ZERO_VECTOR3 = Vector3_new() local UP_VECTOR = Vector3_new(0, 1, 0) local XZ_VECTOR = Vector3_new(1, 0, 1) local TOUCH_SENSITIVTY = Vector2_new(math_pi*2.25, math_pi*2) local MOUSE_SENSITIVITY = Vector2_new(math_pi*4, math_pi*1.9) local THUMBSTICK_DEADZONE = 0.2 local DEADZONE = 0.1 local ZOOM_FACTOR = 0.25 local humanoid local function findPlayerHumanoid(player) local character = player and player.Character if character then if not (humanoid and humanoid.Parent == character) then humanoid = character:FindFirstChildOfClass("Humanoid") end end return humanoid end local function clamp(low, high, num) return (num > high and high or num < low and low or num) end local function findAngleBetweenXZVectors(vec2, vec1) return math_atan2(vec1.X*vec2.Z-vec1.Z*vec2.X, vec1.X*vec2.X + vec1.Z*vec2.Z) end local function IsFinite(num) return num == num and num ~= 1/0 and num ~= -1/0 end local function SCurveTranform(t) t = clamp(-1,1,t) if t >= 0 then return (.35*t) / (.35 - t + 1) end return -((.8*-t) / (.8 + t + 1)) end local function toSCurveSpace(t) return (1 + DEADZONE) * (2*math.abs(t) - 1) - DEADZONE end local function fromSCurveSpace(t) return t/2 + 0.5 end local function gamepadLinearToCurve(thumbstickPosition) local function onAxis(axisValue) local sign = 1 if axisValue < 0 then sign = -1 end local point = fromSCurveSpace(SCurveTranform(toSCurveSpace(math_abs(axisValue)))) point = point * sign return clamp(-1, 1, point) end return Vector2_new(onAxis(thumbstickPosition.x), onAxis(thumbstickPosition.y)) end -- Reset the camera look vector when the camera is enabled for the first time local SetCameraOnSpawn = true local this = {} local isFirstPerson = false local isRightMouseDown = false local isMiddleMouseDown = false this.Enabled = false this.RotateInput = ZERO_VECTOR2 this.DefaultZoom = 10 this.activeGamepad = nil this.PartSubjectHack = nil function this:GetHumanoid() local player = Players.LocalPlayer return findPlayerHumanoid(player) end function this:GetHumanoidRootPart() local humanoid = this:GetHumanoid() return humanoid and humanoid.Torso end function this:GetSubjectPosition() local camera = workspace.CurrentCamera local result = camera.Focus.p local cameraSubject = camera and camera.CameraSubject if cameraSubject then if cameraSubject:IsA("Humanoid") then local char = cameraSubject.Parent if char then local head = char:FindFirstChild("Head") if head and head:IsA("BasePart") then result = head.Position end end if this.PartSubjectHack then this:ZoomCamera(this.PartSubjectHack) this.PartSubjectHack = nil this:UpdateMouseBehavior() end elseif cameraSubject:IsA("BasePart") then result = cameraSubject.Position if not this.PartSubjectHack then this.PartSubjectHack = this:GetCameraZoom() this:ZoomCamera(10) this:UpdateMouseBehavior() end end end return result end function this:GetCameraLook() return workspace.CurrentCamera and workspace.CurrentCamera.CFrame.lookVector or Vector3.new(0,0,1) end function this:GetCameraZoom() if this.currentZoom == nil then local player = Players.LocalPlayer this.currentZoom = player and clamp(player.CameraMinZoomDistance, player.CameraMaxZoomDistance, this.DefaultZoom) or this.DefaultZoom end return this.currentZoom end function this:GetCameraActualZoom() local camera = workspace.CurrentCamera if camera then return (camera.CFrame.p - camera.Focus.p).Magnitude end end function this:ViewSizeX() local result = 1024 local camera = workspace.CurrentCamera if camera then result = camera.ViewportSize.X end return result end function this:ViewSizeY() local result = 768 local camera = workspace.CurrentCamera if camera then result = camera.ViewportSize.Y end return result end function this:ScreenTranslationToAngle(translationVector) local screenX = this:ViewSizeX() local screenY = this:ViewSizeY() local xTheta = (translationVector.x / screenX) local yTheta = (translationVector.y / screenY) return Vector2_new(xTheta, yTheta) end function this:MouseTranslationToAngle(translationVector) local xTheta = (translationVector.x / 1920) local yTheta = (translationVector.y / 1200) return Vector2_new(xTheta, yTheta) end function this:RotateVector(startVector, xyRotateVector) local startCFrame = CFrame_new(ZERO_VECTOR3, startVector) local resultLookVector = (CFrame_Angles(0, -xyRotateVector.x, 0) * startCFrame * CFrame_Angles(-xyRotateVector.y,0,0)).lookVector return resultLookVector, Vector2_new(xyRotateVector.x, xyRotateVector.y) end function this:RotateCamera(startLook, xyRotateVector) local startVertical = math_asin(startLook.y) local yTheta = clamp(-MAX_Y + startVertical, -MIN_Y + startVertical, xyRotateVector.y) return self:RotateVector(startLook, Vector2_new(xyRotateVector.x, yTheta)) end function this:IsInFirstPerson() return isFirstPerson end function this:UpdateMouseBehavior() if isFirstPerson or this.PartSubjectHack then GameSettings.RotationType = Enum.RotationType.CameraRelative UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter else GameSettings.RotationType = Enum.RotationType.MovementRelative if isRightMouseDown or isMiddleMouseDown then UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition else UserInputService.MouseBehavior = Enum.MouseBehavior.Default end end end function this:PlayTick() local now = tick() local lastTickSound = this.LastTickSound if not lastTickSound then lastTickSound = 0 end if (now - lastTickSound) > .03 then local s = Instance.new("Sound") s.SoundId = "rbxasset://sounds/switch3.wav" s.Parent = script s:Play() Debris:AddItem(s,1) this.LastTickSound = now end end function this:ZoomCamera(desiredZoom) this.currentZoom = clamp(0.25, 400, desiredZoom) isFirstPerson = self:GetCameraZoom() < 1.5 -- set mouse behavior self:UpdateMouseBehavior() return self:GetCameraZoom() end function this:ZoomCameraBy(input) if TeleportService:GetTeleportSetting("FPSCapTo30") then input = input * 1.5 end local zoom = this:GetCameraActualZoom() if zoom then if input > 0 then zoom = math.max( 1, zoom / (1 + ZOOM_FACTOR*input)) elseif input < 0 then zoom = math.min(5000, zoom * (1 - ZOOM_FACTOR*input)) end self:ZoomCamera(zoom) end self:PlayTick() return self:GetCameraZoom() end function this:ZoomCameraFixedBy(zoomIncrement) return self:ZoomCamera(self:GetCameraZoom() + zoomIncrement) end ------------------------ ---- Input Events ---- ------------------------ do local startPos = nil local lastPos = nil local panBeginLook = nil local lastTapTime = nil local fingerTouches = {} local NumUnsunkTouches = 0 local inputStartPositions = {} local inputStartTimes = {} local StartingDiff = nil local pinchBeginZoom = nil local dynamicThumbstickFrame = nil local flaggedDynamic = {} local function getDynamicThumbstickFrame() if dynamicThumbstickFrame and dynamicThumbstickFrame:IsDescendantOf(game) then return dynamicThumbstickFrame else local touchGui = PlayerGui:FindFirstChild("TouchGui") if not touchGui then return nil end local touchControlFrame = touchGui:FindFirstChild("TouchControlFrame") if not touchControlFrame then return nil end dynamicThumbstickFrame = touchControlFrame:FindFirstChild("DynamicThumbstickFrame") return dynamicThumbstickFrame end end this.ZoomEnabled = true this.PanEnabled = true this.KeyPanEnabled = true local function inputIsDynamic(input) if flaggedDynamic[input] ~= nil then return flaggedDynamic[input] end if GameSettings.TouchMovementMode ~= Enum.TouchMovementMode.DynamicThumbstick then return false end local df = getDynamicThumbstickFrame() if not df then return end local pos = input.Position local p0 = df.AbsolutePosition local p1 = p0 + df.AbsoluteSize if p0.X <= pos.X and p0.Y <= pos.Y then if pos.X <= p1.X and pos.Y <= p1.Y then flaggedDynamic[input] = true return true end end flaggedDynamic[input] = false return false end local function OnTouchBegan(input, processed) if not inputIsDynamic(input) then fingerTouches[input] = processed if not processed then inputStartPositions[input] = input.Position inputStartTimes[input] = tick() NumUnsunkTouches = NumUnsunkTouches + 1 end end end local function OnTouchChanged(input, processed) if inputIsDynamic(input) then return end if fingerTouches[input] == nil then fingerTouches[input] = processed if not processed then NumUnsunkTouches = NumUnsunkTouches + 1 end end if NumUnsunkTouches == 1 then if fingerTouches[input] == false then panBeginLook = panBeginLook or this:GetCameraLook() startPos = startPos or input.Position lastPos = lastPos or startPos this.UserPanningTheCamera = true local delta = input.Position - lastPos delta = Vector2.new(delta.X, delta.Y * GameSettings:GetCameraYInvertValue()) if this.PanEnabled then local desiredXYVector = this:ScreenTranslationToAngle(delta) * TOUCH_SENSITIVTY this.RotateInput = this.RotateInput + desiredXYVector end lastPos = input.Position end else panBeginLook = nil startPos = nil lastPos = nil this.UserPanningTheCamera = false end if NumUnsunkTouches == 2 then local unsunkTouches = {} for touch, wasSunk in pairs(fingerTouches) do if not wasSunk then table.insert(unsunkTouches, touch) end end if #unsunkTouches == 2 then local difference = (unsunkTouches[1].Position - unsunkTouches[2].Position).magnitude if StartingDiff and pinchBeginZoom then local scale = difference / math_max(0.01, StartingDiff) local clampedScale = clamp(0.1, 10, scale) if this.ZoomEnabled then this:ZoomCamera(pinchBeginZoom / clampedScale) this:PlayTick() end else StartingDiff = difference pinchBeginZoom = this:GetCameraActualZoom() end end else StartingDiff = nil pinchBeginZoom = nil end end local function calcLookBehindRotateInput(torso) if torso then local newDesiredLook = (torso.CFrame.lookVector - Vector3.new(0,0.23,0)).unit local horizontalShift = findAngleBetweenXZVectors(newDesiredLook, this:GetCameraLook()) local vertShift = math_asin(this:GetCameraLook().y) - math_asin(newDesiredLook.y) if not IsFinite(horizontalShift) then horizontalShift = 0 end if not IsFinite(vertShift) then vertShift = 0 end return Vector2.new(horizontalShift, vertShift) end return nil end local function OnTouchEnded(input, processed) if fingerTouches[input] == false then if NumUnsunkTouches == 1 then panBeginLook = nil startPos = nil lastPos = nil elseif NumUnsunkTouches == 2 then StartingDiff = nil pinchBeginZoom = nil end end if fingerTouches[input] ~= nil and fingerTouches[input] == false then NumUnsunkTouches = NumUnsunkTouches - 1 end fingerTouches[input] = nil inputStartPositions[input] = nil inputStartTimes[input] = nil flaggedDynamic[input] = nil end local function OnMousePanButtonPressed(input, processed) if processed then return end this:UpdateMouseBehavior() panBeginLook = panBeginLook or this:GetCameraLook() startPos = startPos or input.Position lastPos = lastPos or startPos this.UserPanningTheCamera = true end local function OnMousePanButtonReleased(input, processed) this:UpdateMouseBehavior() if not (isRightMouseDown or isMiddleMouseDown) then panBeginLook = nil startPos = nil lastPos = nil this.UserPanningTheCamera = false end end local function OnMouse2Down(input, processed) if processed then return end isRightMouseDown = true OnMousePanButtonPressed(input, processed) end local function OnMouse2Up(input, processed) isRightMouseDown = false OnMousePanButtonReleased(input, processed) end local function OnMouse3Down(input, processed) if processed then return end isMiddleMouseDown = true OnMousePanButtonPressed(input, processed) end local function OnMouse3Up(input, processed) isMiddleMouseDown = false OnMousePanButtonReleased(input, processed) end local function OnMouseMoved(input, processed) local inputDelta = input.Delta inputDelta = Vector2.new(inputDelta.X, inputDelta.Y * GameSettings:GetCameraYInvertValue()) if startPos and lastPos and panBeginLook then local currPos = lastPos + input.Delta local totalTrans = currPos - startPos if this.PanEnabled then local desiredXYVector = this:MouseTranslationToAngle(inputDelta) * MOUSE_SENSITIVITY this.RotateInput = this.RotateInput + desiredXYVector end lastPos = currPos elseif (this:IsInFirstPerson() or this.PartSubjectHack) and this.PanEnabled then local desiredXYVector = this:MouseTranslationToAngle(inputDelta) * MOUSE_SENSITIVITY this.RotateInput = this.RotateInput + desiredXYVector end end local function OnMouseWheel(input, processed) if not processed then if this.ZoomEnabled then this:ZoomCameraBy(clamp(-1, 1, input.Position.Z)) end end end local function round(num) return math_floor(num + 0.5) end local eight2Pi = math_pi / 4 local function rotateVectorByAngleAndRound(camLook, rotateAngle, roundAmount) if camLook ~= ZERO_VECTOR3 then camLook = camLook.unit local currAngle = math_atan2(camLook.z, camLook.x) local newAngle = round((math_atan2(camLook.z, camLook.x) + rotateAngle) / roundAmount) * roundAmount return newAngle - currAngle end return 0 end local function OnKeyDown(input, processed) if processed then return end if this.ZoomEnabled then if input.KeyCode == Enum.KeyCode.I then this:ZoomCameraBy(1) elseif input.KeyCode == Enum.KeyCode.O then this:ZoomCameraBy(-1) end end if panBeginLook == nil and this.KeyPanEnabled then if input.KeyCode == Enum.KeyCode.Left then this.TurningLeft = true elseif input.KeyCode == Enum.KeyCode.Right then this.TurningRight = true elseif input.KeyCode == Enum.KeyCode.Comma then local angle = rotateVectorByAngleAndRound(this:GetCameraLook() * Vector3.new(1,0,1), -eight2Pi * (3/4), eight2Pi) if angle ~= 0 then this.RotateInput = this.RotateInput + Vector2.new(angle, 0) this.LastUserPanCamera = tick() this.LastCameraTransform = nil end this:PlayTick() elseif input.KeyCode == Enum.KeyCode.Period then local angle = rotateVectorByAngleAndRound(this:GetCameraLook() * Vector3.new(1,0,1), eight2Pi * (3/4), eight2Pi) if angle ~= 0 then this.RotateInput = this.RotateInput + Vector2.new(angle, 0) this.LastUserPanCamera = tick() this.LastCameraTransform = nil end this:PlayTick() elseif input.KeyCode == Enum.KeyCode.PageUp then this.RotateInput = this.RotateInput + Vector2.new(0,math_pi/12) this.LastCameraTransform = nil this:PlayTick() elseif input.KeyCode == Enum.KeyCode.PageDown then this.RotateInput = this.RotateInput + Vector2.new(0,-math_pi/12) this.LastCameraTransform = nil this:PlayTick() end end end local function OnKeyUp(input, processed) if input.KeyCode == Enum.KeyCode.Left then this.TurningLeft = false elseif input.KeyCode == Enum.KeyCode.Right then this.TurningRight = false end end local lastThumbstickRotate = nil local numOfSeconds = 0.7 local currentSpeed = 0 local maxSpeed = 6 local lastThumbstickPos = Vector2.new(0,0) local ySensitivity = 0.65 local lastVelocity = nil function this:UpdateGamepad() local gamepadPan = this.GamepadPanningCamera if gamepadPan then gamepadPan = gamepadLinearToCurve(gamepadPan) local currentTime = tick() if gamepadPan.X ~= 0 or gamepadPan.Y ~= 0 then this.userPanningTheCamera = true elseif gamepadPan == ZERO_VECTOR2 then lastThumbstickRotate = nil if lastThumbstickPos == ZERO_VECTOR2 then currentSpeed = 0 end end local finalConstant = 0 if lastThumbstickRotate then local elapsed = (currentTime - lastThumbstickRotate) * 10 currentSpeed = currentSpeed + (maxSpeed * ((elapsed*elapsed)/numOfSeconds)) if currentSpeed > maxSpeed then currentSpeed = maxSpeed end if lastVelocity then local velocity = (gamepadPan - lastThumbstickPos)/(currentTime - lastThumbstickRotate) local velocityDeltaMag = (velocity - lastVelocity).magnitude if velocityDeltaMag > 12 then currentSpeed = currentSpeed * (20/velocityDeltaMag) if currentSpeed > maxSpeed then currentSpeed = maxSpeed end end end local gamepadCameraSensitivity = GameSettings.GamepadCameraSensitivity finalConstant = (gamepadCameraSensitivity * currentSpeed) lastVelocity = (gamepadPan - lastThumbstickPos)/(currentTime - lastThumbstickRotate) end lastThumbstickPos = gamepadPan lastThumbstickRotate = currentTime return Vector2_new( gamepadPan.X * finalConstant, gamepadPan.Y * finalConstant * ySensitivity * GameSettings:GetCameraYInvertValue()) end return ZERO_VECTOR2 end local InputEvents = {} function this:DisconnectInputEvents() -- Disconnect all input events. while true do local signalName = next(InputEvents) if signalName then InputEvents[signalName]:Disconnect() InputEvents[signalName] = nil else break end end this.TurningLeft = false this.TurningRight = false this.LastCameraTransform = nil this.UserPanningTheCamera = false this.RotateInput = ZERO_VECTOR2 this.GamepadPanningCamera = ZERO_VECTOR2 -- Reset input states startPos = nil lastPos = nil panBeginLook = nil isRightMouseDown = false isMiddleMouseDown = false fingerTouches = {} NumUnsunkTouches = 0 StartingDiff = nil pinchBeginZoom = nil -- Unlock mouse for example if right mouse button was being held down if UserInputService.MouseBehavior ~= Enum.MouseBehavior.LockCenter then UserInputService.MouseBehavior = Enum.MouseBehavior.Default end end local function resetInputStates() isRightMouseDown = false isMiddleMouseDown = false OnMousePanButtonReleased() -- this function doesn't seem to actually need parameters if UserInputService.TouchEnabled then --[[menu opening was causing serious touch issues this should disable all active touch events if they're active when menu opens.]] for inputObject, value in pairs(fingerTouches) do fingerTouches[inputObject] = nil end panBeginLook = nil startPos = nil lastPos = nil this.UserPanningTheCamera = false StartingDiff = nil pinchBeginZoom = nil NumUnsunkTouches = 0 end end local function getGamepadPan(name, state, input) if input.UserInputType == this.activeGamepad and input.KeyCode == Enum.KeyCode.Thumbstick2 then if state == Enum.UserInputState.Cancel then this.GamepadPanningCamera = ZERO_VECTOR2 return end local inputVector = Vector2.new(input.Position.X, -input.Position.Y) if inputVector.magnitude > THUMBSTICK_DEADZONE then this.GamepadPanningCamera = Vector2_new(input.Position.X, -input.Position.Y) else this.GamepadPanningCamera = ZERO_VECTOR2 end end end local function doGamepadZoom(name, state, input) if input.UserInputType == this.activeGamepad and input.KeyCode == Enum.KeyCode.ButtonR3 and state == Enum.UserInputState.Begin then if this.ZoomEnabled then if this:GetCameraZoom() > 0.5 then this:ZoomCamera(0) else this:ZoomCamera(10) end end end end local function assignActivateGamepad() local connectedGamepads = UserInputService:GetConnectedGamepads() if #connectedGamepads > 0 then for i = 1, #connectedGamepads do if this.activeGamepad == nil then this.activeGamepad = connectedGamepads[i] elseif connectedGamepads[i].Value < this.activeGamepad.Value then this.activeGamepad = connectedGamepads[i] end end end if this.activeGamepad == nil then -- nothing is connected, at least set up for gamepad1 this.activeGamepad = Enum.UserInputType.Gamepad1 end end local function onInputBegan(input, processed) if input.UserInputType == Enum.UserInputType.Touch then OnTouchBegan(input, processed) elseif input.UserInputType == Enum.UserInputType.MouseButton2 then OnMouse2Down(input, processed) elseif input.UserInputType == Enum.UserInputType.MouseButton3 then OnMouse3Down(input, processed) end -- Keyboard if input.UserInputType == Enum.UserInputType.Keyboard then OnKeyDown(input, processed) end end local function onInputChanged(input, processed) if input.UserInputType == Enum.UserInputType.Touch then OnTouchChanged(input, processed) elseif input.UserInputType == Enum.UserInputType.MouseMovement then OnMouseMoved(input, processed) elseif input.UserInputType == Enum.UserInputType.MouseWheel then OnMouseWheel(input, processed) end end local function onInputEnded(input, processed) if input.UserInputType == Enum.UserInputType.Touch then OnTouchEnded(input, processed) elseif input.UserInputType == Enum.UserInputType.MouseButton2 then OnMouse2Up(input, processed) elseif input.UserInputType == Enum.UserInputType.MouseButton3 then OnMouse3Up(input, processed) end -- Keyboard if input.UserInputType == Enum.UserInputType.Keyboard then OnKeyUp(input, processed) end end local inputPassCmds = { ZoomIn = Enum.KeyCode.I; ZoomOut = Enum.KeyCode.O; RotateUp = Enum.KeyCode.PageUp; RotateDown = Enum.KeyCode.PageDown; } local function onInputPassed(command) local passKey = inputPassCmds[command] if passKey then OnKeyDown({KeyCode = passKey}, false) end end local function onGamepadConnected(gamepadEnum) if this.activeGamepad == nil then assignActivateGamepad() end end local function onGamepadDisconnected(gamepadEnum) if this.activeGamepad ~= gamepadEnum then return end this.activeGamepad = nil assignActivateGamepad() end function this:ConnectInputEvents() local player = Players.LocalPlayer local playerScripts = player:WaitForChild("PlayerScripts") local passCameraEvent = playerScripts:WaitForChild("PassCameraEvent") this.RotateInput = ZERO_VECTOR2 this.activeGamepad = nil InputEvents = { InputBegan = UserInputService.InputBegan:Connect(onInputBegan); InputChanged = UserInputService.InputChanged:Connect(onInputChanged); InputEnded = UserInputService.InputEnded:Connect(onInputEnded); MenuOpened = GuiService.MenuOpened:Connect(resetInputStates); MenuOpenedConn = GuiService.MenuOpened:Connect(resetInputStates); GamepadConnected = UserInputService.GamepadConnected:Connect(onGamepadConnected); GamepadDisconnected = UserInputService.GamepadDisconnected:Connect(onGamepadDisconnected); InputPassed = passCameraEvent.Event:Connect(onInputPassed); } ContextActionService:BindAction("RootCamGamepadPan", getGamepadPan, false, Enum.KeyCode.Thumbstick2) ContextActionService:BindAction("RootCamGamepadZoom", doGamepadZoom, false, Enum.KeyCode.ButtonR3) assignActivateGamepad() -- set mouse behavior self:UpdateMouseBehavior() end function this:SetEnabled(newState) if newState ~= self.Enabled then self.Enabled = newState if self.Enabled then self:ConnectInputEvents() else self:DisconnectInputEvents() end end end local function OnPlayerAdded(player) player.Changed:Connect(function (prop) if this.Enabled then if prop == "CameraMode" or prop == "CameraMaxZoomDistance" or prop == "CameraMinZoomDistance" then this:ZoomCameraFixedBy(0) end end end) local function OnCharacterAdded(newCharacter) local humanoid = findPlayerHumanoid(player) local start = tick() while tick() - start < 0.3 and (humanoid == nil or humanoid.Torso == nil) do wait() humanoid = findPlayerHumanoid(player) end if humanoid and humanoid.Torso and player.Character == newCharacter then local newDesiredLook = (humanoid.Torso.CFrame.lookVector - Vector3.new(0,0.23,0)).unit local horizontalShift = findAngleBetweenXZVectors(newDesiredLook, this:GetCameraLook()) local vertShift = math_asin(this:GetCameraLook().y) - math_asin(newDesiredLook.y) if not IsFinite(horizontalShift) then horizontalShift = 0 end if not IsFinite(vertShift) then vertShift = 0 end this.RotateInput = Vector2.new(horizontalShift, vertShift) -- reset old camera info so follow cam doesn't rotate us this.LastCameraTransform = nil end -- Need to wait for camera cframe to update before we zoom in -- Not waiting will force camera to original cframe wait() this:ZoomCamera(this.DefaultZoom) end player.CharacterAdded:Connect(function (character) if this.Enabled or SetCameraOnSpawn then OnCharacterAdded(character) SetCameraOnSpawn = false end end) if player.Character then spawn(function () OnCharacterAdded(player.Character) end) end end if Players.LocalPlayer then OnPlayerAdded(Players.LocalPlayer) end Players.ChildAdded:Connect(function (child) if child and Players.LocalPlayer == child then OnPlayerAdded(Players.LocalPlayer) end end) end ------------------------ ---- Main Updater ---- ------------------------ do local tweenAcceleration = math_rad(220) local tweenSpeed = math_rad(0) local tweenMaxSpeed = math_rad(250) local timeBeforeAutoRotate = 2 local lastUpdate = tick() this.LastUserPanCamera = lastUpdate function this:Update() local now = tick() local timeDelta = (now - lastUpdate) local userPanningTheCamera = (self.UserPanningTheCamera == true) local camera = workspace.CurrentCamera local humanoid = self:GetHumanoid() local cameraSubject = camera and camera.CameraSubject local isInVehicle = cameraSubject and cameraSubject:IsA('VehicleSeat') local isOnASkateboard = cameraSubject and cameraSubject:IsA('SkateboardPlatform') if isInVehicle and cameraSubject.Occupant == humanoid then cameraSubject = humanoid camera.CameraSubject = humanoid isInVehicle = false end if lastUpdate == nil or (now - lastUpdate) > 1 then self.LastCameraTransform = nil end if lastUpdate then local gamepadRotation = self:UpdateGamepad() -- Cap out the delta to 0.1 so we don't get some crazy things when we re-resume from local delta = math_min(0.1, now - lastUpdate) if gamepadRotation ~= ZERO_VECTOR2 then userPanningTheCamera = true self.RotateInput = self.RotateInput + (gamepadRotation * delta) end local angle = 0 if not (isInVehicle or isOnASkateboard) then angle = angle + (self.TurningLeft and -120 or 0) angle = angle + (self.TurningRight and 120 or 0) end if angle ~= 0 then self.RotateInput = self.RotateInput + Vector2.new(math_rad(angle * delta), 0) userPanningTheCamera = true end end -- Reset tween speed if user is panning if userPanningTheCamera then tweenSpeed = 0 self.LastUserPanCamera = now end local userRecentlyPannedCamera = now - self.LastUserPanCamera < timeBeforeAutoRotate local subjectPosition = self:GetSubjectPosition() if subjectPosition and camera then local zoom = self:GetCameraZoom() if zoom < 0.25 then zoom = 0.25 end if TeleportService:GetTeleportSetting("FollowCamera") then if self.LastCameraTransform and not self:IsInFirstPerson() then local lastVec = -(self.LastCameraTransform.p - subjectPosition) local y = findAngleBetweenXZVectors(lastVec, self:GetCameraLook()) -- Check for NaNs if IsFinite(y) and math.abs(y) > 0.0001 then self.RotateInput = self.RotateInput + Vector2.new(y, 0) end end end camera.Focus = CFrame_new(subjectPosition) local newLookVector = self:RotateCamera(self:GetCameraLook(), self.RotateInput) self.RotateInput = ZERO_VECTOR2 if self.LastZoom ~= zoom then self.LastZoom = zoom if camera.CameraSubject and camera.CameraSubject:IsA("Humanoid") then -- Flatten the lookVector newLookVector = (newLookVector * XZ_VECTOR).Unit -- Apply upwards tilt local upY = -math_min(6, zoom/40) newLookVector = (newLookVector + (UP_VECTOR * upY)).Unit end end local newCF = CFrame_new(subjectPosition - (zoom * newLookVector), subjectPosition) camera.CFrame = camera.CFrame:Lerp(newCF,.8) self.LastCameraTransform = camera.CFrame end lastUpdate = now end GameSettings:SetCameraYInvertVisible() GameSettings:SetGamepadCameraSensitivityVisible() end return this Opacity -- SolarCrane local module = {} local LastUpdate = tick() local TransparencyDirty = false local Enabled = false local LastTransparency = nil local DescendantAddedConn, DescendantRemovingConn = nil, nil local ToolDescendantAddedConns = {} local ToolDescendantRemovingConns = {} local CachedParts = {} local function HasToolAncestor(object) return (object:FindFirstAncestorWhichIsA("Tool")) ~= nil end local function IsValidPartToModify(part) if part:IsA('BasePart') or part:IsA('Decal') then return not HasToolAncestor(part) end return false end local function TeardownTransparency() for child, _ in pairs(CachedParts) do child.LocalTransparencyModifier = 0 end CachedParts = {} TransparencyDirty = true LastTransparency = nil if DescendantAddedConn then DescendantAddedConn:disconnect() DescendantAddedConn = nil end if DescendantRemovingConn then DescendantRemovingConn:disconnect() DescendantRemovingConn = nil end for object, conn in pairs(ToolDescendantAddedConns) do conn:disconnect() ToolDescendantAddedConns[object] = nil end for object, conn in pairs(ToolDescendantRemovingConns) do conn:disconnect() ToolDescendantRemovingConns[object] = nil end end local function SetupTransparency(character) TeardownTransparency() if DescendantAddedConn then DescendantAddedConn:Disconnect() end DescendantAddedConn = character.DescendantAdded:connect(function (object) -- This is a part we want to invisify if IsValidPartToModify(object) then CachedParts[object] = true TransparencyDirty = true -- There is now a tool under the character elseif object:IsA('Tool') then if ToolDescendantAddedConns[object] then ToolDescendantAddedConns[object]:Disconnect() end ToolDescendantAddedConns[object] = object.DescendantAdded:connect(function (toolChild) CachedParts[toolChild] = nil if toolChild:IsA('BasePart') or toolChild:IsA('Decal') then -- Reset the transparency toolChild.LocalTransparencyModifier = 0 end end) if ToolDescendantRemovingConns[object] then ToolDescendantRemovingConns[object]:Disconnect() end ToolDescendantRemovingConns[object] = object.DescendantRemoving:connect(function (formerToolChild) wait() -- wait for new parent if character and formerToolChild and formerToolChild:IsDescendantOf(character) then if IsValidPartToModify(formerToolChild) then CachedParts[formerToolChild] = true TransparencyDirty = true end end end) end end) if DescendantRemovingConn then DescendantRemovingConn:Disconnect() end DescendantRemovingConn = character.DescendantRemoving:connect(function (object) if CachedParts[object] then CachedParts[object] = nil -- Reset the transparency object.LocalTransparencyModifier = 0 end end) for _,desc in pairs(character:GetDescendants()) do if IsValidPartToModify(desc) then CachedParts[desc] = true TransparencyDirty = true end end end function module:SetEnabled(newState) if Enabled ~= newState then Enabled = newState self:Update() end end function module:SetSubject(subject) local character = nil if subject and subject:IsA("Humanoid") then character = subject.Parent end if subject and subject:IsA("VehicleSeat") and subject.Occupant then character = subject.Occupant.Parent end if character then SetupTransparency(character) else TeardownTransparency() end end function module:Update() local instant = false local now = tick() local currentCamera = workspace.CurrentCamera if currentCamera then local transparency = 0 if not Enabled then instant = true else local distance = (currentCamera.Focus.p - currentCamera.CFrame.p).magnitude if distance < 2 then transparency = 1 elseif distance < 6 then transparency = 0.5 else transparency = 0 end end if TransparencyDirty or LastTransparency ~= transparency then for child in pairs(CachedParts) do if child.ClassName == "Decal" then child.LocalTransparencyModifier = math.floor(transparency) else child.LocalTransparencyModifier = transparency end end TransparencyDirty = false LastTransparency = transparency end end LastUpdate = now end return module Popper -- PopperCam Version 16 -- OnlyTwentyCharacters local PopperCam = {} -- Guarantees your players won't see outside the bounds of your map! ----------------- --| Constants |-- ----------------- local POP_RESTORE_RATE = 0.3 local MIN_CAMERA_ZOOM = 0.5 local VALID_SUBJECTS = { 'Humanoid', 'VehicleSeat', 'SkateboardPlatform', } ----------------- --| Variables |-- ----------------- local Players = game:GetService('Players') local Camera = nil local CameraSubjectChangeConn = nil local SubjectPart = nil local PlayerCharacters = {} -- For ignoring in raycasts local VehicleParts = {} -- Also just for ignoring local LastPopAmount = 0 local LastZoomLevel = 0 local PopperEnabled = true local CFrame_new = CFrame.new ----------------------- --| Local Functions |-- ----------------------- local math_abs = math.abs local function OnCharacterAdded(player, character) PlayerCharacters[player] = character end local function OnPlayersChildAdded(child) if child:IsA('Player') then child.CharacterAdded:connect(function(character) OnCharacterAdded(child, character) end) if child.Character then OnCharacterAdded(child, child.Character) end end end local function OnPlayersChildRemoved(child) if child:IsA('Player') then PlayerCharacters[child] = nil end end ------------------------- --| Exposed Functions |-- ------------------------- function PopperCam:Update() if PopperEnabled then -- First, prep some intermediate vars local Camera = workspace.CurrentCamera local cameraCFrame = Camera.CFrame local focusPoint = Camera.Focus.p if SubjectPart then focusPoint = SubjectPart.CFrame.p end local ignoreList = {} for _, character in pairs(PlayerCharacters) do ignoreList[#ignoreList + 1] = character end for i = 1, #VehicleParts do ignoreList[#ignoreList + 1] = VehicleParts[i] end -- Get largest cutoff distance local largest = Camera:GetLargestCutoffDistance(ignoreList) -- Then check if the player zoomed since the last frame, -- and if so, reset our pop history so we stop tweening local zoomLevel = (cameraCFrame.p - focusPoint).Magnitude if math_abs(zoomLevel - LastZoomLevel) > 0.001 then LastPopAmount = 0 end -- Finally, zoom the camera in (pop) by that most-cut-off amount, or the last pop amount if that's more local popAmount = largest if LastPopAmount > popAmount then popAmount = LastPopAmount end if popAmount > 0 then Camera.CFrame = cameraCFrame + (cameraCFrame.lookVector * popAmount) LastPopAmount = popAmount - POP_RESTORE_RATE -- Shrink it for the next frame if LastPopAmount < 0 then LastPopAmount = 0 end end LastZoomLevel = zoomLevel end end -------------------- --| Script Logic |-- -------------------- -- Connect to all Players so we can ignore their Characters Players.ChildRemoved:connect(OnPlayersChildRemoved) Players.ChildAdded:connect(OnPlayersChildAdded) for _, player in pairs(Players:GetPlayers()) do OnPlayersChildAdded(player) end return PopperCam Camera local RunService = game:GetService("RunService") local UserInputService = game:GetService("UserInputService") local Players = game:GetService("Players") local playerScripts = script.Parent local playerModule = require(playerScripts:WaitForChild("PlayerModule")) local cameraSystem = playerModule:GetCameras() local main = require(script:WaitForChild("Main")) local popper = require(script:WaitForChild("Popper")) local opacity = require(script:WaitForChild("Opacity")) local cameraSubjectChangedConn = nil local renderSteppedConn = nil local function onCameraSubjectChanged() local currentCamera = workspace.CurrentCamera if currentCamera then local newSubject = currentCamera.CameraSubject opacity:SetSubject(newSubject) end end local function onNewCamera() local currentCamera = workspace.CurrentCamera if currentCamera then if cameraSubjectChangedConn then cameraSubjectChangedConn:Disconnect() end local cameraSubjectChanged = currentCamera:GetPropertyChangedSignal("CameraSubject") cameraSubjectChangedConn = cameraSubjectChanged:Connect(onCameraSubjectChanged) onCameraSubjectChanged() end end -- Initialize cameras. local cameraUpdated = workspace:GetPropertyChangedSignal("CurrentCamera") cameraUpdated:Connect(onNewCamera) onNewCamera() main:SetEnabled(true) opacity:SetEnabled(true) -- Overload the camera update function. function cameraSystem:Update() if cameraSystem.activeCameraController then cameraSystem.activeCameraController:Enable(false) cameraSystem.activeCameraController = nil end main:Update() popper:Update() opacity:Update() end playerScripts:RegisterTouchCameraMovementMode(Enum.TouchCameraMovementMode.Default) playerScripts:RegisterComputerCameraMovementMode(Enum.ComputerCameraMovementMode.Default) CharacterBevels ClickToMove ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- @CloneTrooper1019, 2018 -- ClickToMove ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Constants ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local ContextActionService = game:GetService("ContextActionService") local GuiService = game:GetService("GuiService") local Players = game:GetService("Players") local RunService = game:GetService("RunService") local TeleportService = game:GetService("TeleportService") local UserInputService = game:GetService("UserInputService") local IS_TOUCH = UserInputService.TouchEnabled local ICON_IDLE = "rbxassetid://334630296" local ICON_HOVER = "rbxassetid://1000000" local ICON_CLICK = "rbxasset://textures/DragCursor.png" local DISK_OFFSET = CFrame.Angles(math.pi / 2,0,0) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Character Listener ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local player = game.Players.LocalPlayer local character,humanoid local function onCharacterAdded(char) humanoid = char:WaitForChild("Humanoid") character = char end if player.Character then onCharacterAdded(player.Character) end player.CharacterAdded:Connect(onCharacterAdded) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Gui Focus ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local isMouseHoveringUi = false local function onInputChanged(input, gameProcessed) local inputType = input.UserInputType.Name if inputType == "MouseMovement" then isMouseHoveringUi = gameProcessed end end local function isGuiFocused() return isMouseHoveringUi or GuiService.SelectedObject ~= nil end UserInputService.InputChanged:Connect(onInputChanged) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Movement Goal ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local currentGoal, moveSignal local function findAngleBetweenXZVectors(vec2, vec1) return math.atan2(vec1.X*vec2.Z-vec1.Z*vec2.X, vec1.X*vec2.X + vec1.Z*vec2.Z) end local function isFinite(num) return num == num and num ~= 1/0 and num ~= -1/0 end local function rotateCameraTowardsGoal() local c = workspace.CurrentCamera if c then local cf = c.CFrame local focus = c.Focus local desiredAngle = CFrame.new(cf.p,currentGoal).lookVector local currentAngle = cf.lookVector local angleBetween = findAngleBetweenXZVectors(desiredAngle,currentAngle) if isFinite(angleBetween) then local abs = math.abs(angleBetween) local sign = math.sign(angleBetween) local rotation = math.min(0.01,abs) local cfLocal = focus:toObjectSpace(cf) c.CFrame = focus * CFrame.Angles(0,-rotation*sign,0) * cfLocal end end end local function finishGoal() if currentGoal then currentGoal = nil end if moveSignal then moveSignal:Disconnect() moveSignal = nil end end local function clickToMove(goal) finishGoal() currentGoal = goal moveSignal = humanoid.MoveToFinished:Connect(finishGoal) humanoid:Move(Vector3.new(1,1,1)) humanoid:MoveTo(currentGoal) end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Green Disk ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local mouse = player:GetMouse() local mouseIcon = script.Parent mouse.TargetFilter = workspace.CurrentCamera local lastTarget local lastTargetCanClick = false local disk = Instance.new("CylinderHandleAdornment") disk.Name = "Disk" disk.Color3 = Color3.new(0,1,0) disk.Radius = 1 disk.Height = 0.2 disk.Visible = false disk.Adornee = workspace.Terrain disk.Parent = script local goalDisk = disk:Clone() goalDisk.Name = "Goal" goalDisk.Parent = script local function hasTool() if character then return character:FindFirstChildOfClass("Tool") ~= nil end return false end local function isFirstPerson() if character then local head = character:FindFirstChild("Head") if head then return head.LocalTransparencyModifier == 1 end end return false end local function canClickTarget() local target = mouse.Target if target then if target ~= lastTarget then local canClick = false local clickDetector = target:FindFirstChildOfClass("ClickDetector") if clickDetector then local dist = player:DistanceFromCharacter(target.Position) if dist <= clickDetector.MaxActivationDistance then canClick = true end end lastTarget = target lastTargetCanClick = canClick end return lastTargetCanClick end end local function canRenderDisk(rendering) if not TeleportService:GetTeleportSetting("ClickToMove") then return false end if rendering and IS_TOUCH then return false end if humanoid then local movement = humanoid.MoveDirection if movement.Magnitude == 0 then local pos = mouse.Hit.p local dist = player:DistanceFromCharacter(pos) if dist < 32 then local blockers = {hasTool, isFirstPerson, canClickTarget, isGuiFocused} for _,blocker in pairs(blockers) do if blocker() then return false end end return true end else finishGoal() end end return false end local function render3dAdorn() disk.Visible = canRenderDisk(true) if disk.Visible then disk.CFrame = CFrame.new(mouse.Hit.p) * DISK_OFFSET mouseIcon.Image = ICON_HOVER elseif canClickTarget() then mouseIcon.Image = ICON_CLICK elseif not hasTool() then mouseIcon.Image = ICON_IDLE end if currentGoal then goalDisk.Visible = true goalDisk.CFrame = CFrame.new(currentGoal) * DISK_OFFSET rotateCameraTowardsGoal() else goalDisk.Visible = false end end RunService.Heartbeat:Connect(render3dAdorn) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Click Action ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local function onInputBegan(input,gameProcessed) local goal = mouse.Hit.p if not gameProcessed and canRenderDisk() and humanoid then local name = input.UserInputType.Name if name == "MouseButton1" then clickToMove(goal) elseif name == "Touch" then wait(.1) if input.UserInputState == Enum.UserInputState.End then clickToMove(goal) end elseif name == "Gamepad1" then if input.KeyCode == Enum.KeyCode.ButtonR2 then clickToMove(goal) end end end end UserInputService.InputBegan:Connect(onInputBegan) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- OBLITERATE the invasive click to move mode that Roblox provides ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- pcall(function () if IS_TOUCH then local playerScripts = player:WaitForChild("PlayerScripts") local no = function () end spawn(function () local controlScript = playerScripts:WaitForChild("ControlScript", 86400) if controlScript then local masterControl = controlScript:WaitForChild("MasterControl") local clickToMove = masterControl:WaitForChild("ClickToMoveController") clickToMove = require(clickToMove) clickToMove:Disable() clickToMove.Enable = no end end) spawn(function () local playerModule = playerScripts:WaitForChild("PlayerModule", 86400) if playerModule then local controlModule = playerModule:WaitForChild("ControlModule") local clickToMove = controlModule:WaitForChild("ClickToMoveController") clickToMove = require(clickToMove) clickToMove:Stop() clickToMove.Enable = no end end) end end) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ConsoleTweaks local UserInputService = game:GetService("UserInputService") local GuiService = game:GetService("GuiService") local function addUIScale(obj,scale) local uiScale = Instance.new("UIScale") uiScale.Scale = scale uiScale.Parent = obj end if GuiService:IsTenFootInterface() then local gui = script.Parent local zoomControls = gui:WaitForChild("ZoomControls") zoomControls.Visible = false local backpack = gui:WaitForChild("Backpack") backpack.Position = UDim2.new(0, 0, 1, 0) local chat = gui:WaitForChild("Chat") addUIScale(chat, 1.5) local chatPadding = gui:WaitForChild("ChatPadding", 1) if chatPadding then chatPadding:Destroy() end local safeChat = gui:WaitForChild("SafeChat") addUIScale(safeChat, 1.5) local health = gui:WaitForChild("Health") addUIScale(health, 1.5) end wait() script:Destroy() Explosions local TeleportService = game:GetService("TeleportService") local classicExp = script:WaitForChild("ClassicExp") local c = workspace.CurrentCamera local baseExpAdorn = Instance.new("UnionOperation") baseExpAdorn.Name = "ExplosionAdorn" baseExpAdorn.Anchored = true baseExpAdorn.CanCollide = false baseExpAdorn.Locked = true baseExpAdorn.Transparency = 1 baseExpAdorn.Size = Vector3.new() local function onDescendantAdded(exp) if exp:IsA("Explosion") then local cf = CFrame.new(exp.Position) local expAdorn = baseExpAdorn:Clone() local lifeTime = 1.5 exp.Visible = false if TeleportService:GetTeleportSetting("RetroExplosions") then local expObj = Instance.new("SphereHandleAdornment") expObj.Adornee = expAdorn expObj.Radius = exp.BlastRadius expObj.Color3 = Color3.new(1,0,0) expObj.CFrame = cf expObj.Parent = expAdorn lifeTime = 1 if exp.BlastRadius > 1 then lifeTime = lifeTime - (1/exp.BlastRadius) end else spawn(function () local e = classicExp:Clone() e.Parent = expAdorn expAdorn.CFrame = cf local lessParticles = TeleportService:GetTeleportSetting("ReducedParticles") local count = lessParticles and 25 or 100 for i = 1,8 do e:Emit(count) wait(0.125) end end) end expAdorn.Parent = c wait(lifeTime) expAdorn:Destroy() end end workspace.DescendantAdded:Connect(onDescendantAdded) ForceFields local RunService = game:GetService("RunService") local ffAdorns = workspace:WaitForChild("_ForceFieldAdorns") local registry = {} local cycleStates = {} local cycles = 60 local function onChildAdded(child) if child:IsA("SelectionBox") then spawn(function () while not child.Adornee do child.Changed:Wait() end registry[child] = child.Adornee end) end end local function onChildRemoved(child) if registry[child] then registry[child] = nil end end local function update() local now = tick() for adorn,adornee in pairs(registry) do local model = adornee:FindFirstAncestorWhichIsA("Model") local key if model then local key = model:GetFullName() local startTime = cycleStates[key] if not startTime then startTime = tick() cycleStates[key] = startTime end local cycle = math.floor(((now-startTime)*2) * cycles) % (cycles*2) if cycle > cycles then cycle = cycles - (cycle - cycles) end local invertCycle = cycles - cycle adorn.Color3 = Color3.new(cycle/cycles, 0, invertCycle/cycles) adorn.Transparency = 0 end adorn.Visible = adornee:IsDescendantOf(workspace) and adornee.LocalTransparencyModifier < 1 end end for _,v in pairs(ffAdorns:GetChildren()) do onChildAdded(v) end RunService.Heartbeat:Connect(update) ffAdorns.ChildAdded:Connect(onChildAdded) ffAdorns.ChildRemoved:Connect(onChildRemoved) GamepadPatch -- Seriously Roblox? local Players = game:GetService("Players") local RunService = game:GetService("RunService") local UserInputService = game:GetService("UserInputService") local player = Players.LocalPlayer local playerScripts = player:WaitForChild("PlayerScripts") local playerModule = playerScripts:WaitForChild("PlayerModule") local controlModule = playerModule:WaitForChild("ControlModule") local gamepad = require(controlModule:WaitForChild("Gamepad")) playerModule = require(playerModule) controlModule = playerModule:GetControls() local function fixGamepad() local lastInputType = UserInputService:GetLastInputType() if lastInputType.Name == "Gamepad1" then local controllers = controlModule.controllers if controlModule.activeController ~= controllers[gamepad] then controlModule:SwitchToController(gamepad) end end end RunService:BindToRenderStep("GamepadPatch", 0, fixGamepad) HumanoidLabels local humanoids = {} local player = game.Players.LocalPlayer local pgui = player:WaitForChild("PlayerGui") local healthBase = script:WaitForChild("Health") local rs = game:GetService("RunService") local farStudsOffset = Vector3.new(0,2,0) local closeStudsOffset = Vector3.new(0,1,0) local farSize = UDim2.new(0,50,0,20) local closeSize = UDim2.new(0,100,0,30) local function isFinite(num) return num == num and num ~= -1/0 and num ~= 1/0 end local function setupHumanoid(h) local updateCon = nil local currentHealth = nil local function onAncestryChanged() if updateCon then updateCon:disconnect() updateCon = nil end if currentHealth then currentHealth:Destroy() currentHealth = nil end local char = h.Parent if char then while not char:FindFirstChild("Head") do if h.Parent ~= char then break end char.ChildAdded:wait() end local head = char:FindFirstChild("Head") if head then local health = healthBase:Clone() local playerName = health:WaitForChild("PlayerName") local redBar = health:WaitForChild("RedBar") local greenBar = redBar:WaitForChild("GreenBar") local inOverWrite = false local overWriter = nil local hPlayer = game.Players:GetPlayerFromCharacter(char) playerName.Text = char.Name health.Adornee = head health.PlayerToHideFrom = hPlayer health.Parent = head local c = workspace.CurrentCamera local function update() local dist = (c.CFrame.p - head.Position).magnitude local fontSize = 12 if dist < 20 then fontSize = 24 elseif dist < 50 then fontSize = 18 end local ratio = h.Health / h.MaxHealth redBar.Visible = isFinite(ratio) redBar.BackgroundTransparency = math.floor(ratio) redBar.Size = UDim2.new(0, fontSize * 4, 0, fontSize / 2) greenBar.Size = UDim2.new(ratio, 0, 1, 0) local width = fontSize * 4 health.Size = UDim2.new(0, width, 0, fontSize) health.Enabled = (dist <= 100 and head.Transparency < 1) health.StudsOffsetWorldSpace = Vector3.new(0, 1.5, 0) if hPlayer and game:FindService("Teams") then playerName.TextColor = hPlayer.TeamColor else playerName.TextColor3 = Color3.new(1, 1, 1) end local overWriter = char:FindFirstChild("NameOverwrite") if overWriter and overWriter:IsA("StringValue") then playerName.Text = overWriter.Value else playerName.Text = char.Name end end updateCon = rs.RenderStepped:Connect(update) currentHealth = health h.DisplayDistanceType = "None" end end end onAncestryChanged() h.AncestryChanged:Connect(onAncestryChanged) end local function recurse(obj) for _,v in pairs(obj:GetChildren()) do if v:IsA("Humanoid") then humanoids[v] = true else recurse(v) end end end recurse(workspace) for h in pairs(humanoids) do humanoids[h] = true spawn(function () setupHumanoid(h) end) end local function onDescendantAdded(child) if child:IsA("Humanoid") then humanoids[child] = true setupHumanoid(child) end end local function onDescendantRemoved(child) if humanoids[child] then humanoids[child] = nil end end recurse(workspace) workspace.DescendantAdded:connect(onDescendantAdded) workspace.DescendantRemoving:connect(onDescendantRemoved) Health false null true true true false 0 0 -1 true 0 0 0 0 0 0 0 INF null true null 0 96 0 24 0 0 0 0 0 0 1.5 0 0 PlayerName false 0.5 0.75 true true 1 1 1 1 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 1 false false 9 0 1 null null null null 0.5 0 0 0 null 0 false null 10 0 1 0 0 CloneTrooper1019 1 1 1 true 24 0 0 0 0 0 0 true 2 1 true 1 RedBar false 0.5 0.5 true true 1 0 0 0 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 0 null null null null 0.5 0 0.5 0 null 0 false null 0.6000000238418579 0 0.30000001192092896 0 0 0 true 1 GreenBar false 0 0 true true 0.5058823823928833 0.7725490927696228 0.08627451211214066 0 0.10588239878416061 0.16470590233802795 0.20784319937229156 0 0 false false 0 null null null null 0 0 0 0 null 0 false null 1 0 1 0 0 0 true 1 InputGateway local UserInputService = game:GetService("UserInputService") local ContextActionService = game:GetService("ContextActionService") local Debris = game:GetService("Debris") local gateway = script.Parent local tool = gateway.Parent local remote = gateway:WaitForChild("Gateway") local player = game.Players.LocalPlayer local mouse = player:GetMouse() local isActive = false -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Standard Input -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local function activate(active,cf) isActive = active remote:FireServer("SetActive",active,cf) while isActive do wait(.1) remote:FireServer("SetTarget",mouse.Hit) end end local function onKey(input) local keyCode = input.KeyCode.Name local down = (input.UserInputState.Name == "Begin") remote:FireServer("KeyEvent",keyCode,down) end local function onInputBegan(input,gameProcessed) if not gameProcessed then local name = input.UserInputType.Name if name == "MouseButton1" then activate(true,mouse.Hit) elseif name == "Touch" then wait(.1) local state = input.UserInputState.Name if state == "End" or state == "Cancel" then activate(true,mouse.Hit) end elseif name == "Gamepad1" then local keyCode = input.KeyCode.Name if keyCode == "ButtonR2" then activate(true,mouse.Hit) end elseif name == "Keyboard" then onKey(input) end end end local function onInputEnded(input,gameProcessed) if not gameProcessed and isActive then local name = input.UserInputType.Name if name == "MouseButton1" or name == "Touch" or name == "Gamepad1" then activate(false,mouse.Hit) elseif name == "Keyboard" then onKey(input) end end end UserInputService.InputBegan:Connect(onInputBegan) UserInputService.InputEnded:Connect(onInputEnded) -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Special case Input -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local mControlScheme = tool:WaitForChild("ControlScheme",5) if mControlScheme then local controlSchemeData = require(mControlScheme) local controlScheme = controlSchemeData.Buttons local activateContext = controlSchemeData.ActivateContext local keyEvent = tool:WaitForChild("KeyEvent") local callbacks = {} local hands = { L = "Left", R = "Right" } local handTypes = {"Bumper","Trigger","Joystick (Press)"} local schemeDocs = { Keyboard = {"Hold Left Mouse Button - " .. activateContext}; Gamepad = {"Hold Right Trigger - " .. activateContext}; } for key,data in pairs(controlScheme) do local down = false callbacks[key] = function (actionName,inputState,inputObject) if (inputState.Name == "Begin") and not down then down = true if data.Client then keyEvent:Fire(key,true) else remote:FireServer("KeyEvent",key,true) end elseif (inputState.Name == "End") and down then down = false if data.Client then keyEvent:Fire(key,false) else remote:FireServer("KeyEvent",key,false) end end end local xBtn = data.XboxButton:gsub("Button","") if #xBtn == 2 then local handId,hTypeId = xBtn:match("(%u)(%d)") local hand = hands[handId] local hType = handTypes[tonumber(hTypeId)] xBtn = hand .. " " .. hType else xBtn = "(" .. xBtn .. ")" end table.insert(schemeDocs.Keyboard,key .. " - " .. data.Label) table.insert(schemeDocs.Gamepad,xBtn .. " - " .. data.Label) end local currentSchemeDocMsg local function onLastInputTypeChanged(inputType) if currentSchemeDocMsg and not UserInputService.TouchEnabled and not controlSchemeData.HideControls then local schemeDoc if inputType.Name:find("Gamepad") then schemeDoc = "Gamepad" else schemeDoc = "Keyboard" end currentSchemeDocMsg.Text = schemeDoc .. " Controls:\n\n" .. table.concat(schemeDocs[schemeDoc],"\n") end end local diedCon local equipped = false local function onUnequipped() if equipped then equipped = false for key,data in pairs(controlScheme) do ContextActionService:UnbindAction(data.Label) end currentSchemeDocMsg:Destroy() currentSchemeDocMsg = nil end end local function onEquipped() if not equipped then equipped = true for key,data in pairs(controlScheme) do ContextActionService:BindAction(data.Label,callbacks[key],true,Enum.KeyCode[data.XboxButton]) ContextActionService:SetTitle(data.Label,data.Label) end if UserInputService.TouchEnabled then spawn(function () local playerGui = player:WaitForChild("PlayerGui") local contextActionGui = playerGui:WaitForChild("ContextActionGui") local contextButtonFrame = contextActionGui:WaitForChild("ContextButtonFrame") contextButtonFrame.Size = UDim2.new(3/8,0,3/8,0) contextButtonFrame.AnchorPoint = Vector2.new(1,1) contextButtonFrame.Position = UDim2.new(1,0,1,0) end) end currentSchemeDocMsg = Instance.new("Message") currentSchemeDocMsg.Parent = player onLastInputTypeChanged(UserInputService:GetLastInputType()) if not diedCon then local char = tool.Parent if char then local humanoid = char:FindFirstChildWhichIsA("Humanoid") if humanoid then diedCon = humanoid.Died:Connect(onUnequipped) end end end end end tool.Equipped:Connect(onEquipped) tool.Unequipped:Connect(onUnequipped) UserInputService.LastInputTypeChanged:Connect(onLastInputTypeChanged) end Music local TeleportService = game:GetService("TeleportService") local gameMusic = workspace:WaitForChild("GameMusic",10) if gameMusic and TeleportService:GetTeleportSetting("AllowMusic") then gameMusic:Play() end Shared local TARGET = script.Name do local ReplicatedStorage = game:GetService("ReplicatedStorage") local client = ReplicatedStorage:WaitForChild("Client") local targetScript = client:WaitForChild(TARGET) local activation = require(targetScript) activation(script) end ToolSoundGlitch local CollectionService = game:GetService("CollectionService") local TeleportService = game:GetService("TeleportService") local function onGlitchSoundAdded(glitchSound) if TeleportService:GetTeleportSetting("SoundEquipBug") then glitchSound.MaxDistance = 10000 glitchSound:Play() end end local addSignal = CollectionService:GetInstanceAddedSignal("ToolSoundGlitch") addSignal:Connect(onGlitchSoundAdded) ZoomControls local UserInputService = game:GetService("UserInputService") local GuiService = game:GetService("GuiService") if GuiService:IsTenFootInterface() then return end local IS_TOUCH = UserInputService.TouchEnabled local player = game.Players.LocalPlayer local playerScripts = player:WaitForChild("PlayerScripts") local passCameraEvent = playerScripts:WaitForChild("PassCameraEvent") local self = script.Parent local zoomIn = self:WaitForChild("ZoomIn") local zoomLock = zoomIn:WaitForChild("Lock") local firstPersonIndicator = self:WaitForChild("FirstPersonIndicator") local yellow = Color3.new(1,1,0) local cyan = Color3.new(0,1,1) local white = Color3.new(1,1,1) local c = workspace.CurrentCamera local currentlyDown local function updateCameraStatus() local dist = (c.Focus.p - c.CFrame.p).magnitude firstPersonIndicator.Visible = (dist <= 1.5) zoomLock.Visible = (dist <= 1) end local function setupButton(btn) local isDown = false local inBounds = false local lock = btn:FindFirstChild("Lock") local mouse = player:GetMouse() btn.MouseEnter:connect(function () if (lock == nil or not lock.Visible) then if (currentlyDown == nil or currentlyDown == btn) then inBounds = true if isDown then btn.ImageColor3 = yellow else btn.ImageColor3 = cyan end end end end) btn.MouseLeave:connect(function () if (lock == nil or not lock.Visible) then inBounds = false if isDown then btn.ImageColor3 = cyan else btn.ImageColor3 = white end end end) btn.MouseButton1Down:connect(function () if (lock == nil or not lock.Visible) then isDown = true currentlyDown = btn btn.ImageColor3 = yellow end end) btn.MouseButton1Click:connect(function () if (lock == nil or not lock.Visible) then isDown = false currentlyDown = nil inBounds = false passCameraEvent:Fire(btn.Name) if IS_TOUCH then btn.ImageColor3 = white end end end) mouse.Button1Up:connect(function () if (lock == nil or not lock.Visible) then if isDown then isDown = false currentlyDown = nil if inBounds then inBounds = false passCameraEvent:Fire(btn.Name) end end end btn.ImageColor3 = white end) if lock then lock.Changed:connect(function () if lock.Visible then btn.ImageColor3 = white isDown = false if currentlyDown == btn then currentlyDown = nil end end end) end if IS_TOUCH then btn.Modal = true end end for _,v in pairs(script.Parent:GetChildren()) do if v:IsA("ImageButton") then setupButton(v) end end c.Changed:connect(updateCameraStatus)