--Laser Gun example mod

body = nil
t0 = nil
t1 = nil

function init()
	--Register tool and enable it
	RegisterTool("lasergun", "loc@LASER_GUN", "MOD/vox/lasergun.vox")
	SetBool("game.tool.lasergun.enabled", true)

	--Laser gun has 60 seconds of ammo. 
	--If played in sandbox mode, the sandbox script will make it infinite automatically
	SetFloat("game.tool.lasergun.ammo", 60)
	
	ready = 0
	fireTime = 0
	
	openSnd = LoadSound("MOD/snd/open.ogg")
	closeSnd = LoadSound("MOD/snd/close.ogg")
	laserSnd = LoadLoop("MOD/snd/laser.ogg")
	hitSnd = LoadLoop("MOD/snd/hit.ogg")
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 tick(dt)
	--Check if laser gun is selected
	if GetString("game.player.tool") == "lasergun" then
	
		--Check if tool is firing
		if GetBool("game.player.canusetool") and InputDown("usetool") and GetFloat("game.tool.lasergun.ammo") > 0 then
			if ready == 0 then 
				PlaySound(openSnd) 
			end
			ready = math.min(1.0, ready + dt*4)
			if ready == 1.0 then
				PlayLoop(laserSnd)

				local toolBodyTransform = GetBodyTransform(GetToolBody())
				local toolFwd = TransformToParentVec(toolBodyTransform, Vec(0,0,-1))
				local muzzlePosition = VecAdd(toolBodyTransform.pos, VecScale(toolFwd, 0.9))

				local maxDist = 20
				local hit, s, e = GetPlayerAimInfo(muzzlePosition, maxDist)

				--Draw laser line in ten segments with random offset
				local last = s
				for i=1, 10 do
					local tt = i/10
					local p = VecLerp(s, e, tt)
					p = VecAdd(p, rndVec(0.2*tt))
					DrawLine(last, p, 1, 0.5, 0.7)
					last = p
				end

				--Make damage and spawn particles
				if hit then
					PlayLoop(hitSnd, e)
					SpawnFire(e)
					MakeHole(e, 0.4, 0.2, 0.0, true)
					--SpawnParticle("fire", e, rndVec(0.5), 0.5, 0.5)
					local size = 0.5
					ParticleReset()
					ParticleType("fire")
					ParticleDrag(0.001)
					ParticleGravity(0, 1)
					ParticleColor(1, 0.9, 0.8, 1, 0.5, 0.4)
					ParticleAlpha(0.5, 0.0)
					ParticleRadius(size * 0.1, size)
					ParticleEmissive(10, 0)
					SpawnParticle(e, rndVec(0.5), 0.5)

					--SpawnParticle("smoke", e, rndVec(0.5), 1.0, 1.0)
					size = 1.0
					ParticleReset()
					ParticleType("smoke")
					ParticleDrag(0)
					ParticleGravity(-2, -4)
					ParticleColor(1, 1, 1)
					ParticleAlpha(0.5, 0.0, "linear", 0.05)
					ParticleRadius(0.5 * size, size)
					ParticleCollide(0, 1)
					SpawnParticle(e, rndVec(0.5), 1.0)
				end
				
				fireTime = fireTime + dt
				SetFloat("game.tool.lasergun.ammo", math.max(0, GetFloat("game.tool.lasergun.ammo")-dt))
				
				--Provide ammo display with one decimal
				SetString("game.tool.lasergun.ammo.display", tostring(math.floor(GetFloat("game.tool.lasergun.ammo")*10)/10))
			end
		else
			fireTime = 0
			if ready == 1 then
				PlaySound(closeSnd)
			end
			ready = math.max(0.0, ready - dt*4)
		end
	
		local b = GetToolBody()
		if b ~= 0 then
			local shapes = GetBodyShapes(b)

			--Control emissiveness
			for i=1, #shapes do
				SetShapeEmissiveScale(shapes[i], ready)
			end
	
			--Add some light
			if ready > 0 then
				local p = TransformToParentPoint(GetBodyTransform(body), Vec(0, 0, -2))
				PointLight(p, 1, 0.5, 0.7, ready * math.random(10, 15) / 10)
			end
			
			--Move tool
			local toolTransform = Transform(Vec(0.0, -0.4, -0.2))
			if GetBool("game.thirdperson") then
				toolTransform = Transform(Vec(0.2, -0.5, -0.2))
				SetToolHandPoseLocalTransform(Transform(Vec(0.2,0.0,0.0), QuatAxisAngle(Vec(0,1,0), 90.0)), Transform(Vec(-0.1, 0.0, -0.4)))
			end

			local offset = VecScale(rndVec(0.01), ready*math.min(fireTime/5, 1.0))
			toolTransform.pos = VecAdd(toolTransform.pos, offset)
			SetToolTransform(toolTransform)
			
			--Animate 
			local t	= 1-ready
			t = t*t
			offset = t*0.15
			
			if b ~= body then
				body = b
				--Get default transforms
				t0 = GetShapeLocalTransform(shapes[2])
				t1 = GetShapeLocalTransform(shapes[1])
			end

			t = TransformCopy(t0)
			t.pos = VecAdd(t.pos, Vec(offset))
			SetShapeLocalTransform(shapes[2], t)

			t = TransformCopy(t1)
			t.pos = VecAdd(t.pos, Vec(-offset))
			SetShapeLocalTransform(shapes[1], t)
		end
	end
end

