248 lines
9.8 KiB
Plaintext
Raw Normal View History

2025-07-03 01:48:06 +08:00
-- 关卡代理
local LevelProxy = {}
--> Services
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
--> Variables
local Utils = require(ReplicatedStorage.Tools.Utils)
local ArchiveProxy = require(ServerStorage.Proxy.ArchiveProxy)
2025-07-07 00:03:47 +08:00
local MobsProxy = require(ServerStorage.Proxy.MobsProxy)
local TypeList = require(ServerStorage.Base.TypeList)
2025-07-03 01:48:06 +08:00
--> Json
local JsonLevel = require(ReplicatedStorage.Json.Level)
--> Constants
local STORE_NAME = "Level"
local ENUM_LEVEL_TYPE = {
Main = 1,
}
--------------------------------------------------------------------------------
-- 初始化生成关卡目录
local LevelFolder = Utils:CreateFolder(STORE_NAME, game.Workspace)
--------------------------------------------------------------------------------
-- 获取玩家关卡文件夹
local function GetPlayerLevelFolder(Player: Player)
local pData = Utils:GetPlayerDataFolder(Player)
if not pData then return end
local LevelFolder = pData:FindFirstChild("Level")
return LevelFolder
end
-- 获取玩家关卡Workspace目录
local function GetPlayerLevelWorkspaceFolder(PlayerUserId: string)
return LevelFolder:FindFirstChild(PlayerUserId)
end
-- 创建关卡信息实例
local function CreateLevelInstance(Player: Player, Folder: Instance, LevelKey: string, LevelValue: number)
if not Player or not Folder or not LevelKey or not LevelValue then return end
local LevelInstance = Instance.new("NumberValue")
LevelInstance.Name = LevelKey
LevelInstance.Parent = Folder
LevelInstance.Value = LevelValue
return LevelInstance
end
-- 初始化玩家关卡信息
local function ExtraAddPlayerLevel(Player: Player, LevelData: table)
if not Player or not LevelData then return end
-- 如果列表中不包含信息就添加到表中
for LevelKey, LevelValue in ENUM_LEVEL_TYPE do
if not LevelData[LevelKey] then
LevelData[LevelKey] = LevelValue
end
end
end
2025-07-07 00:03:47 +08:00
local EXCEPT_KEY = { "Task", "Mobs"}
local function ChangeValue(Player: Player, Folder: Instance, LevelKey: string, LevelValue: any)
if not Player or not Folder or not LevelKey or not LevelValue then return end
local ValueInstance = Folder:FindFirstChild(LevelKey)
if not ValueInstance then return end
local storeTable
if Folder.Name == "Challenge" then
storeTable = LevelProxy.pData[Player.UserId]
else
storeTable = ArchiveProxy.pData[Player.UserId][STORE_NAME].Progress
end
storeTable[LevelKey] = LevelValue
if not table.find(EXCEPT_KEY, LevelKey) then ValueInstance.Value = LevelValue end
end
-- 怪物死亡,由初始化时传入
local function OnMobDied(Player: Player, Mob: TypeList.Character)
for _, mob in LevelProxy.pData[Player.UserId].Mobs do
if mob ~= Mob then continue end
table.remove(LevelProxy.pData[Player.UserId].Mobs, mob)
-- 怪物清除判断
local LevelData = Utils:GetJsonData(JsonLevel, LevelProxy.pData[Player.UserId].LevelId)
if LevelProxy.pData[Player.UserId].SpawnWaveFinish and #LevelProxy.pData[Player.UserId].Mobs == 0 then
if LevelProxy.pData[Player.UserId].NowWave < #LevelData["wave"] then
-- 波数增长
LevelProxy.pData[Player.UserId].NowWave = LevelProxy.pData[Player.UserId].NowWave + 1
-- 新波次重置怪物生成状态标记
local ChallengeFolder = LevelFolder:FindFirstChild("Challenge")
ChangeValue(Player, ChallengeFolder, "SpawnWaveFinish", false)
elseif LevelProxy.pData[Player.UserId].NowWave >= #LevelData["wave"] then
-- 结束判断
LevelProxy:ChallengeEnd(Player, true)
end
end
break
end
end
2025-07-03 01:48:06 +08:00
--------------------------------------------------------------------------------
function LevelProxy:InitPlayer(Player: Player)
local pData = Utils:GetPlayerDataFolder(Player)
if not pData then return end
local LevelFolder = Utils:CreateFolder(STORE_NAME, pData)
local ProgressFolder = Utils:CreateFolder("Progress", LevelFolder)
local DungeonFolder = Utils:CreateFolder("Dungeon", LevelFolder)
2025-07-07 00:03:47 +08:00
local ChallengeFolder = Utils:CreateFolder("Challenge", LevelFolder)
2025-07-03 01:48:06 +08:00
-- 当前关卡状态
Utils:CreateFolder("Stats", LevelFolder)
-- 关卡目录下生成玩家目录
local spawnFloder = Utils:CreateFolder(Player.UserId, game.Workspace:FindFirstChild(STORE_NAME))
-- 新玩家数据初始化
if not ArchiveProxy.pData[Player.UserId][STORE_NAME] then
ArchiveProxy.pData[Player.UserId][STORE_NAME] = {}
ArchiveProxy.pData[Player.UserId][STORE_NAME].Progress = {}
-- 副本之后再做
ArchiveProxy.pData[Player.UserId][STORE_NAME].Dungeon = {}
end
ExtraAddPlayerLevel(Player, ArchiveProxy.pData[Player.UserId][STORE_NAME].Progress)
-- 前端变化
for LevelKey, LevelValue in ArchiveProxy.pData[Player.UserId][STORE_NAME].Progress do
CreateLevelInstance(Player, ProgressFolder, LevelKey, LevelValue)
end
2025-07-07 00:03:47 +08:00
-- 本地内容初始化(关卡挑战信息,不存储)
if not LevelProxy.pData then LevelProxy.pData = {} end
if not LevelProxy.pData[Player.UserId] then LevelProxy.pData[Player.UserId] = {} end
LevelProxy.pData[Player.UserId].Task = nil
LevelProxy.pData[Player.UserId].Time = 0
LevelProxy.pData[Player.UserId].LevelId = 0
LevelProxy.pData[Player.UserId].MaxTime = 0
LevelProxy.pData[Player.UserId].IsBoss = false
LevelProxy.pData[Player.UserId].NowWave = 0
LevelProxy.pData[Player.UserId].ShouldWave = 0
LevelProxy.pData[Player.UserId].SpawnWaveFinish = false
LevelProxy.pData[Player.UserId].Mobs = {}
-- 关卡挑战信息前端
for key, value in LevelProxy.pData[Player.UserId] do
if key == "Task" or key == "Mobs" then continue end
CreateLevelInstance(Player, ChallengeFolder, key, value)
end
2025-07-03 01:48:06 +08:00
end
-- 挑战关卡(挑战副本用另一个函数)
function LevelProxy:ChallengeLevel(Player: Player, LevelId: number)
2025-07-07 00:03:47 +08:00
local LevelData = Utils:GetJsonData(JsonLevel, LevelId)
if not LevelData then warn("Level Data not found", LevelId) return end
2025-07-03 01:48:06 +08:00
-- 给前端传数据,做表现
-- 场景后端生成
-- 后端生成当前关卡状态数据
2025-07-07 00:03:47 +08:00
local LevelFolder = GetPlayerLevelWorkspaceFolder(Player.UserId)
local ChallengeFolder = LevelFolder:FindFirstChild("Challenge")
if not ChallengeFolder then return end
local levelTask = task.defer(function()
ChangeValue(Player, ChallengeFolder, "IsBoss", LevelData.type == 1 and true or false)
ChangeValue(Player, ChallengeFolder, "LevelId", LevelId)
ChangeValue(Player, ChallengeFolder, "Time", 0)
ChangeValue(Player, ChallengeFolder, "NowWave", 0)
ChangeValue(Player, ChallengeFolder, "ShouldWave", 1)
ChangeValue(Player, ChallengeFolder, "MaxTime", LevelData.timeLimit or 0)
ChangeValue(Player, ChallengeFolder, "Mobs", {})
if LevelData.timeLimit then
while task.wait(1) do
ChangeValue(Player, ChallengeFolder, "Time", LevelProxy.pData[Player.UserId].Time + 1)
-- 关卡生成
if LevelProxy.pData[Player.UserId].Wave < #LevelData.wave then
ChangeValue(Player, ChallengeFolder, "Wave", LevelProxy.pData[Player.UserId].Wave + 1)
end
if LevelProxy.pData[Player.UserId].NowWave < LevelProxy.pData[Player.UserId].ShouldWave then
ChangeValue(Player, ChallengeFolder, "NowWave", LevelProxy.pData[Player.UserId].NowWave + 1)
local waveData = LevelData.wave[LevelProxy.pData[Player.UserId].NowWave]
for i = 1, #waveData, 3 do
local mobId = waveData[i + 1]
local mobCount = waveData[i + 2]
for _ = 1, mobCount do
local mob = MobsProxy:CreateMob(Player, mobId, LevelData.atkBonus, LevelData.hpBonus, OnMobDied)
table.insert(LevelProxy.pData[Player.UserId].Mobs, mob)
end
end
ChangeValue(Player, ChallengeFolder, "SpawnWaveFinish", true)
end
-- 时间结束
if LevelProxy.pData[Player.UserId].Time >= LevelData.timeLimit then
self:ChallengeEnd(Player, false)
break
end
end
end
end)
ChangeValue(Player, ChallengeFolder, "Task", levelTask)
2025-07-03 01:48:06 +08:00
end
-- 挑战结束
2025-07-07 00:03:47 +08:00
function LevelProxy:ChallengeEnd(Player: Player, result: boolean)
local pData = Utils:GetPlayerDataFolder(Player)
local LevelFolder = Utils:CreateFolder(STORE_NAME, pData)
local ProgressFolder = Utils:CreateFolder("Progress", LevelFolder)
-- 清除剩余怪物
for _, mob in LevelProxy.pData[Player.UserId].Mobs do
mob:Died()
end
LevelProxy.pData[Player.UserId].Mobs = {}
2025-07-03 01:48:06 +08:00
-- 判断玩家是否通关
2025-07-07 00:03:47 +08:00
if result then
ChangeValue(Player, ProgressFolder, "LevelId", LevelProxy.pData[Player.UserId].LevelId + 1)
end
2025-07-03 01:48:06 +08:00
end
function LevelProxy:OnPlayerRemoving(Player: Player)
2025-07-07 00:03:47 +08:00
-- 关卡文件夹清除
2025-07-03 01:48:06 +08:00
local PlayerLevelFolder = GetPlayerLevelWorkspaceFolder(Player.UserId)
if PlayerLevelFolder then
PlayerLevelFolder:Destroy()
end
2025-07-07 00:03:47 +08:00
-- 关卡存储数据清除
if LevelProxy.pData[Player.UserId].Task then
LevelProxy.pData[Player.UserId].Task:Cancel()
end
LevelProxy.pData[Player.UserId] = nil
2025-07-03 01:48:06 +08:00
end
-- ReplicatedStorage.Remotes.PlayerRemoving.Event:Connect(function(PlayerUserId: string)
-- LevelProxy:OnPlayerRemoving(PlayerUserId)
-- end)
Players.PlayerRemoving:Connect(function(Player: Player)
LevelProxy:OnPlayerRemoving(Player)
end)
return LevelProxy