--Minigun custom tool example

#include "script/toolanimation.lua"

body = nil
barrel = nil
barrelTransform = nil
toolAnimator = ToolAnimator()

function init()
	--Register tool and enable it
	RegisterTool("minigun", "loc@MINIGUN", "MOD/prefab/minigun.xml")
	SetBool("game.tool.minigun.enabled", true)

	angle = 0
	angVel = 0
	coolDown = 0
	smoke = 0
	
	spinSnd = LoadLoop("MOD/snd/spin.ogg")
	shootSnd = {}
	for i=0, 7 do
		shootSnd[i] = LoadSound("tools/gun"..i..".ogg")
	end
	
	shootHaptic = LoadHaptic("MOD/haptic/gun_fire.xml")
	local toolHaptic = LoadHaptic("MOD/haptic/background.xml")
	SetToolHaptic("minigun", toolHaptic);

	
	oldPipePos = Vec()
	particleTimer = 0

	toolAnimator.useAimRotation = true
end

--Return a random vector of desired length
function rndVec(length)
	local v = VecNormalize(Vec(math.random(-100,100), math.random(-100,100), math.random(-100,100)))
	return VecScale(v, length)	
end

function rnd(mi, ma)
	return math.random(1000)/1000*(ma-mi) + mi
end

function tick(dt)
	--The minigun shares ammo with gun
	SetInt("game.tool.minigun.ammo", GetInt("game.tool.gun.ammo"))

	--Check if minigun is selected
	if GetString("game.player.tool") == "minigun" then
        local mt = GetToolLocationWorldTransform("muzzle")

		--Check if firing
		if GetBool("game.player.canusetool") and InputDown("usetool") and GetInt("game.tool.gun.ammo") > 0 then
			angVel = math.min(1000, angVel + dt*2000)	
			if angVel == 1000 then
				if coolDown < 0 then
                    local _, p, _, d = GetPlayerAimInfo(mt.pos)
                    d = VecAdd(d, rndVec(0.02))
					Shoot(p, d)

					--Light, particles and sound
					PointLight(mt.pos, 1, 0.7, 0.5, 3)
					PlaySound(shootSnd[math.random(0,#shootSnd)])

					smoke = math.min(1.0, smoke + 0.1)
					coolDown = 0.07
					SetInt("game.tool.gun.ammo", GetInt("game.tool.gun.ammo")-1)
				end
			end
			PlayHaptic(shootHaptic, 1)
			PlayLoop(spinSnd)
		else
			angVel = math.max(0, angVel - dt*1000)
		end
	
		--Emit smoke from the pipe, but not when firing
		if mt ~=nil then
			if not InputDown("usetool") then
				if smoke > 0 then
					if particleTimer < 0.0 then
						particleTimer = dt + (1.0-smoke)*0.05
						local vel = VecScale(VecSub(mt.pos, oldPipePos), 0.5/ dt)
						vel = VecAdd(vel, Vec(0, rnd(0, 2), 0))
						ParticleType("smoke")
						ParticleRadius(0.08, 0.15)
						ParticleAlpha(smoke*0.4, 0)
						ParticleDrag(1.0)
						SpawnParticle(mt.pos, VecAdd(vel, rndVec(0.1)), 2.0)
					end
				end
			end
			oldPipePos = mt.pos
		end
		particleTimer = particleTimer - dt
		
	
		coolDown = coolDown - dt
		angle = angle + angVel*dt
		
		--Move tool a bit to the right and recoil
		local t = Transform()
		local recoil = math.max(0, coolDown)
		toolAnimator.offsetTransform = Transform(Vec(0,recoil,0))
		tickToolAnimator(toolAnimator, dt)

		--Animate barrel around the attachment point
		local b = GetToolBody()
		local voxSize = 0.04
	    local attach = Transform(Vec(0.5*voxSize, 0.5*voxSize, 0))
		if body ~= b then
			body = b
			-- Barrel is the second shape in vox file. Remember original position in attachment frame
			local shapes = GetBodyShapes(b)
			barrel = shapes[1]
			barrelTransform = TransformToLocalTransform(attach, GetShapeLocalTransform(barrel))	
		end
		attach.rot = QuatEuler(0, 0, angle)
		t = TransformToParentTransform(attach, barrelTransform)
		SetShapeLocalTransform(barrel, t)
	end
	smoke = math.max(0.0, smoke - dt/3)
end


