--[[ Evercyan @ March 2023 ServerMain ServerMain requires many important modules for the game to work, as well as housing some miscellaneous code. The modules it requires is under ServerStorage.Modules and the script itself, which makes core features of the game work, such as armor, mobs, and the leveling system. ]] --> Services local ReplicatedStorage = game:GetService("ReplicatedStorage") local ServerStorage = game:GetService("ServerStorage") local Players = game:GetService("Players") --> References local PlayerData = ReplicatedStorage:WaitForChild("PlayerData") --> Dependencies local HumanoidAttributes = require(script.HumanoidAttributes) local PlayerLeveling = require(script.PlayerLeveling) local GameConfig = require(ReplicatedStorage.Data.GameConfig) local ContentLibrary = require(ReplicatedStorage.Modules.ContentLibrary) local ToolLib = require(ServerStorage.Modules.ToolLib) local ArmorLib = require(ServerStorage.Modules.ArmorLib) -------------------------------------------------------------------------------- -- Create initial folders local function CreateFolder(Name: string, Parent: Instance) local Folder = Instance.new("Folder") Folder.Name = Name Folder.Parent = Parent return Folder end local Temporary = CreateFolder("Temporary", workspace) local ProjectileCache = CreateFolder("ProjectileCache", Temporary) local Characters = CreateFolder("Characters", workspace) local function OnPlayerAdded(Player: Player) local pData = PlayerData:WaitForChild(Player.UserId) local Level = pData.Stats.Level local XP = pData.Stats.XP local function OnCharacterAdded(Character: Model) local Humanoid = Character:WaitForChild("Humanoid") :: Humanoid local HumanoidAttributes = HumanoidAttributes.new(Humanoid) local s = tick() while Character.Parent ~= Characters and (tick()+5 > s) do task.wait() pcall(function() Character.Parent = Characters end) end end if Player.Character then task.spawn(OnCharacterAdded, Player.Character) end Player.CharacterAdded:Connect(OnCharacterAdded) -- Starter items -- 这里不会每次进入都给玩家装备吗? for _, StarterItem in GameConfig.StarterItems do local Module = require(ServerStorage.Modules[StarterItem[1] .."Lib"]) Module:Give(Player, ContentLibrary[StarterItem[1]][StarterItem[2]]) end -- If the hotbar is completely empty, fill it with starter items pData:WaitForChild("Hotbar") local isEmpty = true for _, ValueObject in pData.Hotbar:GetChildren() do if ValueObject.Value ~= "" then isEmpty = false end end if isEmpty then for n, StarterItem in GameConfig.StarterItems do if n <= 9 then pData.Hotbar[tostring(n)].Value = StarterItem[2] end end end -- Player leveling -- 登录检测经验升级 PlayerLeveling:TryLevelUp(Player, Level, XP) -- 检测经验变化升级 XP.Changed:Connect(function() PlayerLeveling:TryLevelUp(Player, Level, XP) end) end Players.PlayerAdded:Connect(OnPlayerAdded) for _, Player in Players:GetPlayers() do task.spawn(OnPlayerAdded, Player) end -- Initially require all server-sided & shared modules for _, Location in {ReplicatedStorage.Modules, ServerStorage.Modules} do for _, Library in Location:GetChildren() do if Library:IsA("ModuleScript") then task.spawn(require, Library) end end end ---- Hotbar Persistence -------------------------------------------------------- ReplicatedStorage.Remotes.HotbarItemChanged.OnServerEvent:Connect(function(Player, SlotNumber: number, ItemName: string) if not SlotNumber or typeof(SlotNumber) ~= "number" then return end if not ItemName or typeof(ItemName) ~= "string" or #ItemName > 200 then return end local pData = PlayerData:FindFirstChild(Player.UserId) local Hotbar = pData and pData:FindFirstChild("Hotbar") local ValueObject = Hotbar and Hotbar:FindFirstChild(SlotNumber) if ValueObject then ValueObject.Value = ItemName end end) ---- Shop ---------------------------------------------------------------------- ReplicatedStorage.Remotes.BuyItem.OnServerInvoke = function(Player, ItemType: string, ItemName: string) if not ItemType or not ItemName then return end if typeof(ItemType) ~= "string" or typeof(ItemName) ~= "string" then return end local pData = PlayerData:FindFirstChild(Player.UserId) local Item = ContentLibrary[ItemType] and ContentLibrary[ItemType][ItemName] if not pData or not Item then return end if not Item.Config.Cost then return false, "This item isn't for sale" end if pData.Items[ItemType]:FindFirstChild(ItemName) then return false, "You already own this item" end if pData.Stats.Level.Value < Item.Config.Level then return false, "Your level is too low to purchase this item" end local Currency = pData.Stats[Item.Config.Cost[1]] if Currency.Value < Item.Config.Cost[2] then return false, "Your gold is too low to purchase this item" end Currency.Value -= Item.Config.Cost[2] local Module = require(ServerStorage.Modules[ItemType .."Lib"]) Module:Give(Player, Item) return true end ReplicatedStorage.Remotes.SellItem.OnServerInvoke = function(Player, ItemType: string, ItemName: string) if not ItemType or not ItemName then return end if typeof(ItemType) ~= "string" or typeof(ItemName) ~= "string" then return end local pData = PlayerData:FindFirstChild(Player.UserId) local Item = ContentLibrary[ItemType] and ContentLibrary[ItemType][ItemName] if not pData or not Item then return end if not Item.Config.Sell and not Item.Config.Cost then return false, "This item can't be sold" end if not pData.Items[ItemType]:FindFirstChild(ItemName) then return false, "You don't own this item" end local Currency = pData.Stats[Item.Config.Sell and Item.Config.Sell[1] or Item.Config.Cost[1]] local Return = Item.Config.Sell and Item.Config.Sell[2] or math.floor(Item.Config.Cost[2] / 2) local Module = require(ServerStorage.Modules[ItemType .."Lib"]) Module:Trash(Player, Item) Currency.Value += Return return true end