--Optimization--

local rad = math.rad
local Clamp = math.clamp
local NewCFrame = CFrame.new
local Angles = CFrame.Angles
local NewVector = Vector3.new
local CFLookAt = CFrame.lookAt
local EulerAngles = CFrame.fromEulerAnglesYXZ

function actions.aim()
	
	local aimPos = NewVector()
	local sightIndex = 50
	
	status:set("weaponAimed",true)
	myHuman.AutoRotate = false
	bodyRotate.Enabled = true
	myHuman.WalkSpeed = 10
	
	while true do
		
		local target = status:get("currentTarget")

		if myHuman.Health <=0 or not target or not target.Parent then
			break
		elseif not status:get("m4Equipped") and not status:get("reloading") then
			break
		end

		local target = status:get("currentTarget")
		local dist = core.checkDist(target,myTorso)
		local canSee = core.checkSight(target)
		
		if not canSee then
			sightIndex = sightIndex - 1
		else
			sightIndex = 50
		end
		
		if not canSee and myRoot.Velocity.Magnitude > 3 and sightIndex <= 0 then
			
			local walkPoint = myHuman.WalkToPoint
			local myPos = myRoot.Position
			local dir = (NewVector(walkPoint.X,0,walkPoint.Z) - NewVector(myPos.X,0,myPos.Z)).Unit * 20
			aimPos = myRoot.Position + NewVector(0,1.5,0) + dir
		else
			aimPos = target.Position + target.Velocity/(10 - dist/50)
		end
		
		local tilt = (myRoot.Position.Y - aimPos.Y) / (dist*0.04)
		tilt = Clamp(tilt,-45,45)
		rootJoint.C0 = rootJointOrg * EulerAngles(rad(tilt),0,0)
		lHip.C0 = lHipOrg * EulerAngles(0,0,rad(-tilt))
		rHip.C0 = rHipOrg * EulerAngles(0,0,rad(tilt))
		
		xAxisAttach.WorldCFrame = CFLookAt(m4.Position,aimPos)
		m4Hinge.Attachment0.WorldCFrame = NewCFrame(m4Hinge.Attachment0.WorldPosition) * EulerAngles(rad(0),rad(myRoot.Orientation.Y),0)
		m4Hinge.TargetAngle = xAxisAttach.Orientation.X
		headHinge.TargetAngle = xAxisAttach.Orientation.X
		
		torsoHingeAttach.Position = torsoHingAttachOrgPos + NewVector(0,tilt/90,0)

		yAxisAttach.WorldCFrame = CFLookAt(m4.Position,NewVector(
			aimPos.X,
			myRoot.Position.Y,
			aimPos.Z
			))

		if status:get("m4Equipped") then
			neck.C0 = NewCFrame(0,1,0) * Angles(-1.5 + rad(xAxisAttach.Orientation.X),rad(15),rad(180))
		else
			neck.C0 = NewCFrame(0,1,0) * Angles(-1.5 + rad(xAxisAttach.Orientation.X),0,rad(180))
		end

		runService.Heartbeat:Wait()
		runService.Heartbeat:Wait()
	end
	
	
	actions.resetHead()
	bodyRotate.Enabled = false
	myHuman.WalkSpeed = 16
	myHuman.AutoRotate = true
	
	rootJoint.C0 = rootJointOrg
	lHip.C0 = lHipOrg
	rHip.C0 = rHipOrg
	
	status:set("weaponAimed",false)
end

function actions.reload()
	status:set("weaponAimed",false)
	reloadSound:Play()
	status:set("reloading",true)
	
	actions.yieldM4()

	m4Weld.Part0 = nil
	m4.CFrame = lArm.CFrame * NewCFrame(0.5,-0.2,0) * Angles(rad(-90),rad(180),rad(0))
	m4Weld.Part0 = lArm
	
	reloadAnimation:Play()
	reloadAnimation:AdjustSpeed(3)
	
	wait(0.2)
	
	local fakeMag = magazine:Clone()
	fakeMag.CanCollide = true
	fakeMag.Parent = workspace
	debrisService:AddItem(fakeMag,4)
	magazine.Transparency = 1
	
	reloadAnimation.Stopped:Wait()

	magazine.Transparency = 0
	status:set("reloading",false)
	status:set("mag",marine.Settings.MagSize.Value)
	actions.drawM4()
end

function actions.drawM4()
	actions.yieldKnife()
	if not status:get("m4Equipped") and not status:get("reloading") then
		status:set("m4Equipped",true)
		status:set("m4Lowered",false)
		m4.Equip:Play()
		
		xAxisAttach.CFrame = myTorso.CFrame
		
		--M4 Setup
		m4Weld.Part0 = nil
		m4.CFrame = myRoot.CFrame * NewCFrame(0.3,0.85,1.75) * Angles(rad(-180),rad(180),rad(0))
		m4HingeAttach.WorldPosition = torsoHingeAttach.WorldPosition		
		m4Hinge.Enabled = true
		
		--Right Arm Setup
		rShoulder.Part1 = nil
		rArmWeld.Part1 = nil --x 1.25
		rArmWeld.Enabled = false
		rArm.CFrame = m4.CFrame * NewCFrame(-0.6,-0.5,-0.5) * Angles(rad(-80),rad(-180),rad(-15))
		rArmWeld.Part1 = rArm
		rArmWeld.Enabled = true
		
		--Left Arm Setup 
		lShoulder.Part1 = nil
		lArmWeld.Part1 = nil
		lArm.CFrame = m4.CFrame * NewCFrame(0.7,-0.3,0) * Angles(rad(-90),rad(183),rad(28)) --x84
		lArmWeld.Part1 = lArm
		
		wait(0.5)
	end
end



function actions.yieldM4()
	if status:get("m4Equipped") or status:get("m4Lowered") then

		status:set("m4Equipped",false)
		status:set("weaponAimed",false)
		status:set("m4Lowered",false)

		m4.Equip:Play()
		
		--Right Arm setup
		rArmWeld.Part1 = nil
		rShoulder.Part1 = rArm
		
		--Left Arm Setup
		lArmWeld.Part1 = nil
		lShoulder.Part1 = lArm
		
		--M4 Setup
		m4Weld.Part0 = nil
		m4Hinge.Enabled = false
		m4.CFrame = myTorso.CFrame * NewCFrame(0,0,0.7) * Angles(rad(-90),rad(-135),rad(270))
		m4Weld.Part0 = myTorso
	end
end

function actions.lowerM4()
	if not status:get("m4Lowered") and status:get("m4Equipped") and not status:get("reloading") then
		
		status:set("m4Equipped",false)
		status:set("m4Lowered",true)
		
		m4.Equip:Play()
		
		--M4 Setup
		m4Hinge.Enabled = false
		m4Weld.Part0 = nil
		m4.CFrame = myTorso.CFrame * NewCFrame(-0.2,-1,-1) * Angles(rad(75),rad(55),rad(-75)) -- z 35 x 0
		m4Weld.Part0 = myTorso
		
		--Right Arm Setup
		rShoulder.Part1 = nil 
		rArmWeld.Part1 = nil
		rArm.CFrame = myRoot.CFrame * NewCFrame(1.3,-0.2,-0.3) * Angles(rad(30),rad(14),rad(-25))
		rArmWeld.Part1 = rArm
		
		--Left Arm Setup 
		lShoulder.Part1 = nil 
		lArmWeld.Part1 = nil
		lArm.CFrame = myRoot.CFrame * NewCFrame(-1.3,-0.1,-0.3) * Angles(rad(40),rad(-3),rad(10)) --x84
		lArmWeld.Part1 = lArm
		
		wait(0.5)
	end
end

local knife = marine.Knife
function actions.drawKnife()
	if not status:get("knifeEquipped") then
		actions.yieldM4()
		knife.Equip:Play()
		status:set("knifeEquipped",true)
		knife.Weld.Part0 = nil
		knife.CFrame = rArm.CFrame * NewCFrame(0,-1,-1) * Angles(rad(90),rad(180),rad(180))
		knife.Weld.Part0 = rArm
	end
end

function actions.yieldKnife()
	if status:get("knifeEquipped") then
		status:set("knifeEquipped",false)
		knife.Weld.Part0 = nil
		knife.CFrame = myTorso.CFrame * NewCFrame(-1,-1,0.5) * Angles(rad(-65),0,rad(180))
		knife.Weld.Part0 = myTorso
	end
end

function actions.yieldWeapons()
	actions.yieldKnife()
	actions.yieldM4()
end

function actions.resetHead()
	tweenService:Create(neck,TweenInfo.new(0.5),{C0 = NewCFrame(0,1,0) * Angles(rad(-90),0,rad(180))}):Play()
end

local faces = myHead.Faces
function actions.updateFace(newStatus,recovered)
	if status:get("mood") ~= "Dead" then
		if status:get("mood") ~= "Hurt" or recovered or newStatus == "Dead" then
			local currentFace = status:get("currentFace")
			currentFace.Parent = faces 
			status:set("currentFace",faces["face"..newStatus])
			status:get("currentFace").Parent = myHead
		end
		status:set("mood",newStatus)
	end
end


return actions
