OOP Weapon system approch

So recently i started learning oop and im tryna make a weapon system, so i understood everything about it, i think but im tryna find a way to connect in a decent way the client and the Server

the module is located in ReplicatedStorage

so this is the class which is fine by itself and this is the approch im using i create a new instance in the server and when i do it puts the instance in a table that get sent to all client that basically keep them updated so they can handle themself effect.

so basically when on my client i use the method boost it play the effect and updated the instance then the server get fired and use the same method too but don’t play the effects becouse there is the IsClient condition, then the server will fire all clients and make them fire the same method, this part is still not coded but its what im planning to do.

i know this is wrong but i wasn’t able to find a better solution thats why im here. even if you got a solution please explain to me a your approch(with a coded example if possible) so i can see whats better

-Class

local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Remotes = ReplicatedStorage.Remotes
local WeaponHandlingEvent = Remotes.WeaponHandling
local WeaponData = Remotes.WeaponData

local Assets = ReplicatedStorage.Assets
local ParticleEffects = Assets.ParticleEffects

local Weapon = {}
Weapon.__index = Weapon

function Weapon.new(Settings)
	local NewWeapon = {}
	setmetatable(NewWeapon, Weapon)
	
	local owner = Settings["owner"]
	local weaponname = Settings["weaponname"] 
	local damage = Settings["damage"]
	local knockbackforce = Settings["knockbackforce"] 
	local attackspeed = Settings["attackspeed"]
	local model = Settings["model"]
	
	NewWeapon.Owner = owner or nil
	NewWeapon.Name = weaponname or ""
	NewWeapon.Damage = damage or 0
	NewWeapon.Knockback = knockbackforce or 20
	NewWeapon.AttackSpeed = attackspeed or 0
	NewWeapon.Model = model:Clone() or nil
	
	NewWeapon.Event = Instance.new("RemoteEvent",Remotes)
	NewWeapon.Event.Name = NewWeapon.Owner.UserId.."-"..NewWeapon.Name
	
	NewWeapon.Boosted = false
	NewWeapon.CurrentBoost = ""
	
	NewWeapon.CanAttack = true
	NewWeapon.CanBoost = true
	
	NewWeapon.Equipped = false
	NewWeapon.Tool = nil
	
	print("Instanced a new Weapon.")
	
	NewWeapon:buildtool()
	
	return NewWeapon
end

function Weapon:buildtool()
	if RunService:IsServer() then
		local Char = self.Owner.Character or self.Owner.CharacterAdded:Wait()
		self.Tool = Instance.new("Tool")
		self.Tool.Name = self.Name
		
		if (self.Model) then 
			for i,part in ipairs(self.Model:GetChildren()) do
				part.Parent = self.Tool 
			end
		end
		
		self.Tool.Parent = self.Owner.Backpack	
	end
end

function Weapon:boosteffect()
	local Thread = coroutine.create(function()
		if RunService:IsClient() then
			local CurrentEffectName = self.CurrentBoost
			local CurrentParticle = ParticleEffects:FindFirstChild(CurrentEffectName)

			if CurrentParticle then
				for i,Child in ipairs(CurrentParticle:GetChildren()) do
					Child:Clone().Parent = self.Tool.Blade
				end
			end
		end
	end)
	coroutine.resume(Thread)
end

function Weapon:stopboosteffect()
	local Thread = coroutine.create(function()
		if RunService:IsClient() then
			for i,Child in ipairs(self.Tool.Blade:GetChildren()) do
				Child:Destroy()
			end
		end
	end)
	coroutine.resume(Thread)
end

function Weapon:boost(player, element, duration)
	local Thread = coroutine.create(function()
		if self.Boosted == true then return end
		self.Boosted = true
		self.CurrentBoost = element
		self:boosteffect()
		
		if RunService:IsClient() then
			if self.Owner == player then 
				WeaponHandlingEvent:FireServer("Boost")
			end
		end
		
		task.wait(duration)
		
		if RunService:IsClient() then
			if self.Owner == player then 
				WeaponHandlingEvent:FireServer("StopBoosting")
			end
		end
		
		self.Boosted = false
		self.CurrentBoost = ""
		self:stopboosteffect()
	end)
	coroutine.resume(Thread)
end

return Weapon

-Server

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Models = ReplicatedStorage.Models
local Classes = ReplicatedStorage.Classes
local WeaponsClass = require(Classes.Weapons)

local Remotes = ReplicatedStorage.Remotes
local WeaponData = Remotes.WeaponData

local InitiatedWeapons = {}

local BasicWeapon = {
	["owner"] = "",
	["weaponname"] = "Iron Sword",
	["damage"] = 10,
	["knockbackforce"] = 20,
	["attackspeed"] = 10,
	["model"] = Models.IronSword,
}

function PlayerAdded(Player)
	BasicWeapon.owner = Player
	
	local NewSword = WeaponsClass.new(BasicWeapon)
	table.insert(InitiatedWeapons,NewSword)
end

function ReturnWeaponsData()
	return InitiatedWeapons
end

WeaponData.OnServerInvoke = ReturnWeaponsData
Players.PlayerAdded:Connect(PlayerAdded)

the server is just to test some stuff
and the client is still not done becouse im not confident on my idea

1 Like