local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local localPlayer = Players.LocalPlayer
local emotesModule = require(ReplicatedStorage:WaitForChild("Emotes"))
local allEmotes = emotesModule:GetTable(true)
local emoteList = {}
for emoteName in pairs(allEmotes) do
table.insert(emoteList, emoteName)
end
localPlayer:SetAttribute("Emotes", HttpService:JSONEncode(emoteList))
localPlayer:SetAttribute("ExtraSlots", true)
local character = localPlayer.Character or localPlayer.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local animator = humanoid:FindFirstChildOfClass("Animator")
local currentTracks = {}
local currentConnections = {}
local currentEmoteName = nil
local currentEmoteData = nil
local originalWalkSpeed = humanoid.WalkSpeed
local originalJumpPower = humanoid.JumpPower
local movementLocked = false
local isEnding = false
local function unlockMovement()
if movementLocked then
humanoid.WalkSpeed = originalWalkSpeed
humanoid.JumpPower = originalJumpPower
movementLocked = false
end
end
local function lockMovement(stunType)
originalWalkSpeed = humanoid.WalkSpeed
originalJumpPower = humanoid.JumpPower
if stunType == "Freeze" then
humanoid.WalkSpeed = 0
humanoid.JumpPower = 0
movementLocked = true
elseif stunType == "Slowed" then
humanoid.WalkSpeed = originalWalkSpeed * 0.35
movementLocked = true
end
end
local function hardStop()
for _, t in pairs(currentTracks) do
pcall(function() t:Stop(0) end)
end
currentTracks = {}
for _, c in pairs(currentConnections) do
pcall(function() c:Disconnect() end)
end
currentConnections = {}
currentEmoteName = nil
currentEmoteData = nil
isEnding = false
unlockMovement()
end
local function loadAnim(id)
if not id or id == 0 then return nil end
local anim = Instance.new("Animation")
anim.AnimationId = "rbxassetid://" .. tostring(id)
local ok, track = pcall(function()
return animator:LoadAnimation(anim)
end)
return ok and track or nil
end
local function playEndAnimation()
if not currentEmoteData or not currentEmoteData.End then
hardStop()
return
end
isEnding = true
local endData = currentEmoteData.End
local endAnimId = endData[1]
local endDuration = endData[2] or 2
local endSound = endData[3]
if not movementLocked then
humanoid.WalkSpeed = 0
humanoid.JumpPower = 0
movementLocked = true
end
for _, t in pairs(currentTracks) do
pcall(function() t:Stop(0.15) end)
end
currentTracks = {}
local endTrack = loadAnim(endAnimId)
if endTrack then
endTrack.Looped = false
table.insert(currentTracks, endTrack)
endTrack:Play()
if endSound and endSound.SoundId then
local snd = Instance.new("Sound")
snd.SoundId = endSound.SoundId
snd.Volume = endSound.Volume or 1
snd.Parent = character:FindFirstChild("HumanoidRootPart") or character.PrimaryPart
snd:Play()
game:GetService("Debris"):AddItem(snd, endDuration + 1)
end
end
task.delay(endDuration, hardStop)
end
local function hookKeyframes(data, track)
if not data.Keyframes then return end
for markerName, callback in pairs(data.Keyframes) do
local conn
conn = track:GetMarkerReachedSignal(markerName):Connect(function()
pcall(callback, nil, nil, track, nil)
if markerName ~= "snap" and markerName ~= "clap" and markerName ~= "claploop" and not data.DontDisconnectMarkers then
conn:Disconnect()
end
end)
table.insert(currentConnections, conn)
end
end
local function playEmoteLocal(emoteName)
local data = allEmotes[emoteName]
if not data then return end
if currentEmoteName == emoteName and not isEnding then
playEndAnimation()
return
end
if not data.Animation or data.Animation == 0 then return end
hardStop()
currentEmoteName = emoteName
currentEmoteData = data
local intro = loadAnim(data.Animation)
if not intro then return end
intro.Looped = data.Looped or false
table.insert(currentTracks, intro)
local idle = nil
if not data.Looped and data.Idle and data.Idle ~= 0 then
idle = loadAnim(data.Idle)
if idle then idle.Looped = true end
end
hookKeyframes(data, intro)
if data.Stun then
lockMovement(data.Stun)
end
intro:Play()
intro.Stopped:Once(function()
if currentEmoteName ~= emoteName then return end
if idle then
table.insert(currentTracks, idle)
idle:Play()
elseif not data.Keyframes then
hardStop()
end
end)
end
local communicate = character:WaitForChild("Communicate")
-- GUI Tweaks: Force unlock the second page & Destroy Limited Time Emotes GUI
local function destroyLimitedGui()
local playerGui = localPlayer:FindFirstChild("PlayerGui")
if playerGui then
-- Destroys any element named "Limited" inside the emote ImageLabel
for _, gui in pairs(playerGui:GetDescendants()) do
if gui.Name == "Limited" then
gui:Destroy()
end
end
end
end
-- Run once immediately in case it's already loaded
task.spawn(destroyLimitedGui)
-- Hook into descendants to destroy it if the GUI loads after this script
local playerGui = localPlayer:WaitForChild("PlayerGui")
playerGui.DescendantAdded:Connect(function(desc)
if desc.Name == "Limited" then
task.defer(function()
if desc and desc.Parent then
desc:Destroy()
end
end)
end
end)
local oldNamecall
oldNamecall = hookmetamethod(game, "__namecall", function(self, ...)
local method = getnamecallmethod()
local args = {...}
-- Force the second page to be unlocked
if self == localPlayer and method == "GetAttribute" and args[1] == "ExtraSlots" then
return true
end
if method == "FireServer" and self == communicate then
local data = args[1]
if type(data) == "table" and data.Goal == "Emote" and data.Emote then
task.spawn(playEmoteLocal, data.Emote)
return
end
end
return oldNamecall(self, ...)
end)
UserInputService.InputBegan:Connect(function(input, processed)
if processed then return end
if input.KeyCode == Enum.KeyCode.X and currentEmoteName and not isEnding then
playEndAnimation()
end
end)
Comments
No comments yet
Be the first to share your thoughts!