What should I do for my weapon system?

Alright so,

I’ve overwritten my recent bomb system, where the bombs were all managed in separate scripts and duplicated. Now I just use one module that utilizes OOP Inheritance so that each bomb has its own explode function.

But here’s the thing, I want to achieve two things.

  1. Make it so that certain bombs also have their functions (e.g. a cluster bomb that spawns five mini bombs after it explodes with them also exploding.)
  2. Be able to utilize and change different functions depending on the bomb. (e.g, the dynamite has one sound that plays once instead of a regular tick sound that is played three times.)

In the first thing I want to achieve, the issue at hand is that the bomb module only accounts for one explosion and currently has no feature to make multiple, so I’m not exactly sure how I would implement it so that five mini-bombs spawn right after it.

In the second thing I want to achieve, the issue at hand is that since the structure for the explosion function is linear, the process in which the ticking sound is played only allows it to play for three times, and doesn’t account for if a bomb can play one sound once opposed from three times.

This is the structure of the bomb module, some comments show how it works.

local bomb = {}
bomb.__index = bomb -- OOP Inheritance 

bomb.damage = 25 -- Everything below this are the basic data for a bomb.
bomb.cooldown = 5
bomb.range = {
	["L"] = 12;
	["W"] = 12;
	["H"] = 12;

bomb.tickTime = 1
bomb.tickSound = "rbxasset://sounds\\clickfast.wav"
bomb.tickSoundVolume = 1

bomb.explosionSoundVolume = 1.5
bomb.explosionSoundId = "rbxasset://sounds\\Rocket shot.wav"
bomb.explosionParticles = nil

local debris = game:GetService("Debris")

-- Functions for the bomb system, including the particles and the debugMode's explosion visualizer.
function explosionParticles(bomb, bombData)
	local explosionClone = bombData.explosionParticles:Clone()
	explosionClone.Parent = bomb
	explosionClone.Enabled = true
	return explosionClone

function visualizerCalculator(region3)
	local region3Visual = Instance.new("Part") -- The visualized part for the region3.
	region3Visual.Name = "blastRadiousVisual"
	region3Visual.CanCollide = false
	region3Visual.Size = region3.Size
	region3Visual.CFrame = region3.CFrame
	region3Visual.Anchored = true
	region3Visual.Transparency = .5
	region3Visual.Parent = workspace.Terrain
	region3Visual.BrickColor = BrickColor.new("Persimmon")

bomb.Explode = function(user, bombData, bombClone, plant, debugMode)
	local sound = Instance.new("Sound")
	sound.SoundId = bombData.tickSound
	sound.Parent = bombClone
	for i = 1, 3 do task.wait(bombData.tickTime) -- The timer on the bomb for explosion is ticking
		if i == 3 then task.wait(1) end -- prevents the bomb from exploding instantly on the third i = (tickTime * 3) + 1
	if plant == false then bombClone.Anchored = true end -- We anchor the bomb so that it doesn't roll awaybomb.Anchored = true -- We anchor the bomb so that it doesn't roll awaw
	local explosionClone = explosionParticles(bombClone, bombData)
	local explosionSoundClone = Instance.new("Sound")
	explosionSoundClone.SoundId = bombData.explosionSoundId
	explosionSoundClone.Parent = bombClone
	bombClone.Transparency = 1

	local region3 = Region3.new(
		bombClone.Position - Vector3.new(bombData.range.L, bombData.range.H, bombData.range.W),
		bombClone.Position + Vector3.new(bombData.range.L, bombData.range.H, bombData.range.W) -- Makes a square that is 5x5 long and wide, and 10 Tix high (hence the 1 to 10)
	) -- Creates a region3 that destroys any parts in the explosions radius.
	local explosionVisualizer = visualizerCalculator(region3)

	local explosion = Instance.new("Explosion") -- The explosion instance
	explosion.Parent = bombClone
	explosion.Position = bombClone.Position
	explosion.BlastRadius = region3.Size.Z

	explosion.DestroyJointRadiusPercent = 0
	explosion.BlastPressure = 900000

	local overlapParams = OverlapParams.new()
	overlapParams.FilterDescendantsInstances = {explosionVisualizer}

	local parts = workspace:GetPartBoundsInBox(region3.CFrame, region3.Size, overlapParams)
	for i, v in pairs(parts) do
		if v.Name == "Brick" then
			v.Anchored = false
			v.CanTouch = false

			v.BrickColor = user.TeamColor

			for i, constraint in pairs(v:GetChildren()) do
				if constraint:IsA("Constraint") then constraint:Destroy() end

			debris:AddItem(v, 2)
			-- task.delay(2, game.Destroy, v) MESSIAH WILL MAKE A MODULE FOR PART DELETION
		elseif v.Name == "GameBrick" then v.Name = "TaggedGameBrick" -- TaggedGameBricks are GameBricks in the game that have been effected by the bomb, 
			-- while regular Bricks are just bricks you can destroy by default.
			v.Anchored = false
			v.CanTouch = false

			user.leaderstats.Bricks.Value += 1 -- The total bricks the player has broken throughout the round.
			user["T. Bricks"].Value += 1 -- The total bricks that the player has destroyed throughout there playtime
			user.leaderstats.Tix.Value += .1 -- Increases the players currency (Tix) by 0.1.
			v.BrickColor = user.TeamColor -- Changes the taggedBricks color to the local players team color to show that they have broken the part.
			debris:AddItem(v, 2)
			-- task.delay(2, game.Destroy, v) MESISAH WILL AM+MAKE A MODULE FOR PART DLEETION
	explosionClone.Enabled = false -- Disables the explosion particles.

	debris:AddItem(bombClone, 3)
	debris:AddItem(explosionVisualizer, 3)

bomb.createBomb = function(bombData) -- This is used by the server scripts inside of the bomb tools to create and inherit the bomb functions.
	return setmetatable({}, bomb) -- the "newBomb" table inherits the functions and data from the bomb table/module

return bomb

A noteworthy part is the tick system which is related to the second part of what I want to achieve.

	local sound = Instance.new("Sound")
	sound.SoundId = bombData.tickSound
	sound.Parent = bombClone
	for i = 1, 3 do task.wait(bombData.tickTime) -- The timer on the bomb for explosion is ticking
		if i == 3 then task.wait(1) end -- prevents the bomb from exploding instantly on the third i = (tickTime * 3) + 1

Ignoring the client code, this is the code on the server inside of the tools that create the newBomb .

--\\ Variables //--
local replicatedStorage = game:GetService("ReplicatedStorage")
local bombModule = require(replicatedStorage:WaitForChild("Modules"):WaitForChild("BombModule"))

local remoteEvents = replicatedStorage:WaitForChild("RemoteEvents")
local activateBombRemote = script.Parent:WaitForChild("ActivateBomb") -- Checks when the bomb is activated on the client.

local tool = script.Parent
local bombHandle = tool:WaitForChild("Handle")

local bombData = { -- This is the data for the bomb that are transfered into the explosion function when inherited.
	damage = 25;
	cooldown = 5;
	range = {
		["L"] = 11;
		["W"] = 11;
		["H"] = 10;
	tickTime = 1;
	tickSound = "rbxasset://sounds\\clickfast.wav";
	tickSoundVolume = 1;

	explosionSoundId = "rbxasset://sounds\\Rocket shot.wav";
	explosionSoundVolume = 1.5;
	explosionParticles = bombHandle.Explosion;

--\\ Functions //--
	local bombClone = bombHandle:Clone() -- The cloned version of the handle that eventually explodes.
	bombClone.Parent = game.Workspace
	bombClone.CanCollide = true
	bombClone.CFrame = bombHandle.CFrame * CFrame.new(0, 2, 2) -- The offset for the bomb's position when spawned.
	local newBomb = bombModule.createBomb() -- Inherites the bomb functions.
	newBomb.Explode(user, bombData, bombClone, false, true) -- the bomb explodes (vine boom).