-- Compiled with roblox-ts v3.0.0 local TS = _G[script] local Reflect = TS.import(script, TS.getModule(script, "@flamework", "core").out).Reflect local t_1 = TS.import(script, TS.getModule(script, "@rbxts", "t").lib.ts).t local _components = TS.import(script, TS.getModule(script, "@flamework", "components").out) local Component = _components.Component local BaseComponent = _components.BaseComponent local _services = TS.import(script, TS.getModule(script, "@rbxts", "services")) local Players = _services.Players local RunService = _services.RunService local ServerStorage = _services.ServerStorage local _charm = TS.import(script, TS.getModule(script, "@rbxts", "charm")) local atom = _charm.atom local subscribe = _charm.subscribe local IsExtended = TS.import(script, script.Parent.Parent, "utility").IsExtended local Modding = TS.import(script, TS.getModule(script, "@flamework", "core").out).Modding local Janitor = TS.import(script, TS.getModule(script, "@rbxts", "janitor").src).Janitor local OwnerProfile = TS.import(script, script.Parent, "OwnerProfile").OwnerProfile local getIdFromSpecifier = TS.import(script, TS.getModule(script, "@flamework", "components").out.utility).getIdFromSpecifier local produce = TS.import(script, TS.getModule(script, "@rbxts", "immut").src).produce local DefineContext = TS.import(script, script.Parent, "decorators", "Inject-tycoon").DefineContext local Signal = TS.import(script, TS.getModule(script, "@rbxts", "signals-tooling").out).Signal local TycoonStorage = (if RunService:IsServer() then Instance.new("Folder", ServerStorage) else nil) local BaseTycoonComponent do local super = BaseComponent BaseTycoonComponent = setmetatable({}, { __tostring = function() return "BaseTycoonComponent" end, __index = super, }) BaseTycoonComponent.__index = BaseTycoonComponent function BaseTycoonComponent:constructor(logger, components, tycoonService) super.constructor(self) self.logger = logger self.components = components self.tycoonService = tycoonService self.DataChanged = Signal.new() self.Claimed = Signal.new() self.Unclaimed = Signal.new() self.OwnerChanged = Signal.new() self.DataResetted = Signal.new() self.dataContrainter = atom(nil) self.items = {} self.itemsByInstance = {} self.janitor = Janitor.new() end function BaseTycoonComponent:onStart() self.container = Instance.new("Folder") self.janitor:Add(self.container) self.container.Name = self.instance.Name self.container.Parent = TycoonStorage self.dataContrainter(self:generateData()) self:initEvents() self:initItems() end function BaseTycoonComponent:GetItemsOfType(ctor, excludeLocked) if excludeLocked == nil then excludeLocked = false end local items = {} local _exp = self.items -- ▼ ReadonlyMap.forEach ▼ local _callback = function(item) if excludeLocked and item:IsLocked() then return nil end if TS.instanceof(item, ctor) then local _item = item table.insert(items, _item) end end for _k, _v in _exp do _callback(_v, _k, _exp) end -- ▲ ReadonlyMap.forEach ▲ return items end function BaseTycoonComponent:GetItems() local _array = {} local _length = #_array for _k, _v in self.items do _length += 1 _array[_length] = { _k, _v } end -- ▼ ReadonlyArray.map ▼ local _newValue = table.create(#_array) local _callback = function(_param) local _ = _param[1] local T = _param[2] return T end for _k, _v in _array do _newValue[_k] = _callback(_v, _k - 1, _array) end -- ▲ ReadonlyArray.map ▲ return _newValue end function BaseTycoonComponent:initEvents() self.janitor:Add(subscribe(self.dataContrainter, function(newData, prevData) self.DataChanged:fire(newData, prevData) end)) self.janitor:Add(self.DataChanged, "destroy") self.janitor:Add(self.Claimed, "destroy") self.janitor:Add(self.Unclaimed, "destroy") self.janitor:Add(self.OwnerChanged, "destroy") self.janitor:Add(self.DataResetted, "destroy") self.logger:Info(`Initialized events`) end function BaseTycoonComponent:findAllItemTags(instance) local taggedItems = self.tycoonService:GetConstructorItems() local _exp = instance:GetTags() -- ▼ ReadonlyArray.filter ▼ local _newValue = {} local _callback = function(tag) local _tag = tag return taggedItems[_tag] ~= nil end local _length = 0 for _k, _v in _exp do if _callback(_v, _k - 1, _exp) == true then _length += 1 _newValue[_length] = _v end end -- ▲ ReadonlyArray.filter ▲ return _newValue end function BaseTycoonComponent:initItems() local taggedItems = self.tycoonService:GetConstructorItems() local _exp = self.instance:GetDescendants() -- ▼ ReadonlyArray.forEach ▼ local _callback = function(instance) local foundTags = self:findAllItemTags(instance) if #foundTags == 0 then return nil end if #foundTags > 1 then self.logger:Warn(`Instance has more than one item tag: {table.concat(foundTags, ", ")}`) return nil end local _self = self local _exp_1 = instance local _arg0 = foundTags[1] _self:setupItem(_exp_1, getIdFromSpecifier(taggedItems[_arg0])) end for _k, _v in _exp do _callback(_v, _k - 1, _exp) end -- ▲ ReadonlyArray.forEach ▲ local _exp_1 = self.items -- ▼ ReadonlyMap.forEach ▼ local _callback_1 = function(item) item:onSetup() end for _k, _v in _exp_1 do _callback_1(_v, _k, _exp_1) end -- ▲ ReadonlyMap.forEach ▲ self.logger:Info(`Initialized items`) end function BaseTycoonComponent:setupItem(instance, specific) DefineContext(self) local component = self.components:addComponent(instance, specific) local _logger = self.logger local _items = self.items local _arg0 = component:GetId() _logger:Assert(not (_items[_arg0] ~= nil), `This item id "{component:GetId()}" is already in use`) local _items_1 = self.items local _arg0_1 = component:GetId() _items_1[_arg0_1] = component local _itemsByInstance = self.itemsByInstance local _instance = component.instance _itemsByInstance[_instance] = component end function BaseTycoonComponent:resetData(data) self.dataContrainter(data or self:generateData()) self.DataResetted:fire() self.logger:Info(`Reset data to`, self:GetData()) end function BaseTycoonComponent:destroyItems() local _exp = self.items -- ▼ ReadonlyMap.forEach ▼ local _callback = function(item) return item:Destroy() end for _k, _v in _exp do _callback(_v, _k, _exp) end -- ▲ ReadonlyMap.forEach ▲ table.clear(self.items) table.clear(self.itemsByInstance) end function BaseTycoonComponent:createOwnerProfile(instance) return OwnerProfile.new(instance, self) end function BaseTycoonComponent:MutateItemData(id, newData) self.dataContrainter(produce(self.dataContrainter(), function(draft) local _items = draft.Items local _id = id local _newData = newData _items[_id] = _newData end)) self.logger:Info(`Mutated item data`, self.dataContrainter().Items) end function BaseTycoonComponent:ClearItemData(id) self.dataContrainter(produce(self.dataContrainter(), function(draft) local _items = draft.Items local _id = id _items[_id] = nil end)) self.logger:Info(`Clear item data {id}`) end function BaseTycoonComponent:GetItem(qualifier, itemType) local _itemType = itemType assert(_itemType ~= "" and _itemType, "itemType is required") local _qualifier = qualifier local _result if type(_qualifier) == "string" then local _items = self.items local _qualifier_1 = qualifier _result = _items[_qualifier_1] else local _itemsByInstance = self.itemsByInstance local _qualifier_1 = qualifier _result = _itemsByInstance[_qualifier_1] end local component = _result if not component then return nil end if itemType == "@rbxts/flamework-tycoon:source/item/BaseTycoonItem@BaseTycoonItem" then return component end local requiredConstructor = Modding.getObjectFromId(itemType) if not IsExtended(getmetatable(component), requiredConstructor) then return nil end return component end function BaseTycoonComponent:GetContainer() return self.container end function BaseTycoonComponent:GetOwner() return self.owner end function BaseTycoonComponent:VerifyOwner(player) local _result = self.owner if _result ~= nil then _result = _result.Instance end return _result == player end function BaseTycoonComponent:VerifyOwnerByCharacter(model) return self:VerifyOwner(Players:GetPlayerFromCharacter(model)) end function BaseTycoonComponent:HasOwner() return self.owner ~= nil end function BaseTycoonComponent:GetData() return self.dataContrainter() end function BaseTycoonComponent:Claim(owner, data) local _arg0 = not self.owner assert(_arg0, "Already owned!") self.owner = self:createOwnerProfile(owner) self:resetData(data) self.OwnerChanged:fire(owner) self.Claimed:fire(owner) self.logger:Info(`Claimed`, owner) return self.owner end function BaseTycoonComponent:Unclaim() local _owner = self.owner assert(_owner, "Not owned!") self.owner:Destroy() self.owner = nil self.OwnerChanged:fire(nil) self.Unclaimed:fire() self.logger:Info(`Disowned`) end function BaseTycoonComponent:ResetData() self:resetData() end function BaseTycoonComponent:Destroy() self:destroyItems() self.components:removeComponent(self.instance, getIdFromSpecifier(getmetatable(self))) end function BaseTycoonComponent:destroy() super.destroy(self) self.janitor:Destroy() setmetatable(self, { __index = function(t, index) error(`Tycoon destroyed.`) end, }) self.logger:Info(`Destroyed`) end do -- (Flamework) BaseTycoonComponent metadata Reflect.defineMetadata(BaseTycoonComponent, "identifier", "@rbxts/flamework-tycoon:source/BaseTycoonComponent@BaseTycoonComponent") Reflect.defineMetadata(BaseTycoonComponent, "flamework:parameters", { "@rbxts/flamework-tycoon:source/TycoonLogger@TycoonLogger", "$c:components@Components", "@rbxts/flamework-tycoon:source/TycoonService@TycoonService" }) Reflect.defineMetadata(BaseTycoonComponent, "flamework:implements", { "$:flamework@OnStart" }) end end -- (Flamework) BaseTycoonComponent decorators Reflect.decorate(BaseTycoonComponent, "$c:components@Component", Component, { { attributes = {}, instanceGuard = t_1.instanceIsA("Instance"), } }) return { BaseTycoonComponent = BaseTycoonComponent, }