--rmwak74m custom tool example

#include "script/toolanimation.lua"
local tool_initialized = false
body = nil
barrel = nil
barrelTransform = nil
toolAnimator = ToolAnimator()

	reloadsound1 = LoadSound("MOD/snd/reloadingsounds1.ogg")
	reloadsound2 = LoadSound("MOD/snd/reloadingsounds2.ogg")
	fireselector = LoadSound("MOD/snd/fireselector.ogg")
	silencedshoot = LoadSound("MOD/snd/silenced.ogg")
	
	reticlesprite = LoadSprite("MOD/sprites/reticlesprite2.png")
	donoutreticlesprite = LoadSprite("MOD/sprites/donoutreticlesprite.png")
	okpsprite = LoadSprite("MOD/sprites/okpsprite.png")
	muzzleflash = LoadSprite("MOD/sprites/muzzleflash.png")

function SpentCasing()
	local gt = GetBodyTransform(GetToolBody())
	local casingpos = TransformToParentPoint(gt, Vec(0.18, 0.09, -0.3))
	local fwdpos = TransformToParentPoint(gt, Vec(6+math.random()*4, 0.5+math.random()*4, -0.65+math.random()*4))
	local direction = VecAdd(GetPlayerVelocity(), VecSub(fwdpos, casingpos))
	casing = Spawn("MOD/vox/casing.xml", Transform(casingpos, QuatEuler(math.random(0, 90), math.random(0, 90), math.random(0, 90))))
	SetBodyVelocity(casing[1], direction)
end

function init()
	--Register tool and enable it
	RegisterTool("rmwak74m", "AK74M", "MOD/prefab/minigun.xml")
	SetBool("game.tool.rmwak74m.enabled", true)
	
	 SetToolTransform(Transform(Vec(0, 0, 0)), 0) 
    tool_initialized = false

	angle = 0
	angVel = 0
	coolDown = 0
	smoke = 0
	magazine = 31
	aiming = false
	fireswitch = false
	reloading = false
	reloadtimer = 0
	nocasings = GetBool("savegame.mod.nocasings")
	optics = 0
	grips = 0
	muzzlec = 0
	rails = 0
	attachmentmenu = false
	recoilshake = 0.48
	zoomfov = 55
    charginghandletime = 0
	autospread = 0.01
	spread = 0.002
	low = false
	semi = 0
	
	local offset = Transform(Vec(0.5, 0, 0))
	SetToolTransform(offset, 0)
	
	shootSnd = {}
	for i=0, 7 do
		shootSnd[i] = LoadSound("MOD/snd/rifle.ogg")
	end
	
	shootHaptic = LoadHaptic("MOD/haptic/gun_fire.xml")
	local toolHaptic = LoadHaptic("MOD/haptic/background.xml")
	SetToolHaptic("rmwak74m", 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)

  -- Check if the tool is available
    local tool_transform = GetToolLocationWorldTransform()
    
    -- If the tool is initialized, set the transform with no sway
    if tool_transform then
        if not tool_initialized then
            print("Tool initialized, disabling sway.")
            tool_initialized = true
        end
        SetToolTransform(tool_transform, 0)  -- Disable sway by setting to 0
    else
        -- If the tool is not initialized, keep trying until it's available
        print("Tool transform not available yet.")
    end
	--Check if rmwak74m is selected
	if GetString("game.player.tool") == "rmwak74m" then
        local mt = GetToolLocationWorldTransform("muzzle")
		local at = GetToolLocationWorldTransform("acog")
		local ht = GetToolLocationWorldTransform("holo")
		local ot = GetToolLocationWorldTransform("okp")
		local a = GetToolBody()
		local opticssight = GetBodyShapes(a)
		local b = GetToolBody()
		local foregrips = GetBodyShapes(b)
		local c = GetToolBody()
		local muzzles = GetBodyShapes(c)
		local d = GetToolBody()
		local railings = GetBodyShapes(d)
		
			SetBool("hud.aimdot", false)
		
        if optics > 4 then optics = 0 
		end
		if grips > 2 then grips = 0 
		end
		if muzzlec > 1 then muzzlec = 0 
		end
		if rails > 3 then rails = 0 
		end

if InputReleased("usetool") then semi = 0 
		end
		
		
		if semi > 1 then semi = 1 
		end

       if InputDown("t") and not reloading then attachmentmenu = true ---Turn on the attachment selection Menu
			coolDown = 0.09
			aiming = false
		else attachmentmenu = false
			end
			
        
		
		if InputPressed("mmb") == true and fireswitch == false then fireswitch = true
			coolDown = 0.09
			PlaySound(fireselector)
			end
			
			
		if InputPressed("mmb") == true and fireswitch == true and coolDown < 0 then 
			fireswitch = false
			PlaySound(fireselector)
			end
			
			if InputPressed("o") and attachmentmenu then 
			optics = optics + 1
			end
			
			if InputPressed("p") and attachmentmenu then 
			grips = grips + 1
			end
			
			if InputPressed("k") and attachmentmenu then 
			muzzlec = muzzlec + 1
			end
			
			if InputPressed("l") and attachmentmenu then 
			rails = rails + 1
			end
			
			if GetString("game.player.tool") == "rmwak74m" then --- When Zero then its empty
			
			local optic = opticssight[10]
                if charginghandletime > 0 then ---Charginghandle
					SetShapeLocalTransform(optic, Transform(Vec(0.01, 0.125, -0.1), QuatEuler(-90, 0, 0)))
				else
					SetShapeLocalTransform(optic, Transform(Vec(0.01, 0.125, -0.2), QuatEuler(-90, 0, 0)))
                end
			
			local optic = opticssight[9]
                if reloadtimer > 1 then ---Magazine
					SetTag(optic, "invisible")
				else
				RemoveTag(optic, "invisible")
                end
			
			
			 for i = 1, #opticssight do
                local optic = opticssight[1]
                if optics > 0 then ---Mount
                    RemoveTag(optic, "invisible")
					
					SetShapeLocalTransform(optic, Transform(Vec(-0.05, 0.06, -0.1), QuatEuler(-90, 0, 0)))
				else
				SetTag(optic, "invisible")
					
                end
				local optic = opticssight[2]
                if optics == 2 then ---Acog
                    RemoveTag(optic, "invisible")
					
					SetShapeLocalTransform(optic, Transform(Vec(-0.037, 0.19, -0.07), QuatEuler(-90, 0, 0)))
				else
				SetTag(optic, "invisible")
					
                end
				
				
				local optic = opticssight[3]
                if optics == 3 then ---Holo
                    RemoveTag(optic, "invisible")
					
					SetShapeLocalTransform(optic, Transform(Vec(-0.025, 0.165, -0.15), QuatEuler(-90, 0, 0)))
				else
				SetTag(optic, "invisible")
					
                end
				local optic = opticssight[11]
				if optics == 4 then ---OKP
                    RemoveTag(optic, "invisible")
				
				else
					SetTag(optic, "invisible")
					
                end
                for i = 1, #foregrips do
                local grip = foregrips[4] ---Vertical Grip
                if grips == 1 then
                    RemoveTag(grip, "invisible")
					
				else
					SetTag(grip, "invisible")
					
                end
				
				
				local grip = foregrips[5] ---Angled Grip
                if grips == 2 then
                    RemoveTag(grip, "invisible")
					SetShapeLocalTransform(grip, Transform(Vec(-0.025, 0.013, -0.45), QuatEuler(-90, 0, 0)))
				else
					SetTag(grip, "invisible")
					
                end
				local grip = foregrips[6] ---M203
                if grips == 3 then
                    RemoveTag(grip, "invisible")
					
				else
					SetTag(grip, "invisible")
					
                end
                for i = 1, #muzzles do
                local muzzle = muzzles[7] ---Silencer
                if muzzlec == 1 then 
                    RemoveTag(muzzle, "invisible")
					
				else
					SetTag(muzzle, "invisible")
					
                end
				for i = 1, #railings do
                local rail = railings[8] ---Laser
                if rails > 0 then 
                    RemoveTag(rail, "invisible")
					
				else
					SetTag(rail, "invisible")
					
                end
				
                
            end
                
            end
            end
            end
			end
			
		
		
		
		if InputDown("rmb") and not reloading and not attachmentmenu then 
		aiming = true
		else aiming = false
			end
			
		
		
			if aiming then
			SetCameraFov(80)
			spread = 0.002
			autospread = 0.002
			
    
			if optics == 2 then
			SetCameraFov(30)
			if not InputDown("a") and not InputDown("d") and not InputDown("shift") then
			DrawSprite(reticlesprite, at, 0.04, 0.04, 1, 1, 1, 1)
			end
			end
			if optics == 3 and not InputDown("a") and not InputDown("d") and not InputDown("shift") then
			DrawSprite(donoutreticlesprite, ht, 0.01, 0.01, 1, 1, 1, 1)
			end
			if optics == 4 and not InputDown("a") and not InputDown("d") and not InputDown("shift") then
			DrawSprite(okpsprite, ot, 0.01, 0.01, 1, 1, 1, 1)
			end
			else
			spread = 0.002
			autospread = 0.01
			end
			
			if InputPressed("r") and magazine < 31 and not InputDown("usetool") and not reloading and not attachmentmenu then
				reloadtimer = 2.3
				PlaySound(reloadsound1)
				aiming = false
				reloading = true
			end
			
			if reloadtimer < 0 and reloading == true then
			magazine = 31
			PlaySound(reloadsound2)
			reloading = false
			charginghandletime = 0.1
			end
			
			if grips == 1 then
			recoilshake = 0.31
			end
			
			if grips == 2 then
			recoilshake = 0.31
			end
			
			if grips == 0 then
			recoilshake = 0.48
			end
			
			if grips == 3 then
			recoilshake = 0.48
			end
			
			
		if GetBool("game.player.canusetool") and InputDown("usetool") and not attachmentmenu and GetInt("game.tool.gun.ammo") > 0 and magazine > 0 and fireswitch and not reloading and not low and semi < 1 then
			angVel = math.min(1000, angVel + dt*9000)	
			if angVel == 1000 then
				if coolDown < 0 then
                    local _, p, _, d = GetPlayerAimInfo(mt.pos)
                    d = VecAdd(d, rndVec(spread))
					Shoot(p, d, "bullet", 0.15)
					Shoot(p, d, "bullet", 0.1)
					magazine = magazine - 1
					semi = semi + 1
					ShakeCamera(recoilshake)
					if muzzlec == 0 then
					DrawSprite(muzzleflash, mt, 0.25, 0.25, 1, 1, 1, 1, true)
					end
					SetCameraOffsetTransform(Transform(Vec(x, y, 0.05), QuatEuler(x, y, 1)), true)
					if not nocasings then
					SpentCasing()
					end

					--Light, particles and sound
					PointLight(mt.pos, 1, 0.7, 0.5, 3)
					if muzzlec == 1 then
					PlaySound(silencedshoot)
					else
					PlaySound(shootSnd[math.random(0,#shootSnd)])
					end

					smoke = math.min(1.0, smoke + 0.1)
					coolDown = 0.08
					charginghandletime = 0.07
					SetInt("game.tool.gun.ammo", GetInt("game.tool.gun.ammo")-1)
				end
			end
			PlayHaptic(shootHaptic, 1)
		else
			angVel = math.max(0, angVel - dt*1000)
		end

		--Check if firing
		if GetBool("game.player.canusetool") and InputDown("usetool") and not attachmentmenu and not reloading and GetInt("game.tool.gun.ammo") > 0 and magazine > 0 and not low and not fireswitch then
			angVel = math.min(1000, angVel + dt*9000)	
			if angVel == 1000 then
				if coolDown < 0 then
                    local _, p, _, d = GetPlayerAimInfo(mt.pos)
                    d = VecAdd(d, rndVec(autospread))
					Shoot(p, d, "bullet", 0.15)
					Shoot(p, d, "bullet", 0.1)
					magazine = magazine - 1
					ShakeCamera(recoilshake)
					if muzzlec == 0 then
					DrawSprite(muzzleflash, mt, 0.25, 0.25, 1, 1, 1, 1, true)
					end
					SetCameraOffsetTransform(Transform(Vec(x, y, 0.05), QuatEuler(x, y, 1)), true)
					if not nocasings then
					SpentCasing()
					end

					--Light, particles and sound
					PointLight(mt.pos, 1, 0.7, 0.5, 3)
					if muzzlec == 1 then
					PlaySound(silencedshoot)
					else
					PlaySound(shootSnd[math.random(0,#shootSnd)])
					end

					smoke = math.min(1.0, smoke + 0.1)
					coolDown = 0.08
					charginghandletime = 0.07
					SetInt("game.tool.gun.ammo", GetInt("game.tool.gun.ammo")-1)
				end
			end
			PlayHaptic(shootHaptic, 1)
		else
			angVel = math.max(0, angVel - dt*1000)
		end
	
		--Emit smoke from the pipe, but not when firing
		if InputDown("usetool") and magazine > 0 then
			if smoke > 0 then
				if particleTimer < 0.0 then
					particleTimer = dt + (1.0-smoke)*0.05
					local forward = TransformToParentVec(bt, Vec(0, 0, 0))
					local vel = VecScale(forward, 0.5/ dt)
					local startColour = math.random(20,55)/100
					local endColour = math.random(1,10)/100
					ParticleColor(startColour ,startColour ,startColour ,endColour ,endColour ,endColour )
					vel = VecAdd(vel, Vec(0, rnd(0, 2), 0))
					ParticleType("plain")
					ParticleEmissive(1, 0.1,"easeout")
					ParticleRadius(0.08, 0.15)
					ParticleDrag(5)
					ParticleAlpha(1, 0)
					ParticleCollide(0)
					SpawnParticle(mt.pos, VecAdd(vel, rndVec(0.1)), 2.0)
				end
			end
		end
		particleTimer = particleTimer - dt
	
		reloadtimer = reloadtimer - dt
		coolDown = coolDown - dt
		angle = angle + angVel*dt
		charginghandletime = charginghandletime - dt
		
		--------------------------------------------
		-----\/ WHERE THE LASER POINT NOW AT \/-----
		--------------------------------------------
		--\/ this line is stolen from line 393
		local attachmentPoint = Transform(VecScale(Vec(0, 1.2, -12), 0.05))
		--\/ this line defines the laserlightTransform in world vec, done by translating the local vec inside the tool body out of the tool body
		local laserlightTransfrom=TransformToParentTransform(GetBodyTransform(GetToolBody()), attachmentPoint)
		--\/ just in case its a nil, can remove this if statement if you want, its not needed
		if laserlightTransfrom~=nil and rails == 1 then
			laserForwardTransform=TransformToParentVec(laserlightTransfrom,Vec(0,0,-1))
			hit,dist=QueryRaycast(laserlightTransfrom.pos,laserForwardTransform,500)
			pointpos=VecAdd(laserlightTransfrom.pos,VecScale(laserForwardTransform,dist))
			PointLight(pointpos, 1, 0.1, 0.07,.2)
			DrawLine(pointpos,laserlightTransfrom.pos, 1, 0.1, 0.07, .15)
		end
		if laserlightTransfrom~=nil and rails == 2 then
			laserForwardTransform=TransformToParentVec(laserlightTransfrom,Vec(0,0,-1))
			hit,dist=QueryRaycast(laserlightTransfrom.pos,laserForwardTransform,500)
			pointpos=VecAdd(laserlightTransfrom.pos,VecScale(laserForwardTransform,dist))
			PointLight(pointpos, 0, 1, 0,.2)
			DrawLine(pointpos,laserlightTransfrom.pos, 0, 1, 0, .15)
		end
		if laserlightTransfrom~=nil and rails == 3 then
			laserForwardTransform=TransformToParentVec(laserlightTransfrom,Vec(0,0,-1))
			hit,dist=QueryRaycast(laserlightTransfrom.pos,laserForwardTransform,500)
			pointpos=VecAdd(laserlightTransfrom.pos,VecScale(laserForwardTransform,dist))
			PointLight(pointpos, 1, 0, 0.5,.2)
			DrawLine(pointpos,laserlightTransfrom.pos, 1, 0, 0.5, .15)
		end
		
		--Move tool a bit to the right and recoil
		local t = Transform()
		local recoil = math.max(0, coolDown)
		---toolAnimator.offsetTransform = Transform(Vec(0,0,recoil))
		toolAnimator.offsetTransform = Transform(Vec(0,0,recoil/2), QuatEuler(recoil*math.random(20, 30), recoil*math.random(-10, 10), 0))
		tickToolAnimator(toolAnimator, dt)
		
		if InputDown("shift") and not aiming and not reloading and not attachmentmenu and not InputDown("usetools") then 
		low = true
		SetPlayerWalkingSpeed(10.0)
		else
		low = false
		SetPlayerWalkingSpeed(7.0)
		end
		
		if low then
		toolAnimator.offsetTransform = (Transform(Vec(0, -0.01, 0), QuatEuler(-20, 40, 0)))
		tickToolAnimator(toolAnimator, dt)
		end
		
		if aiming then
		toolAnimator.offsetTransform = (Transform(Vec(-0.1085, 0.044, recoil/2), QuatEuler(0, 0, 0)))
		tickToolAnimator(toolAnimator, dt)
		if optics == 2 then
		toolAnimator.offsetTransform = (Transform(Vec(-0.1085, 0.003, recoil/2), QuatEuler(0, 0, 0)))
		tickToolAnimator(toolAnimator, dt)
		end
		if optics == 3 then
		toolAnimator.offsetTransform = (Transform(Vec(-0.1085, 0.017, recoil/2), QuatEuler(0, 0, 0)))
		tickToolAnimator(toolAnimator, dt)
		end
		if optics == 4 then
		toolAnimator.offsetTransform = (Transform(Vec(-0.1085, 0.01, recoil/2), QuatEuler(0, 0, 0)))
		tickToolAnimator(toolAnimator, dt)
		end
		if InputDown("shift") then
		toolAnimator.offsetTransform = (Transform(Vec(-0.108, 0.005, recoil/2), QuatEuler(0, 0, 30)))
		tickToolAnimator(toolAnimator, dt)
		SetCameraFov(80)
		end
		end
		
		if reloading then
		toolAnimator.offsetTransform = (Transform(Vec(0, -0.01, 0), QuatEuler(10, 20, -35)))
		tickToolAnimator(toolAnimator, dt)
		end
		
		if attachmentmenu then
		toolAnimator.offsetTransform = (Transform(Vec(-0.105, -0.01, -0.2), QuatEuler(35, 20, -35)))
		tickToolAnimator(toolAnimator, dt)
		end

		--Animate barrel around the attachment point
		
		
	end
	smoke = math.max(0.0, smoke - dt/0)
end

function GetAimPos() --where your crosshair is
	local ct = GetCameraTransform()
	local forwardPos = TransformToParentPoint(ct, Vec(0, 0, -100))
    local direction = VecSub(forwardPos, ct.pos)
    local distance = VecLength(direction)
	local direction = VecNormalize(direction)
	local hit, hitDistance = QueryRaycast(ct.pos, direction, distance)
	if hit then
		forwardPos = TransformToParentPoint(ct, Vec(0, 0, -hitDistance))
		distance = hitDistance
	end
	return forwardPos, hit, distance
end

function draw()

if GetString("game.player.tool") == "rmwak74m" and not fireswitch and not reloading and not attachmentmenu then
		UiPush()
			UiTranslate(UiCenter(), UiHeight()-60)
			UiAlign("center middle")
			UiColor(1, 1, 1)
			UiFont("bold.ttf", 32)
			UiTextOutline(0,0,0,1,0.1)
			UiText(magazine.." (5.56x39mm) Auto")
				
				
			end

if GetString("game.player.tool") == "rmwak74m" and fireswitch and not reloading and not attachmentmenu then
		UiPush()
			UiTranslate(UiCenter(), UiHeight()-60)
			UiAlign("center middle")
			UiColor(1, 1, 1)
			UiFont("bold.ttf", 32)
			UiTextOutline(0,0,0,1,0.1)
			UiText(magazine.." (5.56x39mm) Semi")
			
			end
			
if GetString("game.player.tool") == "rmwak74m" and reloading and not attachmentmenu then
		UiPush()
			UiTranslate(UiCenter(), UiHeight()-60)
			UiAlign("center middle")
			UiColor(1, 1, 1)
			UiFont("bold.ttf", 32)
			UiTextOutline(0,0,0,1,0.1)
			UiText(" RELOADING...")
				
				
			end
if GetString("game.player.tool") == "rmwak74m" and not reloading and attachmentmenu then
		UiPush()
			UiTranslate(UiCenter(), UiHeight()-60)
			UiAlign("center middle")
			UiColor(0.8, 0.8, 0.8)
			UiFont("bold.ttf", 31)
			UiTextOutline(0,0,0,1,0.1)
			UiText("Attachments: [O-Sights] [P-Underbarrel] [K-Muzzle] [L-Rails]")
				
			end
			
			
			end
			
			

