```lua
-- #include "common.lua"
awpprojectileHandler = {
	shellNum = 1,
	shells = {},
	defaultShell = {
		active = false
	},
}

function init()
	RegisterTool("awp", "AntiTankRifle", "MOD/vox/AWP.vox")
	SetBool("game.tool.awp.enabled", true)
	SetFloat("game.tool.awp.ammo", 101)
	awp_roundtype = 4
	awp_roundtypes = {
		[4] = "EX",
	}

	damage = 0.2
	penetration = 18
	gravity = Vec(0, 0, 0)
	velocity = 5
	reloadTime = 0
	shotDelay = 1
	ammo = 1000
	mags = 4
	reloading = false
	unlimitedammo = GetBool("savegame.mod.unlimitedammo")
	zoomsense = 15000
	zoomlevel = 5
	maxzoom = 7
	minzoom = 0.5
	awp_iszoomed = false
	for i = 1, 15 do
		awpprojectileHandler.shells[i] = deepcopy(awpprojectileHandler.defaultShell)
	end

	shootTimer = 0
	reloadTimer = 0
	recoilTimer = 0
	lightTimer = 0
	gunsound = LoadSound("MOD/snd/awp_shot.ogg")
	cocksound = LoadSound("MOD/snd/awp_cock.ogg")
	reloadsound = LoadSound("MOD/snd/awp_reload.ogg")
	dryfiresound = LoadSound("MOD/snd/dryfire.ogg")
	refillsound = LoadSound("MOD/snd/refill.ogg")
	zoomsound = LoadSound("MOD/snd/awp_zoom.ogg")
end

function deepcopy(orig)
	local orig_type = type(orig)
	local copy
	if orig_type == 'table' then
		copy = {}
		for orig_key, orig_value in next, orig, nil do
			copy[deepcopy(orig_key)] = deepcopy(orig_value)
		end

		setmetatable(copy, deepcopy(getmetatable(orig)))
	else
		copy = orig
	end
	return copy
end

function clamp(value, mi, ma)
	if value < mi then value = mi end
	if value > ma then value = ma end
	return value
end

function orientation(transform, sign)
	local fwd = VecNormalize(VecSub(TransformToParentPoint(transform, Vec(0, 0, -5)), transform.pos))
	local dir = Vec(0, 1 * sign, 0)
	local orientationFactor = clamp(VecDot(dir, fwd) * 0.7 + 0.3, 0.0, 1.0)
	return orientationFactor
end

function GetAimPos()
	local ct = GetCameraTransform()
	local forwardPos = TransformToParentPoint(ct, Vec(0, 0, -150))
	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 Shoot()
	if shootTimer > 0 or ammo == 0 then return end
	local pen = penetration
	if awp_roundtype == 2 then pen = 15 end
	local ct = GetCameraTransform()
	aimpos, hit, distance = GetAimPos()
	local direction = VecSub(aimpos, toolPos)
	local direction2 = VecSub(aimpos, GetCameraTransform().pos)
	for i = 1, pen do
		awpprojectileHandler.shells[awpprojectileHandler.shellNum] = deepcopy(awpprojectileHandler.defaultShell)
		loadedShell = awpprojectileHandler.shells[awpprojectileHandler.shellNum]
		loadedShell.active = true
		loadedShell.penetration = pen
		loadedShell.roundtype = awp_roundtype
		if i == 1 then
			loadedShell.pos = toolPos
			loadedShell.predictedBulletVelocity = VecScale(direction, velocity * (150 / distance))
		elseif i == pen then
			loadedShell.pos = GetCameraTransform().pos
			loadedShell.predictedBulletVelocity = VecScale(direction2, 0.6 * (velocity * (150 / distance)))
		else
			loadedShell.pos = GetCameraTransform().pos
			loadedShell.predictedBulletVelocity = VecScale(direction2, 0.9 * (velocity * (150 / distance)))
		end

		loadedShell.index = i
		awpprojectileHandler.shellNum = (awpprojectileHandler.shellNum % #awpprojectileHandler.shells) + 1
	end

	SpawnParticle("fire", toolPos, Vec(0, 1.0 + math.random(1, 10) * 0.1, 0), 0.5, 0.15)
	SpawnParticle("darksmoke", toolPos, Vec(0, 1.0 + math.random(1, 10) * 0.1, 0), 0.25, 0.8)
	PlaySound(gunsound, GetPlayerTransform().pos, 0.9, false)
	if not unlimitedammo then ammo = ammo - 1 end
	shootTimer = shotDelay
	recoilTimer = 0.35
	lightTimer = recoilTimer / 2
end

function ProjectileOperations(projectile)
	projectile.predictedBulletVelocity = VecAdd(projectile.predictedBulletVelocity, VecScale(gravity, GetTimeStep()))
	local point2 = VecAdd(projectile.pos, VecScale(projectile.predictedBulletVelocity, GetTimeStep()))
	local dir = VecNormalize(VecSub(point2, projectile.pos))
	local hit, dist = QueryRaycast(projectile.pos, dir, VecLength(VecSub(point2, projectile.pos)))
	if hit then
		hitPos = VecAdd(projectile.pos, VecScale(VecNormalize(VecSub(point2, projectile.pos)), dist))
		projectile.active = false
		SpawnParticle("smoke", hitPos, Vec(0, 1.0 + math.random(1, 10) * 0.1, 0), damage, 1)
		if projectile.roundtype == 3 then SpawnFire(hitPos) end
		if projectile.index < projectile.penetration then
			MakeHole(hitPos, 0.2, 0.2, 0.2)
		else
			if projectile.roundtype == 4 then
				Explosion(hitPos, 0.1)
			else
				MakeHole(hitPos, damage, damage * 0.1, damage * 0.1)
			end
		end
	else
		if projectile.index == 1 then
			if projectile.roundtype > 2 then
				SpawnParticle("smoke", projectile.pos, Vec(0, 0, 0), 0.1, 0.1)
				DrawLine(projectile.pos, point2, 1, 0, 0)
			else
				DrawLine(projectile.pos, point2)
			end
		end
	end

	projectile.pos = point2
end

function Reload()
	if reloading then return end
	reloading = true
	PlaySound(reloadsound, GetPlayerTransform().pos, 0.6, false)
	reloadTimer = reloadTime
	mags = mags - 1
end

function Zoom()
	awp_iszoomed = not awp_iszoomed
	PlaySound(zoomsound, GetPlayerTransform().pos, 0.5, false)
end

function tick(dt)
	if awp_iszoomed then SetString("game.player.tool", "awp") end
	if GetString("game.player.tool") == "awp" and GetPlayerVehicle() == 0 then
		if InputPressed("esc") then awp_iszoomed = false end
		if InputPressed("lmb") and not reloading then
			if mags == 0 or ammo == 0 then
				PlaySound(dryfiresound, GetPlayerTransform().pos, 1, false)
			else
				Shoot()
			end
		end

		if InputPressed("rmb") then Zoom() end
		local b = GetToolBody()
		if b ~= 0 then
			local heightOffset = InputDown("ctrl") and 0.3 or 0.2
			local offset = Transform(Vec(0, heightOffset, 0))
			SetToolTransform(offset)
			toolTrans = GetBodyTransform(b)
			toolPos = TransformToParentPoint(toolTrans, Vec(0.35, -0.55, -3.5))
			if recoilTimer > 0 then
				local t = Transform()
				t.pos = Vec(0, heightOffset, recoilTimer)
				t.rot = QuatEuler(recoilTimer * 50, 0, 0)
				SetToolTransform(t)
				recoilTimer = recoilTimer - dt
			end

			if lightTimer > 0 then
				PointLight(toolPos, 1, 1, 1, 0.5)
				lightTimer = lightTimer - dt
			end
		end

		if not unlimitedammo then
			if ammo < 10 and mags > 1 and InputPressed("R") then Reload() end
			if GetBool("ammobox.refill") then
				SetBool("ammobox.refill", false)
				mags = mags + 1
				PlaySound(refillsound, GetPlayerTransform().pos, 1, false)
			end

			if reloading then
				reloadTimer = reloadTimer - dt
				if reloadTimer < 0 then
					ammo = 10
					reloadTimer = 0
					PlaySound(cocksound)
					reloading = false
				end
			end
		end

		for key, shell in ipairs(awpprojectileHandler.shells) do
			if shell.active then ProjectileOperations(shell) end
		end

		if awp_iszoomed then
			toolPos = GetPlayerCameraTransform().pos
			local mousewheel = InputValue("mousewheel")
			if mousewheel ~= 0 then zoomlevel = clamp(zoomlevel - mousewheel / 2, minzoom, maxzoom) end
			local pvel = GetPlayerVelocity()
			local mx, my = InputValue("mousedx"), -InputValue("mousedy")
			local ct = GetCameraTransform()
			local pt = GetPlayerTransform()
			local upAngle = orientation(Transform(pt.pos, ct.rot), 1)
			local downAngle = orientation(Transform(pt.pos, ct.rot), -1)
			if (upAngle > 0.98 and my > 0) or (downAngle > 0.98 and my < 0) then my = 0 end
			pt.pos[2] = pt.pos[2] + 1.8
			local target = Vec(mx / (zoomsense / zoomlevel), my / (zoomsense / zoomlevel), -1)
			target = TransformToParentVec(ct, target)
			ct.rot = QuatLookAt(ct, target)
			SetCameraTransform(Transform(pt.pos, ct.rot), zoomlevel * 10)
			SetPlayerTransform(Transform(GetPlayerTransform().pos, ct.rot))
			SetPlayerVelocity(pvel)
		end

		if shootTimer > 0 or ammo == 0 then shootTimer = shootTimer - dt end
	end
end

function draw()
	if GetString("game.player.tool") == "awp" and GetPlayerVehicle() == 0 then
		if awp_iszoomed then
			UiPush()
			UiTranslate(UiCenter(), UiMiddle())
			UiAlign("center middle")
			UiImage("MOD/img/awpscope.png")
			UiPop()
		end

		if not unlimitedammo then
			UiPush()
			UiTranslate(UiCenter(), UiHeight() - 60)
			UiAlign("center middle")
			UiColor(1, 1, 1)
			UiFont("bold.ttf", 32)
			UiTextOutline(0, 0, 0, 1, 0.1)
			if reloading then UiText("Reloading") end
			UiPop()
		else
			UiPush()
			UiTranslate(UiCenter(), UiHeight() - 60)
			UiAlign("center middle")
			UiColor(1, 1, 1)
			UiFont("bold.ttf", 32)
			UiTextOutline(0, 0, 0, 1, 0.1)
			UiText(awp_roundtypes[awp_roundtype])
			UiPop()
		end
	end
end
```
[{
	"resource": "/C:/Program Files (x86)/Steam/steamapps/workshop/content/1167630/2797299469/main.lua",
	"owner": "glua",
	"severity": 4,
	"message": "Inconsistent use of 'single quoted strings' and 'double quoted strings'",
	"startLineNumber": 47,
	"startColumn": 24,
	"endLineNumber": 47,
	"endColumn": 46
},{
	"resource": "/C:/Program Files (x86)/Steam/steamapps/workshop/content/1167630/2797299469/main.lua",
	"owner": "glua",
	"severity": 4,
	"message": "Inconsistent use of 'single quoted strings' and 'double quoted strings'",
	"startLineNumber": 53,
	"startColumn": 18,
	"endLineNumber": 53,
	"endColumn": 25
},{
	"resource": "/C:/Program Files (x86)/Steam/steamapps/workshop/content/1167630/2797299469/main.lua",
	"owner": "glua",
	"severity": 4,
	"message": "Variable 'direction' shadows existing binding, defined at line 82, column 8",
	"startLineNumber": 84,
	"startColumn": 8,
	"endLineNumber": 84,
	"endColumn": 17
},{
	"resource": "/C:/Program Files (x86)/Steam/steamapps/workshop/content/1167630/2797299469/main.lua",
	"owner": "glua",
	"severity": 4,
	"message": "Unused variable: ct",
	"startLineNumber": 97,
	"startColumn": 8,
	"endLineNumber": 97,
	"endColumn": 10
},{
	"resource": "/C:/Program Files (x86)/Steam/steamapps/workshop/content/1167630/2797299469/main.lua",
	"owner": "glua",
	"severity": 4,
	"message": "Variable 'hit' shadows existing binding, defined at line 98, column 10",
	"startLineNumber": 135,
	"startColumn": 8,
	"endLineNumber": 135,
	"endColumn": 11
}]

Сделай пробитие реалистичнее, потому что пуля пробивает броню любой толщины насквозь, это не реалистично