--Minigun custom tool example body = nil barrel = nil barrelTransform = nil function init() --Register tool and enable it RegisterTool("minigun", "loc@MINIGUN", "MOD/vox/minigun.vox") 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 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 ct = GetCameraTransform() --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 = TransformToParentPoint(ct, Vec(0.25, -0.25, -1.1)) local d = VecAdd(TransformToParentVec(ct, Vec(0,0,-1)), rndVec(0.02)) Shoot(p, d) --Light, particles and sound local lp = TransformToParentPoint(ct, Vec(0.25, -0.25, -2.0)) PointLight(lp, 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 local p = TransformToParentPoint(ct, Vec(0.25, -0.4, -1.6)) if not InputDown("lmb") then if smoke > 0 then if particleTimer < 0.0 then particleTimer = dt + (1.0-smoke)*0.05 local vel = VecScale(VecSub(p, 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(p, VecAdd(vel, rndVec(0.1)), 2.0) end end end particleTimer = particleTimer - dt oldPipePos = p 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) t.pos = Vec(0.3, 0, recoil) SetToolTransform(t) --Animate barrel around the attachment point local b = GetToolBody() local voxSize = 0.05 local attach = Transform(Vec(0.5*voxSize, -8.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[2] 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