372 lines
15 KiB
Plaintext
372 lines
15 KiB
Plaintext
-- 装备代理
|
|
local EquipmentProxy = {}
|
|
|
|
--> Services
|
|
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
|
local ServerStorage = game:GetService("ServerStorage")
|
|
|
|
--> Variables
|
|
local Utils = require(ReplicatedStorage.Tools.Utils)
|
|
local ArchiveProxy = require(ServerStorage.Proxy.ArchiveProxy)
|
|
local PlayerInfoProxy = require(ServerStorage.Proxy.PlayerInfoProxy)
|
|
local PlayerFightProxy = require(ServerStorage.Proxy.PlayerFightProxy)
|
|
|
|
--> Json
|
|
local JsonEquipment = require(ReplicatedStorage.Json.Equipment)
|
|
local JsonAttributes = require(ReplicatedStorage.Json.Attributes)
|
|
local JsonExAttributes = require(ReplicatedStorage.Json.ExAttributes)
|
|
local JsonParam = require(ReplicatedStorage.Json.Param)
|
|
|
|
--> Events
|
|
local RE_PlayerTip = ReplicatedStorage.Events.RE_PlayerTip
|
|
local RE_WearEquipment = ReplicatedStorage.Events.RE_WearEquipment
|
|
|
|
|
|
--> Constants
|
|
local STORE_NAME = "Equipment"
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
-- 获取装备文件夹
|
|
local function GetPlayerEquipmentFolder(Player: Player)
|
|
local pData = Utils:GetPlayerDataFolder(Player)
|
|
if not pData then return end
|
|
local EquipmentFolder = pData:FindFirstChild("Equipment")
|
|
return EquipmentFolder
|
|
end
|
|
|
|
-- 计算词条等级加成上限
|
|
local function GetEntryLvBonus(PlayerLv: number, BonusData: table)
|
|
local bonus = math.floor(PlayerLv / BonusData[1]) * BonusData[2]
|
|
return math.min(bonus, BonusData[3])
|
|
end
|
|
|
|
-- 改变装备数据
|
|
local function ChangeValue(Player: Player, EquipmentUniqueId: number, KeyName: string, Value: any)
|
|
if not Player or not EquipmentUniqueId or not KeyName then warn("EquipmentProxy ChangeValue", Player.UserId, EquipmentUniqueId, KeyName, Value) return end
|
|
local ValueInstance = GetPlayerEquipmentFolder(Player):FindFirstChild(EquipmentUniqueId)
|
|
if not ValueInstance then warn("ValueInstance not found", KeyName) return end
|
|
|
|
ArchiveProxy.pData[Player.UserId][EquipmentUniqueId][KeyName] = Value
|
|
ValueInstance:SetAttribute(KeyName, Value)
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
-- 初始化玩家
|
|
function EquipmentProxy:InitPlayer(Player: Player)
|
|
local pData = Utils:GetPlayerDataFolder(Player)
|
|
if not pData then return end
|
|
Utils:CreateFolder("Equipment", pData)
|
|
|
|
-- 新玩家数据初始化
|
|
if not ArchiveProxy.pData[Player.UserId][STORE_NAME] then
|
|
ArchiveProxy.pData[Player.UserId][STORE_NAME] = {}
|
|
end
|
|
|
|
-- 初始化装备
|
|
for uniqueId, EquipmentData in ArchiveProxy.pData[Player.UserId][STORE_NAME] do
|
|
local config = Utils:CreateDataInstance(Player, uniqueId, EquipmentData, GetPlayerEquipmentFolder(Player))
|
|
end
|
|
end
|
|
|
|
-- 一些特殊记录或者不用记录的Key
|
|
local EXCEPT_KEYS = { "id", "orgId", "name", "attributes"}
|
|
-- 添加装备到背包
|
|
function EquipmentProxy:AddEquipment(Player: Player, EquipmentId: number)
|
|
local pData = Utils:GetPlayerDataFolder(Player)
|
|
if not pData then return end
|
|
|
|
local EquipmentData = Utils:GetIdDataFromJson(JsonEquipment, EquipmentId)
|
|
if not EquipmentData then return end
|
|
|
|
local UniqueId = Utils:GenUniqueId(ArchiveProxy.pData[Player.UserId][STORE_NAME])
|
|
-- 配置表内容
|
|
local ResultData = {}
|
|
for key, value in pairs(EquipmentData) do
|
|
if not table.find(EXCEPT_KEYS, key) then
|
|
ResultData[key] = value
|
|
end
|
|
end
|
|
|
|
ResultData.id = UniqueId
|
|
ResultData.orgId = EquipmentId
|
|
-- 到时候记录穿戴槽位
|
|
ResultData.wearing = 0
|
|
|
|
-- 随机生成总变量
|
|
local rng = Random.new()
|
|
local PlayerLevel = PlayerInfoProxy:GetPlayerLevel(Player)
|
|
|
|
-- TODO: 之后这里可能根据等级限制权重
|
|
-- 随机生成品质
|
|
local qualityWeightTable = {
|
|
[1] = 90,
|
|
[2] = 70,
|
|
[3] = 50,
|
|
[4] = 30,
|
|
[5] = 10,
|
|
[6] = 5,
|
|
}
|
|
local quality = Utils:GetRandomWeightIndex(qualityWeightTable)
|
|
local qualityParam = Utils:GetIdDataFromJson(JsonParam, 1).intArray
|
|
ResultData.quality = quality
|
|
|
|
-- 生成装备基础词条(固定的)
|
|
ResultData.attributes = {}
|
|
for i = 1, #EquipmentData.attributes, 3 do
|
|
local AttributeData = Utils:GetIdDataFromJson(JsonAttributes, EquipmentData.attributes[i])
|
|
local baseLvValue = EquipmentData.attributes[i + 1] + EquipmentData.attributes[i + 2] * (PlayerLevel - 1)
|
|
local qualityEffectValue = math.floor(baseLvValue * (qualityParam[quality] / 100))
|
|
ResultData.attributes[AttributeData.effectAttribute] = qualityEffectValue
|
|
end
|
|
|
|
-- TODO: 其他随机词条内容添加在下面
|
|
-- 随机生成额外属性数量
|
|
local maxExAttributeNumber = PlayerInfoProxy:GetPlayerInfo(Player).exAttributeNumber or 0
|
|
local exAttributeNumber = rng:NextInteger(0, maxExAttributeNumber)
|
|
ResultData.maxExAttributeNumber = exAttributeNumber
|
|
ResultData.exAttributes = {}
|
|
if exAttributeNumber > 0 then
|
|
local spawnExAttributesId = {}
|
|
for i = 1, exAttributeNumber do
|
|
local newExAttributeId = Utils:GetRandomIdFromJsonWithType(JsonExAttributes, 1, spawnExAttributesId)
|
|
table.insert(spawnExAttributesId, newExAttributeId)
|
|
|
|
local ExAttributeData = Utils:GetIdDataFromJson(JsonExAttributes, newExAttributeId)
|
|
local minValue = ExAttributeData.randomValue[1]
|
|
local maxValue = ExAttributeData.randomValue[2] + GetEntryLvBonus(PlayerLevel, ExAttributeData.bonus)
|
|
local randomExAttributeValue = rng:NextInteger(minValue, maxValue)
|
|
|
|
local AttributeData = Utils:GetIdDataFromJson(JsonAttributes, newExAttributeId)
|
|
ResultData.exAttributes[AttributeData.name] = randomExAttributeValue
|
|
end
|
|
end
|
|
|
|
-- 随机生成元素属性数量(暂时跟额外属性相同,之后可以改逻辑)
|
|
local maxElementNumber = PlayerInfoProxy:GetPlayerInfo(Player).elementNumber or 0
|
|
local elementNumber = rng:NextInteger(0, maxElementNumber)
|
|
ResultData.maxElementNumber = elementNumber
|
|
ResultData.elements = {}
|
|
if elementNumber > 0 then
|
|
local spawnElementsId = {}
|
|
for i = 1, elementNumber do
|
|
local newElementAttributeId = Utils:GetRandomIdFromJsonWithType(JsonExAttributes, 1, spawnElementsId)
|
|
table.insert(spawnElementsId, newElementAttributeId)
|
|
|
|
local ElementAttributeData = Utils:GetIdDataFromJson(JsonExAttributes, newElementAttributeId)
|
|
local minValue = ElementAttributeData.randomValue[1]
|
|
local maxValue = ElementAttributeData.randomValue[2] + GetEntryLvBonus(PlayerLevel, ElementAttributeData.bonus)
|
|
local randomElementAttributeValue = rng:NextInteger(minValue, maxValue)
|
|
|
|
local AttributeData = Utils:GetIdDataFromJson(JsonAttributes, newElementAttributeId)
|
|
ResultData.elements[AttributeData.name] = randomElementAttributeValue
|
|
end
|
|
end
|
|
|
|
-- 随机生成元素抗性数量
|
|
local maxElementDefNumber = PlayerInfoProxy:GetPlayerInfo(Player).elementDefNumber or 0
|
|
local elementDefNumber = rng:NextInteger(0, maxElementDefNumber)
|
|
ResultData.maxElementDefNumber = elementDefNumber
|
|
ResultData.elementDef = {}
|
|
if elementDefNumber > 0 then
|
|
local spawnElementDefId = {}
|
|
for i = 1, elementDefNumber do
|
|
local newElementDefId = Utils:GetRandomIdFromJsonWithType(JsonExAttributes, 1, spawnElementDefId)
|
|
table.insert(spawnElementDefId, newElementDefId)
|
|
|
|
local ElementDefAttributeData = Utils:GetIdDataFromJson(JsonExAttributes, newElementDefId)
|
|
local minValue = ElementDefAttributeData.randomValue[1]
|
|
local maxValue = ElementDefAttributeData.randomValue[2] + GetEntryLvBonus(PlayerLevel, ElementDefAttributeData.bonus)
|
|
local randomElementDefAttributeValue = rng:NextInteger(minValue, maxValue)
|
|
|
|
local AttributeData = Utils:GetIdDataFromJson(JsonAttributes, newElementDefId)
|
|
ResultData.elementDef[AttributeData.name] = randomElementDefAttributeValue
|
|
end
|
|
end
|
|
|
|
-- 随机生成技能槽位数量
|
|
local AbilityProxy = require(ServerStorage.Proxy.AbilityProxy)
|
|
|
|
local maxAbilityNumber = PlayerInfoProxy:GetPlayerInfo(Player).abilityNumber or 0
|
|
local abilityNumber = rng:NextInteger(0, maxAbilityNumber)
|
|
ResultData.maxAbilityNumber = abilityNumber
|
|
if abilityNumber > 0 then
|
|
local spawnAbilitiesId = {}
|
|
for i = 1, abilityNumber do
|
|
local newAbilityId = AbilityProxy:GetRandomAbilityId(spawnAbilitiesId)
|
|
table.insert(spawnAbilitiesId, newAbilityId)
|
|
local newAbilityData, newAbilityInstance = AbilityProxy:AddAbility(Player, newAbilityId)
|
|
AbilityProxy:WearAbility(Player, newAbilityData.id, UniqueId)
|
|
end
|
|
end
|
|
|
|
-- 随机生成宝石数量
|
|
local GemProxy = require(ServerStorage.Proxy.GemProxy)
|
|
local maxGemNumber = PlayerInfoProxy:GetPlayerInfo(Player).gemNumber or 0
|
|
local gemNumber = rng:NextInteger(0, maxGemNumber)
|
|
ResultData.maxGemNumber = gemNumber
|
|
if gemNumber > 0 then
|
|
local spawnGemsId = {}
|
|
for i = 1, gemNumber do
|
|
local newGemId = GemProxy:GetRandomGemId(spawnGemsId)
|
|
table.insert(spawnGemsId, newGemId)
|
|
local newGemData, newGemInstance = GemProxy:AddGem(Player, newGemId)
|
|
GemProxy:WearGem(Player, newGemData.id, UniqueId)
|
|
end
|
|
end
|
|
|
|
------------------------------------------------------------
|
|
|
|
ArchiveProxy.pData[Player.UserId][STORE_NAME][UniqueId] = ResultData
|
|
print(ArchiveProxy.pData[Player.UserId][STORE_NAME])
|
|
Utils:CreateDataInstance(Player, UniqueId, ResultData, GetPlayerEquipmentFolder(Player))
|
|
|
|
-- 添加图鉴记录
|
|
local BookProxy = require(ServerStorage.Proxy.BookProxy)
|
|
BookProxy:AddBook(Player, EquipmentId, UniqueId)
|
|
end
|
|
|
|
-- 回收装备
|
|
function EquipmentProxy:RecycleEquipment(Player: Player, EquipmentId: number)
|
|
local pData = Utils:GetPlayerDataFolder(Player)
|
|
if not pData then return end
|
|
|
|
local EquipmentData = ArchiveProxy.pData[Player.UserId][STORE_NAME][EquipmentId]
|
|
if not EquipmentData then return end
|
|
|
|
-- 根据对应功能模块进行对应回收
|
|
local AbilityProxy = require(ServerStorage.Proxy.AbilityProxy)
|
|
AbilityProxy:RecycleAbility(Player, EquipmentData.id)
|
|
local GemProxy = require(ServerStorage.Proxy.GemProxy)
|
|
GemProxy:RecycleGem(Player, EquipmentData.id)
|
|
|
|
-- 回收装备返回金币
|
|
-- TODO:处理关卡金币产出加成和词条加成
|
|
PlayerInfoProxy:ChangeItem(Player, 1, EquipmentData.recycle)
|
|
|
|
ArchiveProxy.pData[Player.UserId][EquipmentId] = nil
|
|
local EquipmentInstance = GetPlayerEquipmentFolder(Player):FindFirstChild(EquipmentId)
|
|
if EquipmentInstance then
|
|
EquipmentInstance:Destroy()
|
|
end
|
|
end
|
|
|
|
-- 穿戴装备
|
|
function EquipmentProxy:WearEquipment(Player: Player, EquipmentId: number, Slot: number)
|
|
local pData = Utils:GetPlayerDataFolder(Player)
|
|
if not pData then return end
|
|
|
|
-- TODO :穿戴装备时再生成模型
|
|
-- 查看槽位数量是否超出
|
|
local PlayerInfoData = PlayerInfoProxy:GetPlayerInfo(Player)
|
|
-- 没升级是没有键值对的,所以做了个括号简单判断
|
|
if Slot > (PlayerInfoData.AttributesUpgrade.wearingNumber or 1) then
|
|
RE_PlayerTip:FireClient(Player, '穿戴装备槽位超出')
|
|
return
|
|
end
|
|
|
|
-- 查看该槽位是否穿戴装备,穿戴就返回
|
|
for _, EquipmentData in ArchiveProxy.pData[Player.UserId][STORE_NAME] do
|
|
if EquipmentData.wearing == Slot then
|
|
RE_PlayerTip:FireClient(Player, '该槽位已穿戴装备')
|
|
return
|
|
end
|
|
end
|
|
|
|
-- 穿戴装备
|
|
local EquipmentData = ArchiveProxy.pData[Player.UserId][STORE_NAME][EquipmentId]
|
|
if not EquipmentData then return end
|
|
ChangeValue(Player, EquipmentId, "wearing", Slot)
|
|
|
|
-- 更新玩家数据
|
|
PlayerFightProxy:UpdatePlayerFightData(Player)
|
|
end
|
|
|
|
-- 卸下装备
|
|
function EquipmentProxy:UnwearEquipment(Player: Player, EquipmentId: number)
|
|
local pData = Utils:GetPlayerDataFolder(Player)
|
|
if not pData then return end
|
|
|
|
-- TODO :卸下装备时再关闭模型
|
|
|
|
-- 卸下装备
|
|
local EquipmentData = ArchiveProxy.pData[Player.UserId][STORE_NAME][EquipmentId]
|
|
if not EquipmentData then return end
|
|
ChangeValue(Player, EquipmentId, "wearing", 0)
|
|
|
|
-- 更新玩家数据
|
|
PlayerFightProxy:UpdatePlayerFightData(Player)
|
|
end
|
|
|
|
-- 获取穿戴中的装备UniqueId
|
|
function EquipmentProxy:GetPlayerWearingEquipmentUniqueId(Player: Player)
|
|
local wearingEquipmentUniqueId = {}
|
|
-- 穿戴中的填入
|
|
for _, EquipmentData in ArchiveProxy.pData[Player.UserId][STORE_NAME] do
|
|
if EquipmentData.wearing > 0 then
|
|
wearingEquipmentUniqueId[EquipmentData.wearing] = EquipmentData.id
|
|
end
|
|
end
|
|
|
|
-- 补全空缺没填进去的槽位
|
|
local wearingNumber = PlayerInfoProxy:GetPlayerAttributesUpgrade(Player, "wearingNumber")
|
|
if wearingNumber <= 0 then return wearingEquipmentUniqueId end
|
|
for i = 1, wearingNumber do
|
|
if not wearingEquipmentUniqueId[i] then wearingEquipmentUniqueId[i] = 0 end
|
|
end
|
|
return wearingEquipmentUniqueId
|
|
end
|
|
|
|
-- 获取装备属性(汇总,不进行最终属性计算)
|
|
function EquipmentProxy:GetPlayerAttributes(Player: Player)
|
|
local AttributesData = {}
|
|
for _, EquipmentData in ArchiveProxy.pData[Player.UserId][STORE_NAME] do
|
|
if EquipmentData.wearing > 0 then
|
|
-- 增加装备基础属性
|
|
for AttributeName, AttributeValue in EquipmentData.attributes do
|
|
if AttributeName == "atkSpeed" then
|
|
if EquipmentData.wearing == 1 then
|
|
Utils:TableSafeAddValue(AttributesData, AttributeName, AttributeValue)
|
|
end
|
|
else
|
|
Utils:TableSafeAddValue(AttributesData, AttributeName, AttributeValue)
|
|
end
|
|
end
|
|
|
|
-- 增加装备额外属性
|
|
Utils:TableSafeAddTableValue(AttributesData, EquipmentData.exAttributes)
|
|
-- 增加装备元素属性
|
|
Utils:TableSafeAddTableValue(AttributesData, EquipmentData.elements)
|
|
-- 增加装备元素抗性
|
|
Utils:TableSafeAddTableValue(AttributesData, EquipmentData.elementDef)
|
|
end
|
|
end
|
|
return AttributesData
|
|
end
|
|
|
|
-- 获取装备数据
|
|
function EquipmentProxy:GetEquipmentData(Player: Player, EquipmentUniqueId: number)
|
|
local EquipmentData = ArchiveProxy.pData[Player.UserId][STORE_NAME][EquipmentUniqueId]
|
|
return EquipmentData
|
|
end
|
|
|
|
function EquipmentProxy:OnPlayerRemoving(Player: Player)
|
|
|
|
end
|
|
|
|
|
|
ReplicatedStorage.Remotes.PlayerRemoving.Event:Connect(function(PlayerUserId: string)
|
|
EquipmentProxy:OnPlayerRemoving(PlayerUserId)
|
|
end)
|
|
RE_WearEquipment.OnServerEvent:Connect(function(Player: Player, EquipmentUniqueId: number, SlotId: number, Unwear: boolean?)
|
|
if Unwear then
|
|
EquipmentProxy:UnwearEquipment(Player, EquipmentUniqueId)
|
|
else
|
|
print(Player, EquipmentUniqueId, SlotId)
|
|
EquipmentProxy:WearEquipment(Player, EquipmentUniqueId, SlotId)
|
|
end
|
|
end)
|
|
|
|
|
|
return EquipmentProxy |