-
What do you want to achieve? Keep it simple and clear!
I want to merge my Component and Engine modules, since they are very similar. I want the Engine module to inherit from the Component module. -
What is the issue? Include screenshots / videos if possible!
I can’t figure out a way of how to do it. It looks so simple but I just can’t get it. -
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I tried using getmetatable and using separate registers but it didnt work.
Both modules store Instances of their objects in the tables called Instances
Component.Instances = {}
I use this code to add instances to the tables
table.insert(Component.Instances, self)
self.UID = uid
uid += 1
I need to store using uid because I use a lookup function to fetch instances using their children having the same UID.
function Component.lookup(instance:Instance): Component?
for i, v in ipairs(Component.Instances) do
if v.UID == instance:GetAttribute(lookupPrefix .. "UID") then --in this case lookup prefix is Component
return v
end
end
end
my end goal here is for the Engine module to inherit from the Component module. The Engine modules has additional functions.
Component Module
local SS = game:GetService("ServerStorage")
local uid = 1
local lookupPrefix = "Component"
local Component = {}
Component.__index = Component
Component.Instances = {}
type self = {
Body:Model,
Tool:Tool,
UID:number
}
export type Component = typeof(setmetatable({} :: self, Component))
function Component.new(name:string, position:Vector3): Component
local self = setmetatable({} :: self, Component)
table.insert(Component.Instances, self)
self.UID = uid
uid += 1
local tool:Tool = Instance.new("Tool")
tool.Name = name
tool.CanBeDropped = false
self.Tool = tool
local handle:BasePart = Instance.new("Part")
handle.Size = Vector3.one
handle.Transparency = 1
handle.Name = "Handle"
handle.Position = position
handle.CanTouch = false
handle.Parent = tool
local body:Model = SS.Components:FindFirstChild(name):Clone()
body:PivotTo(CFrame.new(position))
body.Parent = tool
self.Body = body
local weld:WeldConstraint = Instance.new("WeldConstraint")
weld.Part0 = handle
weld.Part1 = body.PrimaryPart
weld.Parent = handle
for i, v in ipairs(body:GetChildren()) do
v:SetAttribute(lookupPrefix .. "UID", self.UID)
end
body:SetAttribute(lookupPrefix .. "UID", self.UID)
tool.Parent = workspace
tool.PrimaryPart = body.PrimaryPart
tool.Destroying:Once(function()
self:destroy()
end)
return self
end
function Component.destroy(self:Component): ()
local selfuid = self.UID
table.remove(Component.Instances, table.find(Component.Instances, self))
self = nil
print(lookupPrefix .. " UID: " .. selfuid, Component.Instances)
end
function Component.lookup(instance:Instance): Component?
for i, v in ipairs(Component.Instances) do
if v.UID == instance:GetAttribute(lookupPrefix .. "UID") then
return v
end
end
end
return Component
Engine Module
local SS = game:GetService("ServerStorage")
local Component = require(script.Parent.Component)
local uid = 1
local lookupPrefix = "Engine"
local Engine = {}
Engine.__index = Engine
Engine.Instances = {}
type self = {
Body:Model,
Tool:Tool,
UID:number
}
export type Engine = typeof(setmetatable({} :: self, Engine))
function Engine.new(name:string, position:Vector3): Engine
local self = setmetatable({} :: self, Engine)
table.insert(Engine.Instances, self)
self.UID = uid
uid += 1
local tool:Tool = Instance.new("Tool")
tool.Name = name
tool.CanBeDropped = false
self.Tool = tool
local handle:BasePart = Instance.new("Part")
handle.Size = Vector3.one
handle.Transparency = 1
handle.Name = "Handle"
handle.Position = position
handle.CanTouch = false
handle.Parent = tool
local body:Model = SS.Components:FindFirstChild(name):Clone()
body:PivotTo(CFrame.new(position))
body.Parent = tool
self.Body = body
local weld:WeldConstraint = Instance.new("WeldConstraint")
weld.Part0 = handle
weld.Part1 = body.PrimaryPart
weld.Parent = handle
for i, v in ipairs(body:GetChildren()) do
v:SetAttribute(lookupPrefix .. "UID", self.UID)
end
body:SetAttribute(lookupPrefix .. "UID", self.UID)
tool.Parent = workspace
tool.PrimaryPart = body.PrimaryPart
tool.Destroying:Once(function()
self:destroy()
end)
return self
end
function Engine.destroy(self:Engine): ()
local selfuid = self.UID
table.remove(Engine.Instances, table.find(Engine.Instances, self))
self = nil
print(lookupPrefix .. " UID: " .. selfuid, Engine.Instances)
end
function Engine.lookup(instance:Instance): Engine?
for i, v in ipairs(Engine.Instances) do
if v.UID == instance:GetAttribute(lookupPrefix .. "UID") then
return v
end
end
end
function Engine.PlaceComponent(self:Engine, component:Component.Component, slot:BasePart): ()
local clone = component.Body:Clone()
clone:PivotTo(slot.CFrame)
clone.Parent = slot
local weld:WeldConstraint = Instance.new("WeldConstraint")
weld.Part0 = slot
weld.Part1 = clone.PrimaryPart
weld.Parent = slot
slot.Transparency = 1
component.Tool:Destroy()
self:Update()
end
function Engine.RemoveComponent(self:Engine, body:Model, slot:BasePart): ()
local component = Component.new(slot:GetAttribute("ComponentType"), slot.Position + Vector3.new(0, 5, 0))
body:Destroy()
slot.Transparency = 0.5
self:Update()
end
function Engine.Update(self:Engine): ()
local count = 0
local filled = 0
for i, v in ipairs(self.Body:GetChildren()) do
if v.Name == "Slot" then
count += 1
if v:GetAttribute("Filled") == true then filled += 1; end
end
end
self.Body:SetAttribute("Built", count == filled);
end
return Engine