
KeylessUniversal

-- // 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)No comments yet for this script.



