--Find handles and load sound
function init()	
	fan = FindBody("fan")
	pos = GetBodyTransform(fan).pos
	fanSound = LoadLoop("MOD/snd/map/fan.ogg")
end


--Return random number between mi and ma
function rnd(mi, ma)
	return math.random()*(ma-mi)+mi
end


--Limit linear and angular velocity of a dynamic body
function limitVelocity(body, lin, ang)
	local linVel = GetBodyVelocity(body)
	local linVelLength = VecLength(linVel)
	if linVelLength > lin then 
		linVel = VecScale(linVel, lin/linVelLength)
		SetBodyVelocity(body, linVel)
	end
	
	local angVel = GetBodyAngularVelocity(body)
	local angVelLength = VecLength(angVel)
	if angVelLength > ang then 
		angVel = VecScale(angVel, ang/angVelLength)
		SetBodyAngularVelocity(body, angVel)
	end
end


function tick(dt)
	--Spin fan, play sound and spawn particles
	--It's just a visual effect has no impact on behavior)
	SetBodyAngularVelocity(fan, Vec(0, 2, 0))
	PlayLoop(fanSound, pos, 0.3)
	ParticleRadius(0.5, 3)
        ParticleColor(0.7,0.7,0.7)
	ParticleAlpha(0.2, 0)
        ParticleCollide(1, 1, "constant", 0.05)
	SpawnParticle(VecAdd(pos, Vec(rnd(-1,1), 1, rnd(-1,1))), Vec(rnd(-1,1), 2, rnd(-1,1)), 7.0)
	
	--Collect all dynamic shapes close to the fan (but exclude the fan itself)
	local strength = 0
	local maxDist = 7.0
	QueryRejectBody(fan)
	QueryRequire("dynamic")
	local aabbMin = VecAdd(pos, Vec(-maxDist, 0, -maxDist))
	local aabbMax = VecAdd(pos, Vec(maxDist, maxDist, maxDist))
	local shapes = QueryAabbShapes(aabbMin, aabbMax)
	
	--Apply force to dynamic shapes
	for i=1, #shapes do
		local s = shapes[i]
		local hit, cp = GetShapeClosestPoint(s, pos)

		local d = VecSub(cp, pos)
		local l = VecLength(d)
		if l > 0 and l < maxDist then
			--Scale factor based on distance to fan
			local scale = 1.0-l/maxDist
			
			--Create an upwards impulse
			local imp = Vec(0, strength*scale, 0)

			--Apply impulse to the shape's body 
			local b = GetShapeBody(s)
			ApplyBodyImpulse(b, cp, imp)
			
			--This is a bit of a hack (but quite useful method) to avoid dynamic 
			--bodies to spin out of control
			limitVelocity(b, 10, 10)		
		end
	end
end


