fe critters script
Key RequiredUniversal

fe critters script

Universal Scriptbobjsbobjs 2.3K views 172 executesUpdated Jun 14, 2026
Unrated
00
Lua Script•1291 lines (82893 chars)
-- // notification and sounds
if not isfolder('ScriptBase') then
        makefolder('ScriptBase')
end

if not isfile('ScriptBase/notification.mp3') then
        writefile('ScriptBase/notification.mp3', game:HttpGet('https://github.com/catthatdrinkssprite/moon-convert/raw/main/ScriptBase/notification.mp3', true))
end

if not isfile('ScriptBase/moonlogomarcus.jpg') then
        writefile('ScriptBase/moonlogomarcus.jpg', game:HttpGet('https://github.com/catthatdrinkssprite/moon-convert/raw/main/ScriptBase/moonlogomarcus.jpg', true))
end

-- // libraries
loadstring(game:HttpGet('https://github.com/catthatdrinkssprite/moon-convert/raw/main/Scripts/Main/Functions.lua', true))()
loadstring(game:HttpGet('https://github.com/catthatdrinkssprite/moon-convert/raw/main/Scripts/Other/sendNotification.lua', true))()

-- // auto-run sphere crown abilities
spawn(function()
        local Player = game:GetService('Players').LocalPlayer

        -- Step 1: Get hats
        GetHats({112577517707627, 76697626212367, 79105771884828, 74945186562243, 132457335931169, 13145305905, 18450658793, 102260781968566, 13129720075, 73802108862290, 11150777065, 10933111577, 115625052934319, 18477084021, 15815225169, 13190203956, 7790701785, 74847008873689})

        -- Step 2: Wait 5 seconds for hats to load
        task.wait(5)
        Functions['reanimate']()

        -- Step 3: Wait 10 seconds for reanimate to finish
        task.wait(10)

        -- Step 4: Load script
        loadstring(game:HttpGet('https://github.com/catthatdrinkssprite/moon-convert/raw/main/Scripts/Other/AlignCharacter.lua', true))()

        local Mouse = Player:GetMouse()
        local runservice = game:GetService('RunService')
        local Players = game:GetService('Players')
        local uis = game:GetService('UserInputService')
        local ins = Instance.new
        local v3 = Vector3.new
        local cf = CFrame.new
        local angles = CFrame.Angles
        local rad = math.rad
        local sin = math.sin
        local cos = math.cos
        local random = math.random
        local clamp = math.clamp

        -- Sphere IDs and name keywords for matching
        local sphereIDs = {
                112577517707627, 76697626212367, 79105771884828, 74945186562243,
                132457335931169, 13145305905, 18450658793, 102260781968566,
                13129720075, 73802108862290, 11150777065, 10933111577,
                115625052934319, 18477084021, 15815225169, 13190203956,
                7790701785, 74847008873689
        }
        local sphereNames = {
                'Dodecahedron', 'Dodecahedron', 'Dodecahedron', 'Dodecahedron',
                'Dodecahedron', 'Stellated', 'Dodecahedron', 'Dice',
                'Icosahedron', 'Reflective', 'Wedge', 'Round Noob',
                'Cute Noob', 'Excited Noob', 'Normal', 'Happy Earth',
                'Pumpkin', 'Servbot'
        }

        -- ============================================
        -- AGGRESSIVELY KILL ALL CLICK FLING
        -- ============================================
        task.wait(1)
        pcall(function()
                for _, conn in ipairs(getconnections(Mouse.Button1Down)) do conn:Disable() end
        end)
        task.wait(0.5)
        pcall(function()
                for _, conn in ipairs(getconnections(Mouse.Button1Down)) do conn:Disable() end
                for _, conn in ipairs(getconnections(Mouse.Button1Up)) do conn:Disable() end
        end)
        task.wait(0.3)
        pcall(function()
                for _, conn in ipairs(getconnections(Mouse.Button1Down)) do conn:Disable() end
                for _, conn in ipairs(getconnections(Mouse.Button1Up)) do conn:Disable() end
        end)

        -- Wait for character parts
        local char = Player.Character
        local function waitForParts()
                for i = 1, 50 do
                        if char and char:FindFirstChild('Head') and char:FindFirstChild('Torso') and char:FindFirstChild('HumanoidRootPart')
                                and char:FindFirstChild('Right Arm') and char:FindFirstChild('Left Arm')
                                and char:FindFirstChild('Right Leg') and char:FindFirstChild('Left Leg') then
                                return true
                        end
                        task.wait(0.5)
                end
                return false
        end
        if not waitForParts() then return end

        local h = char.Head
        local t = char.Torso
        local ra = char['Right Arm']
        local la = char['Left Arm']
        local rl = char['Right Leg']
        local ll = char['Left Leg']
        local rut = char.HumanoidRootPart
        local hum = char:FindFirstChildOfClass('Humanoid')

        -- Remove default animations
        pcall(function()
                if char:FindFirstChild('Animate') then char.Animate:Destroy() end
                if hum and hum:FindFirstChildOfClass('Animator') then hum.Animator:Destroy() end
        end)

        pcall(function()
                hum.MaxHealth = 25000
                hum.Health = hum.MaxHealth
        end)

        -- Save joint references and C0/C1 defaults
        local nec = t:FindFirstChild('Neck') or t:FindFirstChildOfClass('Motor6D')
        local rutj = rut:FindFirstChild('RootJoint') or rut:FindFirstChildOfClass('Motor6D')
        local rs = t:FindFirstChild('Right Shoulder') or t:FindFirstChildOfClass('Motor6D')
        local ls = t:FindFirstChild('Left Shoulder') or t:FindFirstChildOfClass('Motor6D')
        local rh = t:FindFirstChild('Right Hip') or t:FindFirstChildOfClass('Motor6D')
        local lh = t:FindFirstChild('Left Hip') or t:FindFirstChildOfClass('Motor6D')

        necc0,necc1 = cf(0,t.Size.Y/2,0),cf(0,-h.Size.Y/2,0)
        rutjc0,rutjc1 = cf(0,0,0),cf(0,0,0)
        rsc0,rsc1 = cf(t.Size.X/2,t.Size.Y/4,0),cf(-ra.Size.X/2,ra.Size.Y/4,0)
        lsc0,lsc1 = cf(-t.Size.X/2,t.Size.Y/4,0),cf(la.Size.X/2,la.Size.Y/4,0)
        rhc0,rhc1 = cf(t.Size.X/4,-t.Size.Y/2,0),cf(0,rl.Size.Y/2,0)
        lhc0,lhc1 = cf(-t.Size.X/4,-t.Size.Y/2,0),cf(0,ll.Size.Y/2,0)

        -- Remove old joints safely
        pcall(function() nec.Parent = nil end)
        pcall(function() rutj.Parent = nil end)
        pcall(function() rs.Parent = nil end)
        pcall(function() ls.Parent = nil end)
        pcall(function() rh.Parent = nil end)
        pcall(function() lh.Parent = nil end)

        -- Recreate joints
        nec = ins('Motor6D',t) nec.Name = 'Neck' nec.Part0 = t nec.Part1 = h
        nec.C1 = necc1; nec.C0 = necc0
        rutj = ins('Motor6D',rut) rutj.Name = 'RootJoint' rutj.Part0 = t rutj.Part1 = rut
        rutj.C1 = rutjc1; rutj.C0 = rutjc0
        rs = ins('Motor6D',t) rs.Name = 'Right Shoulder' rs.Part0 = t rs.Part1 = ra
        rs.C1 = rsc1; rs.C0 = rsc0
        ls = ins('Motor6D',t) ls.Name = 'Left Shoulder' ls.Part0 = t ls.Part1 = la
        ls.C1 = lsc1; ls.C0 = lsc0
        rh = ins('Motor6D',t) rh.Name = 'Right Hip' rh.Part0 = t rh.Part1 = rl
        rh.C1 = rhc1; rh.C0 = rhc0
        lh = ins('Motor6D',t) lh.Name = 'Left Hip' lh.Part0 = t lh.Part1 = ll
        lh.C1 = lhc1; lh.C0 = lhc0

        -- Animation state
        local anim = 'idle'
        local sine = 0
        local change = 1
        local ws = 25
        local jp = 65

        function swait()
                runservice.Stepped:Wait()
        end

        function rayc(spos, direc, ignore, dist)
                local rai = Ray.new(spos, direc.Unit * dist)
                return workspace:FindPartOnRayWithIgnoreList(rai, ignore, false, false)
        end

        -- ============================================
        -- SPHERE CROWN SETUP (18 spheres)
        -- ============================================
        local spheres = {}
        local totalSpheres = 18
        local crownRadius = 4.5
        local crownHeight = 3

        local function setupSphere(index, acc, handle)
                -- Remove all welds
                for _, w in ipairs(handle:GetChildren()) do
                        if w:IsA('Weld') or w:IsA('WeldConstraint') or w:IsA('Motor6D') then
                                w:Destroy()
                        end
                end
                task.wait(0.05)

                handle.Anchored = false
                handle.Massless = true
                handle.CanCollide = false
                handle.CustomPhysicalProperties = PhysicalProperties.new(0, 0, 0, 0, 0)
                pcall(function() handle:SetNetworkOwner(Player) end)

                local bp = ins('BodyPosition', handle)
                bp.MaxForce = v3(math.huge, math.huge, math.huge)
                bp.P = 50000
                bp.D = 1000

                local bg = ins('BodyGyro', handle)
                bg.MaxTorque = v3(math.huge, math.huge, math.huge)
                bg.P = 50000
                bg.D = 1000

                -- Big invisible hitbox (4x size)
                local hitbox = ins('Part', workspace)
                hitbox.Name = 'CrownHitbox_' .. index
                hitbox.Size = v3(8, 8, 8)
                hitbox.Transparency = 1
                hitbox.CanCollide = false
                hitbox.Massless = true
                hitbox.Anchored = false
                hitbox.CustomPhysicalProperties = PhysicalProperties.new(0, 0, 0, 0, 0)
                pcall(function() hitbox:SetNetworkOwner(Player) end)
                local hitboxWeld = ins('Weld', hitbox)
                hitboxWeld.Part0 = handle
                hitboxWeld.Part1 = hitbox
                hitboxWeld.C0 = cf(0, 0, 0)
                hitboxWeld.C1 = cf(0, 0, 0)

                spheres[index] = {
                        handle = handle,
                        accessory = acc,
                        bp = bp,
                        bg = bg,
                        hitbox = hitbox,
                        hitboxWeld = hitboxWeld,
                        state = 'crown',
                        orbitAngle = (index - 1) * (math.pi * 2 / totalSpheres),
                        bobPhase = random() * math.pi * 2,
                        abilityTarget = nil,
                        abilityVelocity = v3(0, 0, 0),
                        abilityReturnTimer = 0,
                        lastFlingTime = 0
                }
        end

        -- Pass 1: Find from equipped accessories by name
        for _, acc in ipairs(char:GetChildren()) do
                if acc:IsA('Accessory') and acc:FindFirstChild('Handle') then
                        local accName = acc.Name
                        for i, name in ipairs(sphereNames) do
                                if not spheres[i] and string.find(accName, name) then
                                        setupSphere(i, acc, acc.Handle)
                                        break
                                end
                        end
                end
        end

        -- Pass 2: InsertService for missing
        for i = 1, totalSpheres do
                if not spheres[i] then
                        pcall(function()
                                local insertService = game:GetService('InsertService')
                                local asset = insertService:LoadAsset(sphereIDs[i])
                                if asset then
                                        for _, v in ipairs(asset:GetChildren()) do
                                                if v:IsA('Accessory') and v:FindFirstChild('Handle') then
                                                        v.Parent = char
                                                        task.wait(0.2)
                                                        setupSphere(i, v, v.Handle)
                                                        break
                                                end
                                        end
                                        asset:Destroy()
                                end
                        end)
                        task.wait(0.3)
                end
        end

        -- Pass 3: Fill remaining with any leftover accessories
        for _, acc in ipairs(char:GetChildren()) do
                if acc:IsA('Accessory') and acc:FindFirstChild('Handle') then
                        local used = false
                        for _, s in ipairs(spheres) do
                                if s and s.accessory == acc then used = true; break end
                        end
                        if not used then
                                for i = 1, totalSpheres do
                                        if not spheres[i] then
                                                setupSphere(i, acc, acc.Handle)
                                                break
                                        end
                                end
                        end
                end
        end

        -- ============================================
        -- FLING FUNCTION
        -- ============================================
        local function flingPlayer(targetChar, sourcePart)
                if not targetChar then return end
                local rootPart = targetChar:FindFirstChild('HumanoidRootPart') or targetChar:FindFirstChild('Torso')
                if not rootPart then return end

                local origin = sourcePart and sourcePart.Position or rut.Position
                local flingDir = (rootPart.Position - origin).Unit
                flingDir = flingDir + v3(random(-0.3, 0.3), 0.8, random(-0.3, 0.3))
                local flingForce = flingDir.Unit * 1000

                rootPart.AssemblyLinearVelocity = flingForce + v3(0, 500, 0)
                rootPart.AssemblyAngularVelocity = v3(random(-800,800), random(-800,800), random(-800,800))

                for _, part in ipairs(targetChar:GetChildren()) do
                        if part:IsA('BasePart') and part ~= rootPart then
                                part.AssemblyLinearVelocity = flingForce * 0.7 + v3(random(-400,400), random(200,600), random(-400,400))
                                part.AssemblyAngularVelocity = v3(random(-1200,1200), random(-1200,1200), random(-1200,1200))
                        end
                end
        end

        -- ============================================
        -- CLICK FLING (replaces reanimate fling)
        -- ============================================
        local clickActiveSphere = nil

        Mouse.Button1Down:Connect(function()
                if abilityActive then return end
                if clickActiveSphere then return end

                -- Find nearest player to mouse hit
                local clickPos = Mouse.Hit.Position
                local nearestChar = nil
                local nearestDist = math.huge
                for _, plr in ipairs(Players:GetPlayers()) do
                        if plr ~= Player and plr.Character and plr.Character:FindFirstChild('HumanoidRootPart') then
                                local targetHum = plr.Character:FindFirstChildOfClass('Humanoid')
                                if targetHum and targetHum.Health > 0 then
                                        local dist = (plr.Character.HumanoidRootPart.Position - clickPos).Magnitude
                                        if dist < nearestDist and dist < 100 then
                                                nearestDist = dist
                                                nearestChar = plr.Character
                                        end
                                end
                        end
                end

                if nearestChar then
                        -- Send nearest available sphere to fling them
                        for i = 1, totalSpheres do
                                if spheres[i] and spheres[i].state == 'crown' then
                                        local s = spheres[i]
                                        clickActiveSphere = s
                                        s.state = 'click'
                                        s.abilityTarget = nearestChar
                                        s.abilityReturnTimer = tick()
                                        -- Direct fling via velocity on sphere
                                        local targetRoot = nearestChar.HumanoidRootPart or nearestChar:FindFirstChild('Torso')
                                        if targetRoot then
                                                local dir = (targetRoot.Position - s.handle.Position).Unit
                                                s.abilityVelocity = dir * 200
                                        end
                                        break
                                end
                        end
                end
        end)

        -- ============================================
        -- TOUCHED EVENTS (fling on contact)
        -- ============================================
        for i = 1, totalSpheres do
                if spheres[i] then
                        local sData = spheres[i]
                        local function onTouched(hit)
                                if sData.state == 'crown' then return end
                                if tick() < sData.lastFlingTime + 0.5 then return end
                                if hit:IsDescendantOf(char) then return end
                                local targetChar = hit.Parent
                                for _ = 1, 5 do
                                        if targetChar and targetChar:FindFirstChildOfClass('Humanoid') then break end
                                        if targetChar then targetChar = targetChar.Parent else break end
                                end
                                if not targetChar then return end
                                local targetHum = targetChar:FindFirstChildOfClass('Humanoid')
                                if targetHum and targetHum.Health > 0 and targetHum ~= hum then
                                        flingPlayer(targetChar, sData.handle)
                                        sData.lastFlingTime = tick()
                                        -- If this was a click sphere, return it
                                        if sData.state == 'click' then
                                                sData.state = 'returning'
                                                sData.abilityReturnTimer = tick()
                                        end
                                end
                        end
                        sData.hitbox.Touched:Connect(onTouched)
                        sData.handle.Touched:Connect(onTouched)
                end
        end

        -- ============================================
        -- ABILITY SYSTEM
        -- ============================================
        local abilityActive = false
        local abilityName = nil
        local abilityStartTime = 0
        local cooldowns = {q = 0, e = 0, r = 0, f = 0, c = 0}

        local function getNearestPlayers(fromPos, count, excludeChar)
                local playerList = {}
                for _, plr in ipairs(Players:GetPlayers()) do
                        if plr ~= Player and plr.Character and plr.Character:FindFirstChild('HumanoidRootPart') then
                                local targetHum = plr.Character:FindFirstChildOfClass('Humanoid')
                                if targetHum and targetHum.Health > 0 and plr.Character ~= excludeChar then
                                        local dist = (plr.Character.HumanoidRootPart.Position - fromPos).Magnitude
                                        if dist < 300 then
                                                table.insert(playerList, {char = plr.Character, dist = dist})
                                        end
                                end
                        end
                end
                table.sort(playerList, function(a, b) return a.dist < b.dist end)
                local result = {}
                for i = 1, math.min(count, #playerList) do
                        result[i] = playerList[i].char
                end
                return result
        end

        -- Q: SPHERE JUGGLE - juggle all spheres in a cascade pattern
        local function activateQ()
                if abilityActive or crownizeActive then return end
                if tick() < cooldowns.q then return end
                abilityActive = true
                abilityName = 'q'
                abilityStartTime = tick()
                cooldowns.q = tick() + 8
                for i = 1, totalSpheres do
                        if spheres[i] then
                                spheres[i].state = 'ability'
                                -- Stagger start times for cascade juggle effect
                                spheres[i].abilityTarget = (i - 1) * 0.15
                        end
                end
        end

        -- E: SPHERE SHOTGUN - all spheres fire toward mouse position
        local function activateE()
                if abilityActive or crownizeActive then return end
                if tick() < cooldowns.e then return end
                abilityActive = true
                abilityName = 'e'
                abilityStartTime = tick()
                cooldowns.e = tick() + 6
                local targetPos = Mouse.Hit.Position
                local baseDir = (targetPos - rut.Position).Unit
                for i = 1, totalSpheres do
                        if spheres[i] then
                                spheres[i].state = 'ability'
                                local spreadAngle = ((i - 1) - totalSpheres / 2) * 0.03
                                local right = baseDir:Cross(v3(0, 1, 0)).Unit
                                local up = v3(0, 1, 0)
                                local dir = (baseDir + right * spreadAngle + up * random(-0.05, 0.05)).Unit
                                spheres[i].abilityVelocity = dir * 180
                                spheres[i].abilityTarget = targetPos + dir * 100
                        end
                end
        end

        -- R: SPHERE VORTEX - spheres orbit player fast, fling anyone close
        local function activateR()
                if abilityActive or crownizeActive then return end
                if tick() < cooldowns.r then return end
                abilityActive = true
                abilityName = 'r'
                abilityStartTime = tick()
                cooldowns.r = tick() + 10
                for i = 1, totalSpheres do
                        if spheres[i] then
                                spheres[i].state = 'ability'
                        end
                end
        end

        -- F: SPHERE HOMING - each sphere picks a different player and chases them
        local function activateF()
                if abilityActive or crownizeActive then return end
                if tick() < cooldowns.f then return end
                abilityActive = true
                abilityName = 'f'
                abilityStartTime = tick()
                cooldowns.f = tick() + 12
                local targets = getNearestPlayers(rut.Position, totalSpheres)
                for i = 1, totalSpheres do
                        if spheres[i] then
                                spheres[i].state = 'ability'
                                if targets[i] then
                                        spheres[i].abilityTarget = targets[i]
                                else
                                        spheres[i].abilityTarget = nil
                                end
                        end
                end
        end

        -- G: CROWNIZE - permanently place spheres on every player's head, toggle off with G
        local crownizeActive = false

        -- ============================================
        -- H: BIND SYSTEM - click accessory then click player to bind them
        -- Bound players always get their assigned sphere when G is pressed
        -- ============================================
        local bindMode = false         -- true when in bind mode
        local bindStep = 0             -- 0 = not binding, 1 = waiting for sphere click, 2 = waiting for player click
        local bindSelectedSphere = nil  -- the sphere index selected in step 1
        local playerBindings = {}      -- { [playerName] = sphereIndex }

        local function startBindMode()
                if abilityActive then return end
                bindMode = true
                bindStep = 1
                bindSelectedSphere = nil
                sendNotification('BIND MODE: Click on a sphere to select it', 5)
        end

        -- Bind click handler - intercepts clicks only during bind mode
        local bindClickConn = nil
        bindClickConn = Mouse.Button1Down:Connect(function()
                if not bindMode then return end

                if bindStep == 1 then
                        -- Step 1: Find which sphere the mouse is closest to
                        local clickPos = Mouse.Hit.Position
                        local closestSphere = nil
                        local closestDist = math.huge
                        for i = 1, totalSpheres do
                                if spheres[i] and spheres[i].handle and spheres[i].handle.Parent then
                                        local dist = (spheres[i].handle.Position - clickPos).Magnitude
                                        if dist < closestDist and dist < 8 then
                                                closestDist = dist
                                                closestSphere = i
                                        end
                                end
                        end

                        if closestSphere then
                                bindSelectedSphere = closestSphere
                                bindStep = 2
                                sendNotification('Selected sphere ' .. closestSphere .. '! Now click on a player', 5)
                        else
                                sendNotification('No sphere nearby, click closer to one', 3)
                        end

                elseif bindStep == 2 then
                        -- Step 2: Find which player the mouse is closest to
                        local clickPos = Mouse.Hit.Position
                        local nearestPlayer = nil
                        local nearestDist = math.huge
                        for _, plr in ipairs(Players:GetPlayers()) do
                                if plr ~= Player and plr.Character and plr.Character:FindFirstChild('HumanoidRootPart') then
                                        local tHum = plr.Character:FindFirstChildOfClass('Humanoid')
                                        if tHum and tHum.Health > 0 then
                                                local dist = (plr.Character.HumanoidRootPart.Position - clickPos).Magnitude
                                                if dist < nearestDist and dist < 15 then
                                                        nearestDist = dist
                                                        nearestPlayer = plr
                                                end
                                        end
                                end
                        end

                        if nearestPlayer then
                                -- Save binding: this player always gets this sphere
                                playerBindings[nearestPlayer.Name] = bindSelectedSphere
                                sendNotification('Bound ' .. nearestPlayer.Name .. ' to sphere ' .. bindSelectedSphere .. '!', 5)
                                -- Show all bindings
                                local bindList = ''
                                local count = 0
                                for name, idx in pairs(playerBindings) do
                                        bindList = bindList .. name .. '=' .. idx .. ' '
                                        count = count + 1
                                end
                                if count > 0 then
                                        sendNotification('Bindings: ' .. bindList, 6)
                                end
                        else
                                sendNotification('No player nearby, click closer to someone', 3)
                        end

                        -- Exit bind mode
                        bindMode = false
                        bindStep = 0
                        bindSelectedSphere = nil
                end
        end)

        local function toggleCrownize()
                if abilityActive then return end
                crownizeActive = not crownizeActive
                if crownizeActive then
                        -- Apply saved bindings first
                        local assignedSpheres = {}
                        for plrName, sphereIdx in pairs(playerBindings) do
                                local targetPlr = Players:FindFirstChild(plrName)
                                if targetPlr and targetPlr.Character and targetPlr.Character:FindFirstChild('HumanoidRootPart') then
                                        local targetHum = targetPlr.Character:FindFirstChildOfClass('Humanoid')
                                        if targetHum and targetHum.Health > 0 and spheres[sphereIdx] then
                                                spheres[sphereIdx].state = 'crownize'
                                                spheres[sphereIdx].abilityTarget = targetPlr.Character
                                                assignedSpheres[sphereIdx] = true
                                        end
                                end
                        end

                        -- Fill remaining spheres with nearest unassigned players
                        local remainingTargets = getNearestPlayers(rut.Position, totalSpheres)
                        local targetIdx = 1
                        for i = 1, totalSpheres do
                                if spheres[i] and not assignedSpheres[i] then
                                        spheres[i].state = 'crownize'
                                        while targetIdx <= #remainingTargets do
                                                local tChar = remainingTargets[targetIdx]
                                                local alreadyBound = false
                                                for _, s in ipairs(spheres) do
                                                        if s and s.state == 'crownize' and s.abilityTarget == tChar then
                                                                alreadyBound = true
                                                                break
                                                        end
                                                end
                                                if not alreadyBound then
                                                        spheres[i].abilityTarget = tChar
                                                        targetIdx = targetIdx + 1
                                                        break
                                                end
                                                targetIdx = targetIdx + 1
                                        end
                                        if targetIdx > #remainingTargets then
                                                spheres[i].abilityTarget = nil
                                        end
                                end
                        end

                        sendNotification('crownize ON' .. (#playerBindings > 0 and ' (' .. #playerBindings .. ' bindings)' or ''), 3)
                else
                        -- Return all spheres to crown
                        for i = 1, totalSpheres do
                                if spheres[i] and spheres[i].state == 'crownize' then
                                        spheres[i].state = 'returning'
                                        spheres[i].abilityReturnTimer = tick()
                                        spheres[i].abilityTarget = nil
                                end
                        end
                end
        end

        -- C: SPIN TOWER - spheres on ground, spin, launch up into tower, fall onto back in undecagon
        local function activateC()
                if abilityActive or crownizeActive then return end
                if tick() < cooldowns.c then return end
                abilityActive = true
                abilityName = 'c'
                abilityStartTime = tick()
                cooldowns.c = tick() + 14
                for i = 1, totalSpheres do
                        if spheres[i] then
                                spheres[i].state = 'ability'
                                -- Each sphere gets a fixed angle on the ground ring
                                spheres[i].abilityTarget = (i - 1) * (math.pi * 2 / totalSpheres)
                        end
                end
        end

        -- Keybinds
        uis.InputBegan:Connect(function(input, gp)
                if gp then return end
                if input.KeyCode == Enum.KeyCode.Q then
                        activateQ()
                elseif input.KeyCode == Enum.KeyCode.E then
                        activateE()
                elseif input.KeyCode == Enum.KeyCode.R then
                        activateR()
                elseif input.KeyCode == Enum.KeyCode.F then
                        activateF()
                elseif input.KeyCode == Enum.KeyCode.C then
                        activateC()
                elseif input.KeyCode == Enum.KeyCode.G then
                        toggleCrownize()
                elseif input.KeyCode == Enum.KeyCode.H then
                        startBindMode()
                end
        end)

        -- ============================================
        -- MAIN HEARTBEAT (sphere positioning + ability logic)
        -- ============================================
        runservice.Heartbeat:Connect(function(dt)
                local now = tick()

                -- Check if ability should end
                if abilityActive then
                        local elapsed = now - abilityStartTime
                        local shouldEnd = false

                        if abilityName == 'q' and elapsed > 6 then shouldEnd = true end
                        if abilityName == 'e' and elapsed > 2 then shouldEnd = true end
                        if abilityName == 'r' and elapsed > 5 then shouldEnd = true end
                                -- For vortex, fling anyone within range each frame
                                if abilityName == 'r' then
                                        for i = 1, totalSpheres do
                                                if spheres[i] and spheres[i].state == 'ability' then
                                                        local sPos = spheres[i].handle.Position
                                                        for _, plr in ipairs(Players:GetPlayers()) do
                                                                if plr ~= Player and plr.Character and plr.Character:FindFirstChild('HumanoidRootPart') then
                                                                        local tRoot = plr.Character.HumanoidRootPart
                                                                        if (tRoot.Position - sPos).Magnitude < 12 then
                                                                                local tHum = plr.Character:FindFirstChildOfClass('Humanoid')
                                                                                if tHum and tHum.Health > 0 then
                                                                                        flingPlayer(plr.Character, spheres[i].handle)
                                                                                end
                                                                        end
                                                                end
                                                        end
                                                end
                                        end
                                end
                        if abilityName == 'f' and elapsed > 6 then shouldEnd = true end
                        if abilityName == 'c' and elapsed > 12 then shouldEnd = true end

                        if shouldEnd then
                                abilityActive = false
                                abilityName = nil
                                for i = 1, totalSpheres do
                                        if spheres[i] and spheres[i].state == 'ability' then
                                                spheres[i].state = 'returning'
                                                spheres[i].abilityReturnTimer = now
                                        end
                                end
                        end
                end

                -- Update each sphere
                for i = 1, totalSpheres do
                        local s = spheres[i]
                        if not s then continue end
                        if not s.handle or not s.handle.Parent then continue end
                        if not s.bp or not s.bp.Parent or not s.bg or not s.bg.Parent then continue end

                        s.bobPhase = s.bobPhase + dt * 4

                        if s.state == 'crown' then
                                -- Normal crown orbit
                                s.orbitAngle = s.orbitAngle + dt * 1.5
                                local ox = math.cos(s.orbitAngle) * crownRadius
                                local oz = math.sin(s.orbitAngle) * crownRadius
                                local oy = crownHeight + math.sin(s.bobPhase) * 0.3
                                local targetPos = rut.CFrame * cf(ox, oy, oz)
                                s.bp.Position = targetPos.Position
                                s.bg.CFrame = targetPos
                                s.handle.Velocity = v3(0, 0, 0)
                                s.handle.RotVelocity = v3(0, 3, 0)

                        elseif s.state == 'click' then
                                -- Click sphere flying toward target
                                s.bp.Position = s.bp.Position + s.abilityVelocity * dt
                                s.bg.CFrame = cf(s.handle.Position, s.handle.Position + s.abilityVelocity)
                                s.handle.RotVelocity = s.abilityVelocity * 0.3

                                -- Timeout after 1.5s, return
                                if now - s.abilityReturnTimer > 1.5 then
                                        s.state = 'returning'
                                        s.abilityReturnTimer = now
                                end

                                -- Check if reached target area
                                if s.abilityTarget and s.abilityTarget.Parent then
                                        local tRoot = s.abilityTarget:FindFirstChild('HumanoidRootPart')
                                        if tRoot and (s.handle.Position - tRoot.Position).Magnitude < 5 then
                                                flingPlayer(s.abilityTarget, s.handle)
                                                s.lastFlingTime = now
                                                s.state = 'returning'
                                                s.abilityReturnTimer = now
                                        end
                                end

                        elseif s.state == 'ability' then
                                local elapsed = now - abilityStartTime

                                if abilityName == 'q' then
                                        -- Q: JUGGLE - cascade juggle pattern
                                        -- Each sphere follows a parabolic arc, alternating left/right hand
                                        local delay = s.abilityTarget or 0
                                        local jTime = elapsed - delay
                                        local cycleTime = 0.8 -- time for one full throw arc
                                        local t = (jTime % cycleTime) / cycleTime -- 0 to 1 progress through arc

                                        if jTime < 0 then
                                                -- Not started yet, hold at crown
                                                s.bp.Position = s.bp.Position
                                                s.bg.CFrame = s.bg.CFrame
                                        else
                                                -- Parabolic arc: x goes from -1.5 to 1.5 (left to right hand), y arcs up
                                                local handOffset = (i % 2 == 0) and 1 or -1
                                                local xPos = handOffset * 2.5 * (1 - 2 * t) -- cross from one hand to other, wider spread
                                                local arcHeight = 4 + (totalSpheres - i) * 0.2 -- higher spheres on top of cascade
                                                local yPos = arcHeight * sin(t * math.pi) -- parabolic arc
                                                local zPos = math.sin(t * math.pi) * 0.5

                                                local jugglePos = rut.CFrame * cf(xPos, 2.5 + yPos, -0.5 + zPos)
                                                s.bp.Position = jugglePos.Position
                                                s.bg.CFrame = jugglePos
                                                -- Spin while in air
                                                s.handle.RotVelocity = v3(random(-10,10), 12 * (1 - math.abs(t - 0.5) * 2), random(-10,10))
                                        end

                                elseif abilityName == 'e' then
                                        -- SPHERE SHOTGUN: fly toward target
                                        s.bp.Position = s.bp.Position + s.abilityVelocity * dt
                                        s.bg.CFrame = cf(s.handle.Position, s.handle.Position + s.abilityVelocity)
                                        s.handle.RotVelocity = s.abilityVelocity * 0.4

                                        -- Check if reached target area
                                        if (s.handle.Position - s.abilityTarget).Magnitude < 8 then
                                                s.state = 'returning'
                                                s.abilityReturnTimer = now
                                        end
                                        -- Timeout
                                        if elapsed > 1.5 then
                                                s.state = 'returning'
                                                s.abilityReturnTimer = now
                                        end

                                elseif abilityName == 'r' then
                                        -- SPHERE VORTEX: fast orbit around player
                                        local vortexAngle = s.orbitAngle + elapsed * 14
                                        local vortexR = 8 + math.sin(s.bobPhase) * 1.5
                                        local heightOff = math.sin(s.bobPhase + i * 0.8) * 3
                                        local ox = math.cos(vortexAngle) * vortexR
                                        local oz = math.sin(vortexAngle) * vortexR
                                        local oy = crownHeight + heightOff
                                        local targetPos = rut.CFrame * cf(ox, oy, oz)
                                        s.bp.Position = targetPos.Position
                                        s.bg.CFrame = cf(s.handle.Position, rut.Position)
                                        s.handle.RotVelocity = v3(random(-25,25), random(-25,25), random(-25,25))

                                elseif abilityName == 'f' then
                                        -- SPHERE HOMING: chase target player
                                        if s.abilityTarget and s.abilityTarget.Parent and s.abilityTarget:FindFirstChild('HumanoidRootPart') then
                                                local targetRoot = s.abilityTarget.HumanoidRootPart
                                                local targetHum = s.abilityTarget:FindFirstChildOfClass('Humanoid')
                                                if targetHum and targetHum.Health > 0 then
                                                        local targetPos = targetRoot.Position + v3(0, 3, 0)
                                                        s.bp.Position = targetPos
                                                        s.bg.CFrame = cf(s.handle.Position, targetPos)
                                                        s.handle.RotVelocity = v3(random(-15,15), 15, random(-15,15))
                                                else
                                                        -- Target dead, orbit wide
                                                        s.abilityTarget = nil
                                                end
                                        end
                                        if not s.abilityTarget then
                                                -- No target, orbit at wider radius
                                                local angle = s.orbitAngle + elapsed * 4
                                                local ox = math.cos(angle) * 10
                                                local oz = math.sin(angle) * 10
                                                local targetPos = rut.CFrame * cf(ox, crownHeight, oz)
                                                s.bp.Position = targetPos.Position
                                                s.bg.CFrame = targetPos
                                                s.handle.RotVelocity = v3(0, 8, 0)
                                        end

                                elseif abilityName == 'c' then
                                        -- C: SPIN TOWER - multi phase
                                        local sphereAngle = s.abilityTarget or 0
                                        local ringRadius = 6

                                        if elapsed < 1.2 then
                                                -- PHASE 1: Spheres on ground, spinning around player
                                                -- Player is spinning, spheres stay at their angle on the ring
                                                local spinSpeed = elapsed * 15
                                                local currentAngle = sphereAngle + elapsed * spinSpeed
                                                local gx = math.cos(currentAngle) * ringRadius
                                                local gz = math.sin(currentAngle) * ringRadius
                                                local groundPos = rut.CFrame * cf(gx, -rut.Size.Y / 2 + 1, gz)
                                                s.bp.Position = groundPos.Position
                                                s.bg.CFrame = cf(s.handle.Position, s.handle.Position + v3(0, 0, 1))
                                                -- Roll on ground
                                                s.handle.RotVelocity = v3(random(-30,30), 0, random(-30,30))

                                        elseif elapsed < 3.5 then
                                                -- PHASE 2: Launch upward, form a tower
                                                local launchProgress = clamp((elapsed - 1.2) / 1.5, 0, 1)
                                                local towerY = launchProgress * (totalSpheres * 1.2)
                                                local stackIndex = i - 1
                                                local sphereY = -2 + stackIndex * 1.2
                                                local lerpY = sphereY * launchProgress
                                                local towerPos = rut.CFrame * cf(0, rut.Size.Y / 2 + lerpY + 1.5, 0)
                                                s.bp.Position = towerPos.Position
                                                s.bg.CFrame = towerPos
                                                s.handle.RotVelocity = v3(0, 10, 0)

                                        elseif elapsed < 7 then
                                                -- PHASE 3: Tower holds briefly, then spheres fall with gravity
                                                local holdEnd = 3.8
                                                local fallStart = holdEnd
                                                if elapsed < holdEnd then
                                                        -- Still holding tower
                                                        local sphereY = (i - 1) * 1.2
                                                        local towerPos = rut.CFrame * cf(0, rut.Size.Y / 2 + sphereY + 1.5, 0)
                                                        s.bp.Position = towerPos.Position
                                                        s.bg.CFrame = towerPos
                                                        s.handle.RotVelocity = v3(0, 5, 0)
                                                else
                                                        -- Falling with gravity
                                                        local fallTime = elapsed - fallStart
                                                        local sphereY = (i - 1) * 1.2
                                                        local gravity = 70
                                                        local fallDist = 0.5 * gravity * fallTime * fallTime
                                                        local fallY = math.max(-fallDist + sphereY, -3)
                                                        -- Arc toward the back
                                                        local backOffset = -2 - fallTime * 2
                                                        local towerPos = rut.CFrame * cf(0, rut.Size.Y / 2 + fallY + 1.5, backOffset)
                                                        s.bp.Position = towerPos.Position
                                                        s.bg.CFrame = towerPos
                                                        s.handle.RotVelocity = v3(random(-15,15), random(-15,15), random(-15,15))
                                                end

                                        else
                                                -- PHASE 4: Settle into undecagon on back
                                                local settleProgress = clamp((elapsed - 7) / 1.5, 0, 1)
                                                local ease = settleProgress * settleProgress * (3 - 2 * settleProgress)
                                                local backAngle = sphereAngle
                                                local backRadius = 2
                                                local backX = math.cos(backAngle) * backRadius
                                                local backZ = math.sin(backAngle) * backRadius - 2
                                                local backY = rut.Size.Y / 2 + 0.5
                                                local backPos = rut.CFrame * cf(backX, backY, backZ)

                                                -- Interpolate from wherever sphere is to back position
                                                s.bp.Position = s.bp.Position:Lerp(backPos.Position, ease * 0.15)
                                                s.bg.CFrame = backPos
                                                s.handle.RotVelocity = v3(0, 2 * (1 - ease), 0)
                                        end
                                end

                        elseif s.state == 'crownize' then
                                -- Stay on target player's head permanently
                                if s.abilityTarget and s.abilityTarget.Parent and s.abilityTarget:FindFirstChild('HumanoidRootPart') then
                                        local targetRoot = s.abilityTarget.HumanoidRootPart
                                        local targetHum = s.abilityTarget:FindFirstChildOfClass('Humanoid')
                                        if targetHum and targetHum.Health > 0 then
                                                -- Pet position: behind player 3 studs, just above head
                                                local petPos = targetRoot.CFrame * cf(0, 4 + math.sin(s.bobPhase) * 0.3, -3)
                                                s.bp.Position = petPos.Position
                                                s.bg.CFrame = petPos
                                                s.handle.RotVelocity = v3(0, 4, 0)
                                        else
                                                -- Target died, find new one
                                                local newTargets = getNearestPlayers(rut.Position, totalSpheres)
                                                for _, t in ipairs(newTargets) do
                                                        local taken = false
                                                        for j = 1, totalSpheres do
                                                                if spheres[j] and spheres[j].abilityTarget == t then taken = true; break end
                                                        end
                                                        if not taken then
                                                                s.abilityTarget = t
                                                                break
                                                        end
                                                end
                                        end
                                else
                                        -- Target gone, find new one or return
                                        local newTargets = getNearestPlayers(rut.Position, totalSpheres)
                                        local found = false
                                        for _, t in ipairs(newTargets) do
                                                local taken = false
                                                for j = 1, totalSpheres do
                                                        if spheres[j] and spheres[j].abilityTarget == t then taken = true; break end
                                                end
                                                if not taken then
                                                        s.abilityTarget = t
                                                        found = true
                                                        break
                                                end
                                        end
                                        if not found then
                                                s.state = 'returning'
                                                s.abilityReturnTimer = now
                                                s.abilityTarget = nil
                                        end
                                end

                        elseif s.state == 'returning' then
                                -- Smoothly return to crown position
                                local returnElapsed = now - s.abilityReturnTimer
                                if returnElapsed < 1.2 then
                                        s.orbitAngle = s.orbitAngle + dt * 1.5
                                        local ox = math.cos(s.orbitAngle) * crownRadius
                                        local oz = math.sin(s.orbitAngle) * crownRadius
                                        local oy = crownHeight + math.sin(s.bobPhase) * 0.3
                                        local orbitPos = rut.CFrame * cf(ox, oy, oz)
                                        s.bp.Position = orbitPos.Position
                                        s.bg.CFrame = orbitPos
                                        s.handle.RotVelocity = v3(0, 5, 0)
                                else
                                        s.state = 'crown'
                                        if s == clickActiveSphere then
                                                clickActiveSphere = nil
                                        end
                                end
                        end
                end
        end)

        -- ============================================
        -- CHARACTER ANIMATION HEARTBEAT
        -- ============================================
        runservice.Heartbeat:Connect(function()
                sine = sine + change

                local verVel = rut.Velocity.Y
                local horVel = (rut.Velocity * v3(1,0,1)).Magnitude
                local Ccf = rut.CFrame
                local dir = hum.MoveDirection

                if dir == v3(0,0,0) then
                        dir = rut.Velocity / 10
                end

                hum.WalkSpeed = ws
                hum.JumpPower = jp

                local Walktest1 = dir * Ccf.LookVector
                local Walktest2 = dir * Ccf.RightVector
                local rotfb = Walktest1.X + Walktest1.Z
                local rotrl = Walktest2.X + Walktest2.Z

                if rotfb > 1 then rotfb = 1 elseif rotfb < -1 then rotfb = -1 end
                if rotrl > 1 then rotrl = 1 elseif rotrl < -1 then rotrl = -1 end

                local hit = rayc(rut.Position + v3(0,-rut.Size.Y/2,0), v3(rut.Position.x,-10000,rut.Position.z), {char}, 3)

                if abilityActive then
                        -- ==========================================
                        -- ABILITY ANIMATIONS (override normal anim)
                        -- Each ability in its own pcall so errors don't kill all
                        -- ==========================================
                        local elapsed = tick() - abilityStartTime
                        local a = 0.8  -- fast lerp so poses are visible

                        if abilityName == 'q' then
                                pcall(function()
                                        -- Q: JUGGLING animation - arms alternate throwing/catching
                                        local juggleCycle = elapsed * 4
                                        local rightThrow = sin(juggleCycle)
                                        local leftThrow = sin(juggleCycle + math.pi)
                                        local rUp = clamp(rightThrow, 0, 1)
                                        local rDown = clamp(-rightThrow, 0, 1)
                                        local lUp = clamp(leftThrow, 0, 1)
                                        local lDown = clamp(-leftThrow, 0, 1)
                                        -- C0 + C1 combined (no separate pcall needed)
                                        nec.C0 = nec.C0:Lerp(necc0 * angles(rad(-8 + rightThrow * 8), 0, 0), a)
                                        nec.C1 = nec.C1:Lerp(necc1 * angles(rad(-8 + rightThrow * 8), rad(rightThrow * 5), 0), a)
                                        rutj.C0 = rutj.C0:Lerp(rutjc0 * cf(sin(elapsed * 8) * 0.05, 0, 0) * angles(rad(-5 + rightThrow * 3), 0, 0), a)
                                        rutj.C1 = rutj.C1:Lerp(rutjc1 * cf(sin(elapsed * 8) * 0.05, 0, 0) * angles(rad(-5 + rightThrow * 3), 0, 0), a)
                                        -- Right arm: up = throwing (arm goes up and out), down = catching
                                        rs.C0 = rs.C0:Lerp(rsc0 * cf(0, rUp * 0.5 - rDown * 0.2, -rUp * 0.8 + rDown * 0.3) * angles(rad(-170 * rUp + 10 * rDown), rad(rUp * 15), rad(-30 + rUp * 60)), a)
                                        rs.C1 = rs.C1:Lerp(rsc1 * cf(0, rUp * 0.5 - rDown * 0.2, -rUp * 0.8 + rDown * 0.3) * angles(rad(-170 * rUp + 10 * rDown), rad(rUp * 15), rad(-30 + rUp * 60)), a)
                                        -- Left arm: opposite phase
                                        ls.C0 = ls.C0:Lerp(lsc0 * cf(0, lUp * 0.5 - lDown * 0.2, -lUp * 0.8 + lDown * 0.3) * angles(rad(-170 * lUp + 10 * lDown), rad(-lUp * 15), rad(30 - lUp * 60)), a)
                                        ls.C1 = ls.C1:Lerp(lsc1 * cf(0, lUp * 0.5 - lDown * 0.2, -lUp * 0.8 + lDown * 0.3) * angles(rad(-170 * lUp + 10 * lDown), rad(-lUp * 15), rad(30 - lUp * 60)), a)
                                        rh.C0 = rh.C0:Lerp(rhc0 * cf(0, sin(elapsed * 4) * 0.05, 0), a * 0.5)
                                        rh.C1 = rh.C1:Lerp(rhc1 * cf(0, sin(elapsed * 4) * 0.05, 0), a * 0.5)
                                        lh.C0 = lh.C0:Lerp(lhc0 * cf(0, -sin(elapsed * 4) * 0.05, 0), a * 0.5)
                                        lh.C1 = lh.C1:Lerp(lhc1 * cf(0, -sin(elapsed * 4) * 0.05, 0), a * 0.5)
                                end)

                        elseif abilityName == 'e' then
                                pcall(function()
                                        -- E: Both arms thrust forward (punch/shotgun blast)
                                        local punchPhase = clamp(elapsed / 0.25, 0, 1)
                                        local punch = sin(punchPhase * rad(90))
                                        local recoil = elapsed > 0.3 and sin((elapsed - 0.3) * 8) * 0.1 or 0
                                        nec.C0 = nec.C0:Lerp(necc0 * angles(rad(-10), rad(0), rad(0)), a)
                                        nec.C1 = nec.C1:Lerp(necc1 * angles(rad(-8), rad(0), rad(0)), a)
                                        rutj.C0 = rutj.C0:Lerp(rutjc0 * cf(0, 0, -0.25 * punch) * angles(rad(-8 * punch), rad(0), rad(0)), a)
                                        rutj.C1 = rutj.C1:Lerp(rutjc1 * cf(0.3 * punch + recoil, 0, -0.4 * punch) * angles(rad(-15 * punch), rad(0), rad(0)), a)
                                        rs.C0 = rs.C0:Lerp(rsc0 * cf(0, -0.1 * punch, -0.6 * punch) * angles(rad(-95 * punch), rad(0), rad(-5)), a)
                                        rs.C1 = rs.C1:Lerp(rsc1 * cf(0, -0.1 * punch, -0.6 * punch) * angles(rad(-95 * punch), rad(0), rad(-5)), a)
                                        ls.C0 = ls.C0:Lerp(lsc0 * cf(0, -0.1 * punch, -0.6 * punch) * angles(rad(-95 * punch), rad(0), rad(5)), a)
                                        ls.C1 = ls.C1:Lerp(lsc1 * cf(0, -0.1 * punch, -0.6 * punch) * angles(rad(-95 * punch), rad(0), rad(5)), a)
                                        rh.C0 = rh.C0:Lerp(rhc0 * cf(0, -0.3 * punch, -0.15 * punch) * angles(rad(-15), rad(0), rad(0)), a)
                                        rh.C1 = rh.C1:Lerp(rhc1 * cf(0, -0.3 * punch, -0.15 * punch) * angles(rad(-15), rad(0), rad(0)), a)
                                        lh.C0 = lh.C0:Lerp(lhc0 * cf(0, -0.3 * punch, -0.15 * punch) * angles(rad(-15), rad(0), rad(0)), a)
                                        lh.C1 = lh.C1:Lerp(lhc1 * cf(0, -0.3 * punch, -0.15 * punch) * angles(rad(-15), rad(0), rad(0)), a)
                                end)

                        elseif abilityName == 'r' then
                                pcall(function()
                                        -- R: Arms raised up, floating/hovering, slight spin
                                        local hover = sin(elapsed * 5) * 0.15
                                        local sway = sin(elapsed * 3) * 0.05
                                        nec.C0 = nec.C0:Lerp(necc0 * angles(rad(-10), 0, rad(0)), a)
                                        nec.C1 = nec.C1:Lerp(necc1 * angles(rad(-10), sway * rad(20), 0), a)
                                        rutj.C0 = rutj.C0:Lerp(rutjc0 * cf(0, hover, 0), a)
                                        rutj.C1 = rutj.C1:Lerp(rutjc1 * cf(0, hover, 0) * angles(rad(-8), sin(elapsed * 4) * rad(8), rad(0)), a)
                                        rs.C0 = rs.C0:Lerp(rsc0 * cf(0, 0.3 + sin(elapsed * 5) * 0.1, -0.2) * angles(rad(-155 + sin(elapsed * 6) * 12), rad(0), rad(-25 + sin(elapsed * 4) * 10)), a)
                                        rs.C1 = rs.C1:Lerp(rsc1 * cf(0, 0.3 + sin(elapsed * 5) * 0.1, -0.2) * angles(rad(-155 + sin(elapsed * 6) * 12), rad(0), rad(-25 + sin(elapsed * 4) * 10)), a)
                                        ls.C0 = ls.C0:Lerp(lsc0 * cf(0, 0.3 + sin(elapsed * 5) * 0.1, -0.2) * angles(rad(-155 + sin(elapsed * 6) * 12), rad(0), rad(25 - sin(elapsed * 4) * 10)), a)
                                        ls.C1 = ls.C1:Lerp(lsc1 * cf(0, 0.3 + sin(elapsed * 5) * 0.1, -0.2) * angles(rad(-155 + sin(elapsed * 6) * 12), rad(0), rad(25 - sin(elapsed * 4) * 10)), a)
                                        rh.C0 = rh.C0:Lerp(rhc0 * cf(0, hover * 0.3, 0.1) * angles(rad(-8), rad(0), rad(5)), a)
                                        rh.C1 = rh.C1:Lerp(rhc1 * cf(0, hover * 0.3, 0.1) * angles(rad(-8), rad(0), rad(5)), a)
                                        lh.C0 = lh.C0:Lerp(lhc0 * cf(0, hover * 0.3, 0.1) * angles(rad(-8), rad(0), rad(-5)), a)
                                        lh.C1 = lh.C1:Lerp(lhc1 * cf(0, hover * 0.3, 0.1) * angles(rad(-8), rad(0), rad(-5)), a)
                                end)

                        elseif abilityName == 'f' then
                                pcall(function()
                                        -- F: Casting/throwing pose - one arm forward, other back, alternating
                                        local castPulse = sin(elapsed * 6)
                                        local armSwitch = elapsed % 2 < 1
                                        nec.C0 = nec.C0:Lerp(necc0 * angles(rad(-12), rad(0), rad(0)), a)
                                        nec.C1 = nec.C1:Lerp(necc1 * angles(rad(-15), rad(0), rad(0)), a)
                                        rutj.C0 = rutj.C0:Lerp(rutjc0 * cf(0, 0, -0.15) * angles(rad(-5), rad(0), rad(0)), a)
                                        rutj.C1 = rutj.C1:Lerp(rutjc1 * cf(0, castPulse * 0.1, -0.15) * angles(rad(-10), rad(0), rad(0)), a)
                                        if armSwitch then
                                                rs.C0 = rs.C0:Lerp(rsc0 * cf(0, -0.1, -0.4) * angles(rad(-85 + castPulse * rad(10)), rad(0), rad(-15)), a)
                                                rs.C1 = rs.C1:Lerp(rsc1 * cf(0, -0.1, -0.4) * angles(rad(-85 + castPulse * rad(10)), rad(0), rad(-15)), a)
                                                ls.C0 = ls.C0:Lerp(lsc0 * cf(0, 0.15, 0.2) * angles(rad(-40 + castPulse * rad(10)), rad(0), rad(15)), a)
                                                ls.C1 = ls.C1:Lerp(lsc1 * cf(0, 0.15, 0.2) * angles(rad(-40 + castPulse * rad(10)), rad(0), rad(15)), a)
                                        else
                                                rs.C0 = rs.C0:Lerp(rsc0 * cf(0, 0.15, 0.2) * angles(rad(-40 + castPulse * rad(10)), rad(0), rad(-15)), a)
                                                rs.C1 = rs.C1:Lerp(rsc1 * cf(0, 0.15, 0.2) * angles(rad(-40 + castPulse * rad(10)), rad(0), rad(-15)), a)
                                                ls.C0 = ls.C0:Lerp(lsc0 * cf(0, -0.1, -0.4) * angles(rad(-85 + castPulse * rad(10)), rad(0), rad(15)), a)
                                                ls.C1 = ls.C1:Lerp(lsc1 * cf(0, -0.1, -0.4) * angles(rad(-85 + castPulse * rad(10)), rad(0), rad(15)), a)
                                        end
                                        rh.C0 = rh.C0:Lerp(rhc0 * cf(0, -0.1, 0), a)
                                        rh.C1 = rh.C1:Lerp(rhc1 * cf(0, -0.1, 0), a)
                                        lh.C0 = lh.C0:Lerp(lhc0 * cf(0, -0.1, 0), a)
                                        lh.C1 = lh.C1:Lerp(lhc1 * cf(0, -0.1, 0), a)
                                end)

                        elseif abilityName == 'c' then
                                pcall(function()
                                        -- C: SPIN TOWER animation
                                        local spinRate = elapsed * 300
                                        if elapsed < 1.2 then
                                                -- Spinning on ground - arm out, body spinning
                                                local spinPulse = sin(elapsed * 12)
                                                nec.C0 = nec.C0:Lerp(necc0 * angles(rad(-8), 0, 0), a)
                                                nec.C1 = nec.C1:Lerp(necc1 * angles(rad(-5), rad(spinRate % 360), 0), a)
                                                rutj.C0 = rutj.C0:Lerp(rutjc0 * cf(0, -0.2, 0) * angles(rad(-15), 0, 0), a)
                                                rutj.C1 = rutj.C1:Lerp(rutjc1 * cf(0, -0.3 + spinPulse * 0.05, 0) * angles(rad(-15), rad(spinRate % 360), 0), a)
                                                rs.C0 = rs.C0:Lerp(rsc0 * cf(0, 0.2, -0.5) * angles(rad(-100), rad(0), rad(-90)), a)
                                                rs.C1 = rs.C1:Lerp(rsc1 * cf(0, 0.2, -0.5) * angles(rad(-95), rad(0), rad(-90)), a)
                                                ls.C0 = ls.C0:Lerp(lsc0 * cf(0, -0.1, 0.3) * angles(rad(-30), rad(0), rad(50)), a)
                                                ls.C1 = ls.C1:Lerp(lsc1 * cf(0, -0.1, 0.3) * angles(rad(-30), rad(0), rad(50)), a)
                                                rh.C0 = rh.C0:Lerp(rhc0 * cf(0, -0.2, -0.1) * angles(rad(-20), rad(0), rad(5)), a)
                                                rh.C1 = rh.C1:Lerp(rhc1 * cf(0, -0.2, -0.1) * angles(rad(-20), rad(0), rad(5)), a)
                                                lh.C0 = lh.C0:Lerp(lhc0 * cf(0, -0.2, -0.1) * angles(rad(-20), rad(0), rad(-5)), a)
                                                lh.C1 = lh.C1:Lerp(lhc1 * cf(0, -0.2, -0.1) * angles(rad(-20), rad(0), rad(-5)), a)

                                        elseif elapsed < 3.8 then
                                                -- Launch pose - both arms thrust UP, looking up
                                                local upPulse = sin(elapsed * 8) * 0.05
                                                nec.C0 = nec.C0:Lerp(necc0 * angles(rad(-25), 0, 0), a)
                                                nec.C1 = nec.C1:Lerp(necc1 * angles(rad(-25), 0, 0), a)
                                                rutj.C0 = rutj.C0:Lerp(rutjc0 * cf(0, 0, -0.1) * angles(rad(-10), 0, 0), a)
                                                rutj.C1 = rutj.C1:Lerp(rutjc1 * cf(0, upPulse, -0.1) * angles(rad(-12), 0, 0), a)
                                                rs.C0 = rs.C0:Lerp(rsc0 * cf(0, 0.4, -0.2) * angles(rad(-170), rad(0), rad(-20)), a)
                                                rs.C1 = rs.C1:Lerp(rsc1 * cf(0, 0.4, -0.2) * angles(rad(-170), rad(0), rad(-20)), a)
                                                ls.C0 = ls.C0:Lerp(lsc0 * cf(0, 0.4, -0.2) * angles(rad(-170), rad(0), rad(20)), a)
                                                ls.C1 = ls.C1:Lerp(lsc1 * cf(0, 0.4, -0.2) * angles(rad(-170), rad(0), rad(20)), a)
                                                rh.C0 = rh.C0:Lerp(rhc0 * cf(0, -0.15, 0) * angles(rad(-5), 0, 0), a)
                                                rh.C1 = rh.C1:Lerp(rhc1 * cf(0, -0.15, 0) * angles(rad(-5), 0, 0), a)
                                                lh.C0 = lh.C0:Lerp(lhc0 * cf(0, -0.15, 0) * angles(rad(-5), 0, 0), a)
                                                lh.C1 = lh.C1:Lerp(lhc1 * cf(0, -0.15, 0) * angles(rad(-5), 0, 0), a)

                                        elseif elapsed < 7 then
                                                -- Watching them fall - arms down slightly, crouching
                                                local fallWatch = sin(elapsed * 4) * 0.05
                                                nec.C0 = nec.C0:Lerp(necc0 * angles(rad(-10), 0, 0), a)
                                                nec.C1 = nec.C1:Lerp(necc1 * angles(rad(-10), 0, 0), a)
                                                rutj.C0 = rutj.C0:Lerp(rutjc0 * cf(0, -0.2, 0.1) * angles(rad(8), 0, 0), a)
                                                rutj.C1 = rutj.C1:Lerp(rutjc1 * cf(0, -0.25 + fallWatch, 0.1) * angles(rad(10), 0, 0), a)
                                                rs.C0 = rs.C0:Lerp(rsc0 * cf(0, 0.1, 0.1) * angles(rad(-40), 0, rad(-10)), a)
                                                rs.C1 = rs.C1:Lerp(rsc1 * cf(0, 0.1, 0.1) * angles(rad(-40), rad(0), rad(-10)), a)
                                                ls.C0 = ls.C0:Lerp(lsc0 * cf(0, 0.1, 0.1) * angles(rad(-40), 0, rad(10)), a)
                                                ls.C1 = ls.C1:Lerp(lsc1 * cf(0, 0.1, 0.1) * angles(rad(-40), rad(0), rad(10)), a)
                                                rh.C0 = rh.C0:Lerp(rhc0 * cf(0, -0.3, 0.15) * angles(rad(10), 0, rad(5)), a)
                                                rh.C1 = rh.C1:Lerp(rhc1 * cf(0, -0.3, 0.15) * angles(rad(10), 0, rad(5)), a)
                                                lh.C0 = lh.C0:Lerp(lhc0 * cf(0, -0.3, 0.15) * angles(rad(10), 0, rad(-5)), a)
                                                lh.C1 = lh.C1:Lerp(lhc1 * cf(0, -0.3, 0.15) * angles(rad(10), 0, rad(-5)), a)

                                        else
                                                -- Settled - standing straight, slight lean back from weight
                                                local settleBreath = sin(elapsed * 3) * 0.02
                                                nec.C0 = nec.C0:Lerp(necc0 * angles(rad(-8), 0, 0), a)
                                                nec.C1 = nec.C1:Lerp(necc1 * angles(rad(-8), 0, 0), a)
                                                rutj.C0 = rutj.C0:Lerp(rutjc0 * cf(0, 0, -0.08) * angles(rad(5), 0, 0), a)
                                                rutj.C1 = rutj.C1:Lerp(rutjc1 * cf(0, settleBreath, -0.1) * angles(rad(5), 0, 0), a)
                                                rs.C0 = rs.C0:Lerp(rsc0, a)
                                                rs.C1 = rs.C1:Lerp(rsc1 * cf(0, 0, 0) * angles(rad(-10), rad(0), rad(-5)), a)
                                                ls.C0 = ls.C0:Lerp(lsc0, a)
                                                ls.C1 = ls.C1:Lerp(lsc1 * cf(0, 0, 0) * angles(rad(-10), rad(0), rad(5)), a)
                                                rh.C0 = rh.C0:Lerp(rhc0, a)
                                                rh.C1 = rh.C1:Lerp(rhc1 * cf(0, -0.1, 0), a)
                                                lh.C0 = lh.C0:Lerp(lhc0, a)
                                                lh.C1 = lh.C1:Lerp(lhc1 * cf(0, -0.1, 0), a)
                                        end
                                end)
                        end

                else
                        -- ==========================================
                        -- NORMAL ANIMATIONS (same as BallThrower)
                        -- ==========================================
                        pcall(function()
                                if anim == 'idle' and hit then
                                        nec.C1 = nec.C1:Lerp(necc1 * cf(0,0,0) * angles(sin(sine/20) * rad(2.5),sin(sine/40) * rad(1),sin(sine/40) * rad(5)),.1)
                                        rutj.C1 = rutj.C1:Lerp(rutjc1 * cf(sin(sine/40)/15,sin(sine/20)/15,sin(sine/60)/15) * angles(sin(sine/20) * rad(2.5),sin(sine/80) * rad(5),sin(sine/40) * rad(2.5)),.1)
                                        rs.C1 = rs.C1:Lerp(rsc1 * cf(0,-sin(sine/20)/15,0) * angles(-sin(sine/20) * rad(1.5),sin(sine/80) * rad(5),sin(sine/40) * rad(1.5)),.1)
                                        ls.C1 = ls.C1:Lerp(lsc1 * cf(0,sin(sine/20)/15,0) * angles(-cos(sine/20) * rad(7.5),sin(sine/80) * rad(5),sin(sine/40) * rad(2.5)),.1)
                                        rh.C1 = rh.C1:Lerp(rhc1 * cf(0,(sin(sine/20)/15) + (sin(sine/40)/25),0) * angles((sin(sine/20) * rad(3.5)) + (sin(sine/80) * rad(2.5)),rad(0),sin(sine/40) * rad(5)),.1)
                                        lh.C1 = lh.C1:Lerp(lhc1 * cf(0,(sin(sine/20)/15) + (-sin(sine/40)/25),0) * angles((sin(sine/20) * rad(3.5)) - (sin(sine/80) * rad(2.5)),rad(0),sin(sine/40) * rad(5)),.1)
                                elseif anim == 'fall' and not hit then
                                        nec.C1 = nec.C1:Lerp(necc1, .1)
                                        rutj.C1 = rutj.C1:Lerp(rutjc1, .1)
                                        rs.C1 = rs.C1:Lerp(rsc1, .1)
                                        ls.C1 = ls.C1:Lerp(lsc1, .1)
                                        rh.C1 = rh.C1:Lerp(rhc1, .1)
                                        lh.C1 = lh.C1:Lerp(lhc1, .1)
                                elseif anim == 'jump' and not hit then
                                        nec.C1 = nec.C1:Lerp(necc1, .1)
                                        rutj.C1 = rutj.C1:Lerp(rutjc1, .1)
                                        rs.C1 = rs.C1:Lerp(rsc1, .1)
                                        ls.C1 = ls.C1:Lerp(lsc1, .1)
                                        rh.C1 = rh.C1:Lerp(rhc1, .1)
                                        lh.C1 = lh.C1:Lerp(lhc1, .1)
                                elseif anim == 'walk' and hit then
                                        nec.C1 = nec.C1:Lerp(necc1 * cf(0,0,0) * angles(-sin(sine/1.75) * rad(1),sin(sine/3.5) * rad(3.5),sin(sine/3.5) * rad(2.5)) * angles(0,rotrl/1.5,0),.2)
                                        rutj.C1 = rutj.C1:Lerp(rutjc1 * cf(0,sin(sine/1.75)/7.5,0) * angles(sin(sine/1.75) * rad(5),sin(sine/3.5) * rad(5),rad(0)) * angles(-rotfb/7.5,0,-rotrl/6),.2)
                                        rs.C1 = rs.C1:Lerp(rsc1 * cf(0,sin(sine/1.75)/10,0) * angles(sin(sine/3.5) * rad(5) * rotfb,rad(0),rad(0)),.2)
                                        ls.C1 = ls.C1:Lerp(lsc1 * cf(0,-sin(sine/1.75)/10,-cos(sine/3.5)/10) * angles(sin(sine/3.5) * rad(65) * rotfb,sin(sine/1.75) * rad(7.5),sin(sine/1.75) * rad(1.5)),.2)
                                        rh.C1 = rh.C1:Lerp(rhc1 * cf(0,cos(sine/3.5)/5,-cos(sine/3.5)/3.5) * angles((sin(sine/3.5) * rad(60) + rad(7.5)) * rotfb,rad(0),sin(sine/3.5) * rad(45) * rotrl) * angles(rad(0),cos(sine/3.5) * rad(2.5),rad(0)),.2)
                                        lh.C1 = lh.C1:Lerp(lhc1 * cf(0,-cos(sine/3.5)/5,cos(sine/3.5)/3.5) * angles((-sin(sine/3.5) * rad(60) + rad(7.5)) * rotfb,rad(0),-sin(sine/3.5) * rad(45) * rotrl) * angles(rad(0),cos(sine/3.5) * rad(2.5),rad(0)),.2)
                                end
                        end)

                        -- C0 lerps (only when NOT in ability/crownize)
                        if not abilityActive and not crownizeActive then
                                if horVel > 5 and verVel >-10 and verVel <10 then
                                anim = 'walk'
                                change = .6
                                pcall(function()
                                        nec.C0 = nec.C0:Lerp(necc0, .2)
                                        rutj.C0 = rutj.C0:Lerp(rutjc0, .2)
                                        rs.C0 = rs.C0:Lerp(rsc0, .2)
                                        ls.C0 = ls.C0:Lerp(lsc0, .2)
                                        rh.C0 = rh.C0:Lerp(rhc0, .2)
                                        lh.C0 = lh.C0:Lerp(lhc0, .2)
                                end)
                        elseif verVel >10 then
                                anim = 'jump'
                                change = 1
                                pcall(function()
                                        nec.C0 = nec.C0:Lerp(necc0 * cf(0,0,0) * angles(rad(15),rad(0),rad(0)),.2)
                                        rutj.C0 = rutj.C0:Lerp(rutjc0 * cf(0,0,0) * angles(rad(-5),rad(0),rad(0)),.2)
                                        rs.C0 = rs.C0:Lerp(rsc0, .2)
                                        ls.C0 = ls.C0:Lerp(lsc0 * cf(0,0,0) * angles(rad(145),rad(0),rad(-8)),.2)
                                        rh.C0 = rh.C0:Lerp(rhc0 * cf(0,.1,-.1) * angles(rad(-3.5),rad(0),rad(2)),.2)
                                        lh.C0 = lh.C0:Lerp(lhc0 * cf(0,.3,-.25) * angles(rad(-9),rad(0),rad(-3.5)),.2)
                                end)
                        elseif verVel <-10 then
                                anim = 'fall'
                                change = 1
                                pcall(function()
                                        nec.C0 = nec.C0:Lerp(necc0 * cf(0,0,0) * angles(rad(-5),rad(0),rad(0)),.2)
                                        rutj.C0 = rutj.C0:Lerp(rutjc0 * cf(0,0,0) * angles(rad(5),rad(0),rad(0)),.2)
                                        rs.C0 = rs.C0:Lerp(rsc0, .2)
                                        ls.C0 = ls.C0:Lerp(lsc0 * cf(-.45,-.44,0) * angles(rad(6),rad(0),rad(-97.5)),.2)
                                        rh.C0 = rh.C0:Lerp(rhc0 * cf(0,.3,-.25) * angles(rad(-9),rad(0),rad(2)),.2)
                                        lh.C0 = lh.C0:Lerp(lhc0 * cf(0,.1,-.1) * angles(rad(-3.5),rad(0),rad(-3.5)),.2)
                                end)
                        elseif horVel < 5 and verVel >-10 and verVel <10 then
                                anim = 'idle'
                                change = 1
                                pcall(function()
                                        nec.C0 = nec.C0:Lerp(necc0 * cf(0,0,0) * angles(rad(-10),rad(0),rad(0)),.1)
                                        rutj.C0 = rutj.C0:Lerp(rutjc0 * cf(0,0,-.05) * angles(rad(-5),rad(0),rad(0)),.1)
                                        rs.C0 = rs.C0:Lerp(rsc0, .1)
                                        ls.C0 = ls.C0:Lerp(lsc0 * cf(0,-.15,.1) * angles(rad(-6.5),rad(15),rad(-3.5)),.1)
                                        rh.C0 = rh.C0:Lerp(rhc0 * cf(0,0,0) * angles(rad(-5),rad(-5),rad(2.5)),.1)
                                        lh.C0 = lh.C0:Lerp(lhc0 * cf(0,0,0) * angles(rad(-5),rad(5),rad(-2.5)),.1)
                                end)
                        end
                        end -- not abilityActive
                end
        end)
end)

Features & Information

yes very much pets for just a baseplate
#just a baseplate#reanimate#pets#script

Community Comments (0)

No comments yet for this script.

More Scripts for Universal Scripts