rbxIdleWeapon/src/Server/ServerMain/init.server.luau

187 lines
5.9 KiB
Plaintext
Raw Normal View History

2025-06-29 23:59:43 +08:00
--[[
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