So I made a gun module, or more accurately a weapons module which works, but I think that the code could be better.
Here’s the code:
local Gun = {}
Gun.__index = Gun
local FastCast = require(script.Parent:WaitForChild("FastCastRedux"))
function Gun.new()
local newGun = {}
setmetatable(newGun, Gun)
return newGun
end
function Gun:Equip(char, location)
local Torso = char:FindFirstChild("Torso")
Torso.ToolGrip.Part0 = Torso
Torso.ToolGrip.Part1 = location
return nil
end
function Gun:Unequip(char)
local Torso = char:FindFirstChild("Torso")
Torso.ToolGrip.Part1 = nil
return nil
end
function Gun:Shoot(fireOrigin ,fireDirection, teamKill, gunBullet, spreadAngle, bulletSpeed, bulletGravity, maxDist, fireDelay, container, moreBullets, canDamage)
self.fireOrigin = fireOrigin
self.fireDirection = fireDirection
self.gunBullet = gunBullet or nil
self.spreadAngle = spreadAngle
self.bulletSpeed = bulletSpeed
self.bulletGravity = bulletGravity
self.container = container or nil
self.moreBullets = moreBullets or nil
local RNG = Random.new()
local TPI = math.pi * 2
local minSpreadAngle = 0
local tool = script.Parent.Parent
local shot = false
local Caster = FastCast.new()
local function fireGun(direction)
local directionCF = CFrame.new(Vector3.new(), direction)
local direction = (directionCF * CFrame.fromOrientation(0, 0, RNG:NextNumber(0, TPI)) * CFrame.fromOrientation(math.rad(RNG:NextNumber(minSpreadAngle, spreadAngle)), 0, 0)).LookVector
local HRP = tool.Parent:FindFirstChild("HumanoidRootPart")
local movementSpeed = HRP.Velocity
local modifiedBulletSpeed = (direction * bulletSpeed) + movementSpeed
if container then
if moreBullets then
local randomX = math.random(-1000, 1000)
local randomY = math.random(-1000, 1000)
for i = 0, 1, 1 do
wait()
local bullet = gunBullet:Clone()
bullet.CFrame = CFrame.new(fireOrigin, fireOrigin + direction + Vector3.new(randomX, randomY, 0))
bullet.Parent = container
local ignoreList = {container, HRP.Parent}
Caster:FireWithBlacklist(fireOrigin, direction * maxDist, modifiedBulletSpeed, ignoreList ,bullet, false, bulletGravity )
end
else
local bullet = gunBullet:Clone()
bullet.CFrame = CFrame.new(fireOrigin, fireOrigin + direction)
bullet.Parent = container
local ignoreList = {container, HRP.Parent}
Caster:FireWithBlacklist(fireOrigin, direction * maxDist, modifiedBulletSpeed, ignoreList ,bullet, false, bulletGravity )
end
else
local bullet = gunBullet:Clone()
bullet.CFrame = CFrame.new(fireOrigin, fireOrigin + direction)
bullet.Parent = workspace
Caster:Fire(fireOrigin, direction * maxDist, modifiedBulletSpeed, bullet, script.Parent.Parent, false, bulletGravity)
end
end
local function onRayHit(hitPart, hitPoint, normal, material, segmentVelocity, cosmeticBulletObject)
cosmeticBulletObject:Destroy()
local char = tool.Parent:FindFirstChild("HumanoidRootPart").Parent
-- Lol this part is bugged as heck bro
if hitPart and hitPart.Parent and hitPart.Parent ~= char then
local humanoid = hitPart.Parent:FindFirstChild("Humanoid")
local plr = game:GetService("Players"):GetPlayerFromCharacter(hitPart.Parent)
if humanoid then
if teamKill and canDamage then
humanoid:TakeDamage(25)
elseif not teamKill and canDamage and not plr then
humanoid:TakeDamage(25)
else
end
end
end
end
local function onRayUpdated(castOrigin, segmentOrigin, segmentDirection, length, segmentVelocity, cosmeticBulletObject)
local bulletLength = cosmeticBulletObject.Size.Z / 2
local baseCFrame = CFrame.new(segmentOrigin, segmentOrigin + segmentDirection)
cosmeticBulletObject.CFrame = baseCFrame * CFrame.new(0, 0, -(length - bulletLength))
end
Caster.LengthChanged:Connect(onRayUpdated)
Caster.RayHit:Connect(onRayHit)
if not shot then
shot = true
fireGun(fireDirection)
wait(fireDelay)
shot = false
end
return nil
end
return Gun