local A={wave=false;point=false,dance=true,dance2=true,dance3=true,laugh=false;cheer=false}math.randomseed(tick())function findExistingAnimationInSet(A,S)if A==nil or S==nil then return 0 end for x=1,A.count,1 do if A[x].anim.AnimationId==S.AnimationId then return x end end return 0 end local function S()for A,S in pairs(strafingLocomotionMap)do if S.track then S.track:Stop()S.track:Destroy()S.track=nil end end for A,S in pairs(fallbackLocomotionMap)do if S.track then S.track:Stop()S.track:Destroy()S.track=nil end end cachedRunningSpeed=0 end local x,v,M,Q local function B(A)v=0 x=0 Q=0 M=0 end local function c(A)if A then if A.x>x then x=A.x end if A.y>M then M=A.y end if A.x<v then v=A.x end if A.y<Q then Q=A.y end end end local function O(A)if x==0 or v==0 or M==0 or Q==0 then if locomotionMap==strafingLocomotionMap then warn("\083\116\114\097\102\101 \098\108\101\110\100\105\110\103 \100\105\115\097\098\108\101\100\046  \078\111\116 \097\108\108 \113\117\097\100\114\097\110\116\115 \111\102 \109\111\116\105\111\110 \114\101\112\114\101\115\101\110\116\101\100\046")end locomotionMap=fallbackLocomotionMap elseif not strafingLocomotionMap.run or not strafingLocomotionMap.walk then if locomotionMap==strafingLocomotionMap then warn("\083\116\114\097\102\101 \098\108\101\110\100\105\110\103 \100\105\115\097\098\108\101\100\046  \082\117\110 \097\110\100 \119\097\108\107 \109\117\115\116 \098\101 \115\116\114\097\102\105\110\103-\102\114\105\101\110\100\108\121\046")end locomotionMap=fallbackLocomotionMap else if locomotionMap~=strafingLocomotionMap then locomotionMap=strafingLocomotionMap warn("\083\116\114\097\102\105\110\103 \114\101\101\110\097\098\108\101\100")end end end local function I()B()for A,S in pairs(strafingLocomotionMap)do c(S.lv)end O()for A,S in pairs(locomotionMap)do S.track=Humanoid:LoadAnimation(animTable[A][1].anim)S.track.Priority=Enum.AnimationPriority.Core end end local function n(A,x)local v=false if currentAnim=="\119\097\108\107"and locomotionMap[A]then S()v=true end if x then strafingLocomotionMap[A]={lv=x;speed=x.Magnitude}else strafingLocomotionMap[A]=nil end if A=="\114\117\110"or A=="\119\097\108\107"then if x then fallbackLocomotionMap[A]=strafingLocomotionMap[A]else local S=A=="\114\117\110"and RUN_SPEED or WALK_SPEED fallbackLocomotionMap[A]={lv=Vector2.new(.0,S);speed=S}strafingLocomotionMap[A]=nil end end if v then I()lastBlendTime=0 end end function configureAnimationSet(A,S)if animTable[A]~=nil then for A,S in pairs(animTable[A].connections)do S:disconnect()end end animTable[A]={}animTable[A].count=0 animTable[A].totalWeight=0 animTable[A].connections={}local x=script:FindFirstChild(A)if x~=nil then table.insert(animTable[A].connections,x.ChildAdded:connect(function(x)configureAnimationSet(A,S)end))table.insert(animTable[A].connections,x.ChildRemoved:connect(function(x)configureAnimationSet(A,S)end))local v=0 for x,M in pairs(x:GetChildren())do if M:IsA("\065\110\105\109\097\116\105\111\110")then local x=1 local Q=M:FindFirstChild("\087\101\105\103\104\116")if Q~=nil then x=Q.Value end animTable[A].count=animTable[A].count+1 v=animTable[A].count animTable[A][v]={}animTable[A][v].anim=M animTable[A][v].weight=x animTable[A].totalWeight=animTable[A].totalWeight+animTable[A][v].weight table.insert(animTable[A].connections,M.Changed:connect(function(x)configureAnimationSet(A,S)end))table.insert(animTable[A].connections,M.ChildAdded:connect(function(x)configureAnimationSet(A,S)end))table.insert(animTable[A].connections,M.ChildRemoved:connect(function(x)configureAnimationSet(A,S)end))local B=M:GetAttribute("\076\105\110\101\097\114\086\101\108\111\099\105\116\121")n(A,B)end end end if animTable[A].count<=0 then for S,x in pairs(S)do animTable[A][S]={}animTable[A][S].anim=Instance.new("\065\110\105\109\097\116\105\111\110")animTable[A][S].anim.Name=A animTable[A][S].anim.AnimationId=x.id animTable[A][S].weight=x.weight animTable[A].count=animTable[A].count+1 animTable[A].totalWeight=animTable[A].totalWeight+x.weight end end for A,S in pairs(animTable)do for A=1,S.count,1 do if PreloadedAnims[S[A].anim.AnimationId]==nil then Humanoid:LoadAnimation(S[A].anim)PreloadedAnims[S[A].anim.AnimationId]=true end end end end

local emoteNames = { wave = false, point = false, dance = true, dance2 = true, dance3 = true, laugh = false, cheer = false}

math.randomseed(tick())

function findExistingAnimationInSet(set, anim)
	if set == nil or anim == nil then
		return 0
	end

	for idx = 1, set.count, 1 do
		if set[idx].anim.AnimationId == anim.AnimationId then
			return idx
		end
	end

	return 0
end

local function destroyWalkAnimations()
	for _,v in pairs(strafingLocomotionMap) do
		if v.track then
			v.track:Stop()
			v.track:Destroy()
			v.track = nil
		end
	end
	for _,v in pairs(fallbackLocomotionMap) do
		if v.track then
			v.track:Stop()
			v.track:Destroy()
			v.track = nil
		end
	end
	cachedRunningSpeed = 0
end


local maxVeloX, minVeloX, maxVeloY, minVeloY

local function resetVelocityBounds(velo)
	minVeloX = 0
	maxVeloX = 0
	minVeloY = 0
	maxVeloY = 0
end

local function updateVelocityBounds(velo)
	if velo then
		if velo.x > maxVeloX then maxVeloX = velo.x end
		if velo.y > maxVeloY then maxVeloY = velo.y end
		if velo.x < minVeloX then minVeloX = velo.x end
		if velo.y < minVeloY then minVeloY = velo.y end
	end
end

local function checkStrafingEnabled(velo)
	if maxVeloX == 0 or minVeloX == 0 or maxVeloY == 0 or minVeloY == 0  then
		if locomotionMap == strafingLocomotionMap then
			warn("Strafe blending disabled.  Not all quadrants of motion represented.")
		end
		locomotionMap = fallbackLocomotionMap
	elseif not strafingLocomotionMap["run"] or not strafingLocomotionMap["walk"] then
		if locomotionMap == strafingLocomotionMap then
			warn("Strafe blending disabled.  Run and walk must be strafing-friendly.")
		end
		locomotionMap = fallbackLocomotionMap
	else
		if locomotionMap ~= strafingLocomotionMap then
			locomotionMap = strafingLocomotionMap
			warn("Strafing reenabled")
		end
	end
end

local function setupWalkAnimations()
	resetVelocityBounds()
	-- check to see if we need to blend a walk/run animation
	for n,v in pairs(strafingLocomotionMap) do
		updateVelocityBounds(v.lv)
	end
	checkStrafingEnabled()
	for n,v in pairs(locomotionMap) do
		v.track = Humanoid:LoadAnimation(animTable[n][1].anim)
		v.track.Priority = Enum.AnimationPriority.Core
	end
end

local function replaceLocomotionTrack(name, lv)
	local restartWalks = false
	if currentAnim == "walk" and locomotionMap[name] then
		-- Need to tear down and startup locomotion
		destroyWalkAnimations()
		restartWalks = true
	end

	if lv then
		strafingLocomotionMap[name] = {lv=lv, speed = lv.Magnitude}
	else
		strafingLocomotionMap[name] = nil
	end
	if  name == "run"  or name == "walk" then
		if lv then
			fallbackLocomotionMap[name] = strafingLocomotionMap[name]
		else
			local speed = name == "run" and RUN_SPEED or WALK_SPEED
			fallbackLocomotionMap[name] = {lv=Vector2.new(0.0, speed), speed = speed}
			strafingLocomotionMap[name] = nil
		end
	end
	if restartWalks then
		setupWalkAnimations()
		lastBlendTime = 0
	end
end

function configureAnimationSet(name, fileList)
	if (animTable[name] ~= nil) then
		for _, connection in pairs(animTable[name].connections) do
			connection:disconnect()
		end
	end
	animTable[name] = {}
	animTable[name].count = 0
	animTable[name].totalWeight = 0
	animTable[name].connections = {}

	-- check for config values
	local config = script:FindFirstChild(name)
	if (config ~= nil) then
		table.insert(animTable[name].connections, config.ChildAdded:connect(function(child) configureAnimationSet(name, fileList) end))
		table.insert(animTable[name].connections, config.ChildRemoved:connect(function(child) configureAnimationSet(name, fileList) end))

		local idx = 0

		for _, childPart in pairs(config:GetChildren()) do
			if (childPart:IsA("Animation")) then
				local newWeight = 1
				local weightObject = childPart:FindFirstChild("Weight")
				if (weightObject ~= nil) then
					newWeight = weightObject.Value
				end
				animTable[name].count = animTable[name].count + 1
				idx = animTable[name].count
				animTable[name][idx] = {}
				animTable[name][idx].anim = childPart
				animTable[name][idx].weight = newWeight
				animTable[name].totalWeight = animTable[name].totalWeight + animTable[name][idx].weight
				table.insert(animTable[name].connections, childPart.Changed:connect(function(property) configureAnimationSet(name, fileList) end))
				table.insert(animTable[name].connections, childPart.ChildAdded:connect(function(property) configureAnimationSet(name, fileList) end))
				table.insert(animTable[name].connections, childPart.ChildRemoved:connect(function(property) configureAnimationSet(name, fileList) end))
				local lv = childPart:GetAttribute("LinearVelocity")
				replaceLocomotionTrack(name, lv)

			end
		end
	end

	-- fallback to defaults
	if (animTable[name].count <= 0) then
		for idx, anim in pairs(fileList) do
			animTable[name][idx] = {}
			animTable[name][idx].anim = Instance.new("Animation")
			animTable[name][idx].anim.Name = name
			animTable[name][idx].anim.AnimationId = anim.id
			animTable[name][idx].weight = anim.weight
			animTable[name].count = animTable[name].count + 1
			animTable[name].totalWeight = animTable[name].totalWeight + anim.weight
		end
	end

	-- preload anims
	for i, animType in pairs(animTable) do
		for idx = 1, animType.count, 1 do
			if PreloadedAnims[animType[idx].anim.AnimationId] == nil then
				Humanoid:LoadAnimation(animType[idx].anim)
				PreloadedAnims[animType[idx].anim.AnimationId] = true
			end
		end
	end
end
