This commit is contained in:
Ggafrik 2025-07-15 01:12:05 +08:00
parent 083331454f
commit 9b6a1e3a6d
29 changed files with 680 additions and 58 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
excel/global.xlsx Normal file

Binary file not shown.

Binary file not shown.

BIN
excel/language.xlsx Normal file

Binary file not shown.

Binary file not shown.

View File

@ -4,24 +4,26 @@
{"id":3,"type":1,"effectAttribute":"swordAtk","battleValue":[1,10]},
{"id":4,"type":2,"effectAttribute":"swordWearBase","battleValue":[1,10]},
{"id":5,"type":2,"effectAttribute":"swordWearSpe","battleValue":[1,10]},
{"id":6,"type":1,"effectAttribute":"fireAtk","battleValue":[1,10]},
{"id":7,"type":1,"effectAttribute":"iceAtk","battleValue":[1,10]},
{"id":8,"type":1,"effectAttribute":"lightAtk","battleValue":[1,10]},
{"id":9,"type":1,"effectAttribute":"shadowAtk","battleValue":[1,10]},
{"id":6,"type":2,"effectAttribute":"fireAtk","battleValue":[1,10]},
{"id":7,"type":2,"effectAttribute":"iceAtk","battleValue":[1,10]},
{"id":8,"type":2,"effectAttribute":"lightAtk","battleValue":[1,10]},
{"id":9,"type":2,"effectAttribute":"shadowAtk","battleValue":[1,10]},
{"id":10,"type":1,"effectAttribute":"fireDef","battleValue":[1,10]},
{"id":11,"type":1,"effectAttribute":"iceDef","battleValue":[1,10]},
{"id":12,"type":1,"effectAttribute":"lightDef","battleValue":[1,10]},
{"id":13,"type":1,"effectAttribute":"shadowDef","battleValue":[1,10]},
{"id":14,"type":2,"effectAttribute":"attackRate","battleValue":[1,10]},
{"id":15,"type":2,"effectAttribute":"hpRate","battleValue":[1,10]},
{"id":16,"type":2,"effectAttribute":"atkSpeed","battleValue":[1,10]},
{"id":20,"type":2,"effectAttribute":"critRate","battleValue":[1,10]},
{"id":21,"type":2,"effectAttribute":"critDamageRate","battleValue":[1,10]},
{"id":22,"type":2,"effectAttribute":"atkSpeedRate","battleValue":[1,10]},
{"id":23,"type":2,"effectAttribute":"cdRate","battleValue":[1,10]},
{"id":24,"type":2,"effectAttribute":"hpRate","battleValue":[1,10]},
{"id":25,"type":1,"effectAttribute":"mpBonus","battleValue":[1,10]},
{"id":26,"type":2,"effectAttribute":"mpReduceRate","battleValue":[1,10]},
{"id":27,"type":1,"effectAttribute":"mpRecoverBonus","battleValue":[1,10]},
{"id":28,"type":2,"effectAttribute":"vampireRate","battleValue":[1,10]},
{"id":29,"type":2,"effectAttribute":"coinBonus","battleValue":[1,10]},
{"id":24,"type":1,"effectAttribute":"mpBonus","battleValue":[1,10]},
{"id":25,"type":2,"effectAttribute":"mpReduceRate","battleValue":[1,10]},
{"id":26,"type":1,"effectAttribute":"mpRecoverBonus","battleValue":[1,10]},
{"id":27,"type":2,"effectAttribute":"vampireRate","battleValue":[1,10]},
{"id":28,"type":2,"effectAttribute":"coinBonus","battleValue":[1,10]},
{"id":50,"type":1,"effectAttribute":"wearNumber","battleValue":[1,10]},
{"id":51,"type":1,"effectAttribute":"skillNumber","battleValue":[1,10]},
{"id":52,"type":1,"effectAttribute":"extraAttributeNumber","battleValue":[1,10]},

View File

@ -5,7 +5,7 @@
{"id":4,"type":1,"effectAttribute":"swordWearBase","cost":[1,10,20],"lvAdd":[10,20],"battleValueLimit":[5,20],"maxLv":null},
{"id":5,"type":1,"effectAttribute":"swordWearSpe","cost":[1,10,20],"lvAdd":[10,20],"battleValueLimit":[5,20],"maxLv":null},
{"id":10,"type":2,"effectAttribute":"wearNumber","cost":[1,10,20],"lvAdd":[1,1],"battleValueLimit":[5,20],"maxLv":4},
{"id":11,"type":2,"effectAttribute":"skillNumber","cost":[1,10,20],"lvAdd":[1,1],"battleValueLimit":[5,20],"maxLv":3},
{"id":11,"type":2,"effectAttribute":"abilityNumber","cost":[1,10,20],"lvAdd":[1,1],"battleValueLimit":[5,20],"maxLv":3},
{"id":12,"type":2,"effectAttribute":"extraAttributeNumber","cost":[1,10,20],"lvAdd":[1,1],"battleValueLimit":[5,20],"maxLv":3},
{"id":13,"type":2,"effectAttribute":"elementNumber","cost":[1,10,20],"lvAdd":[1,1],"battleValueLimit":[5,20],"maxLv":3},
{"id":14,"type":2,"effectAttribute":"elementDefNumber","cost":[1,10,20],"lvAdd":[1,1],"battleValueLimit":[5,20],"maxLv":3},

View File

@ -1,3 +1,3 @@
[
{"id":1,"name":1,"attack":10,"hp":100,"walkSpeed":10,"attackSpeed":2}
{"id":1,"name":1,"attack":10,"hp":100,"walkSpeed":10,"atkSpeed":1}
]

View File

@ -1,3 +1,3 @@
[
{"id":1,"type":1,"name":1,"attributes":[1,20,2,20],"recycle":10}
{"id":1,"type":1,"name":1,"attributes":[14,200,10,15,200,10,16,100,0],"recycle":10}
]

View File

@ -1,12 +1,20 @@
[
{"id":20,"value":[10,20]},
{"id":21,"value":[10,20]},
{"id":22,"value":[10,20]},
{"id":23,"value":[10,20]},
{"id":24,"value":[10,20]},
{"id":25,"value":[10,20]},
{"id":26,"value":[10,20]},
{"id":27,"value":[10,20]},
{"id":28,"value":[10,20]},
{"id":29,"value":[10,20]}
{"id":20,"type":1,"randomValue":[10,20],"lvBonus":[1,2]},
{"id":21,"type":1,"randomValue":[10,20],"lvBonus":[1,2]},
{"id":22,"type":1,"randomValue":[10,20],"lvBonus":[1,2]},
{"id":23,"type":1,"randomValue":[10,20],"lvBonus":[1,2]},
{"id":24,"type":1,"randomValue":[10,20],"lvBonus":[1,2]},
{"id":25,"type":1,"randomValue":[10,20],"lvBonus":[3,2,10]},
{"id":26,"type":1,"randomValue":[10,20],"lvBonus":[5,2,10]},
{"id":27,"type":1,"randomValue":[10,20],"lvBonus":[5,2,10]},
{"id":28,"type":1,"randomValue":[10,20],"lvBonus":[1,2,10]},
{"id":29,"type":1,"randomValue":[10,20],"lvBonus":[1,2]},
{"id":6,"type":2,"randomValue":[10,20],"lvBonus":[1,2]},
{"id":7,"type":2,"randomValue":[10,20],"lvBonus":[1,2]},
{"id":8,"type":2,"randomValue":[10,20],"lvBonus":[1,2]},
{"id":9,"type":2,"randomValue":[10,20],"lvBonus":[1,2]},
{"id":10,"type":3,"randomValue":[10,20],"lvBonus":[1,2]},
{"id":11,"type":3,"randomValue":[10,20],"lvBonus":[1,2]},
{"id":12,"type":3,"randomValue":[10,20],"lvBonus":[1,2]},
{"id":13,"type":3,"randomValue":[10,20],"lvBonus":[1,2]}
]

View File

@ -0,0 +1,17 @@
[
{"id":1,"cost":[2,20]},
{"id":2,"cost":[2,30]},
{"id":3,"cost":[2,40]},
{"id":4,"cost":[2,50]},
{"id":5,"cost":[2,60]},
{"id":6,"cost":[2,70]},
{"id":7,"cost":[2,80]},
{"id":8,"cost":[2,90]},
{"id":9,"cost":[2,100]},
{"id":10,"cost":[2,110]},
{"id":11,"cost":[2,120]},
{"id":12,"cost":[2,130]},
{"id":13,"cost":[2,140]},
{"id":14,"cost":[2,150]},
{"id":15,"cost":[2,160]}
]

View File

@ -1,6 +1,7 @@
[
{"id":1,"type":1,"typeArgs":[],"quality":4,"iconId":1,"nameId":10001,"textId":20001,"buyPrice":[],"sellPrice":[],"use":[],"showPackage":null},
{"id":2,"type":1,"typeArgs":[],"quality":4,"iconId":2,"nameId":10002,"textId":20002,"buyPrice":[],"sellPrice":[],"use":[],"showPackage":null},
{"id":3,"type":1,"typeArgs":[],"quality":2,"iconId":3,"nameId":10003,"textId":20003,"buyPrice":[],"sellPrice":[],"use":[],"showPackage":null},
{"id":11,"type":1,"typeArgs":[],"quality":1,"iconId":11,"nameId":10011,"textId":20011,"buyPrice":[],"sellPrice":[],"use":[],"showPackage":null},
{"id":10000,"type":4,"typeArgs":[],"quality":1,"iconId":12,"nameId":20000,"textId":30000,"buyPrice":[11,10],"sellPrice":[11,10],"use":[],"showPackage":null},
{"id":10001,"type":4,"typeArgs":[],"quality":2,"iconId":13,"nameId":20001,"textId":30001,"buyPrice":[11,20],"sellPrice":[11,20],"use":[],"showPackage":null},

View File

@ -0,0 +1,62 @@
[
{"id":1,"exp":10},
{"id":2,"exp":20},
{"id":3,"exp":30},
{"id":4,"exp":40},
{"id":5,"exp":50},
{"id":6,"exp":60},
{"id":7,"exp":70},
{"id":8,"exp":80},
{"id":9,"exp":90},
{"id":10,"exp":100},
{"id":11,"exp":110},
{"id":12,"exp":120},
{"id":13,"exp":130},
{"id":14,"exp":140},
{"id":15,"exp":150},
{"id":16,"exp":160},
{"id":17,"exp":170},
{"id":18,"exp":180},
{"id":19,"exp":190},
{"id":20,"exp":200},
{"id":21,"exp":210},
{"id":22,"exp":220},
{"id":23,"exp":230},
{"id":24,"exp":240},
{"id":25,"exp":250},
{"id":26,"exp":260},
{"id":27,"exp":270},
{"id":28,"exp":280},
{"id":29,"exp":290},
{"id":30,"exp":300},
{"id":31,"exp":310},
{"id":32,"exp":320},
{"id":33,"exp":330},
{"id":34,"exp":340},
{"id":35,"exp":350},
{"id":36,"exp":360},
{"id":37,"exp":370},
{"id":38,"exp":380},
{"id":39,"exp":390},
{"id":40,"exp":400},
{"id":41,"exp":410},
{"id":42,"exp":420},
{"id":43,"exp":430},
{"id":44,"exp":440},
{"id":45,"exp":450},
{"id":46,"exp":460},
{"id":47,"exp":470},
{"id":48,"exp":480},
{"id":49,"exp":490},
{"id":50,"exp":500},
{"id":51,"exp":510},
{"id":52,"exp":520},
{"id":53,"exp":530},
{"id":54,"exp":540},
{"id":55,"exp":550},
{"id":56,"exp":560},
{"id":57,"exp":570},
{"id":58,"exp":580},
{"id":59,"exp":590},
{"id":60,"exp":600}
]

View File

@ -0,0 +1,3 @@
[
{"id":1,"key":"quality_bonus","intValue":null,"stringValue":null,"intArray":[100,125,150,200,275,375]}
]

View File

@ -0,0 +1,7 @@
[
{"id":1,"timeId":1,"rewards":[2,100]},
{"id":2,"timeId":1,"rewards":[2,100]},
{"id":3,"timeId":1,"rewards":[2,100]},
{"id":10,"timeId":1000,"rewards":[6,15]},
{"id":11,"timeId":1003,"rewards":[6,5]}
]

View File

@ -26,7 +26,9 @@ end
function Utils:SetAttributesList(Object: Instance, Attributes: table)
for Attribute, Value in Attributes do
Object:SetAttribute(Attribute, Value)
if type(Value) ~= "table" then
Object:SetAttribute(Attribute, Value)
end
end
end
@ -95,6 +97,26 @@ function Utils:GetRandomIdFromJsonWithType(JsonData: table, Type: number, Except
return randomId
end
-- 随机获取权重Index
function Utils:GetRandomWeightIndex(WeightTable: table)
local totalWeight = 0
for _, weight in ipairs(WeightTable) do
totalWeight = totalWeight + weight
end
if totalWeight == 0 then
return nil -- 没有有效权重
end
local rng = Random.new()
local rand = rng:NextInteger(1, totalWeight)
local sum = 0
for i, weight in ipairs(WeightTable) do
sum = sum + weight
if rand <= sum then
return i
end
end
end
function Utils:GetMaxIdFromJson(JsonData: table)
local maxId = 0
for _, item in ipairs(JsonData) do
@ -138,9 +160,17 @@ function Utils:CreateDataInstance(Player: Player, UniqueId: number, EquipmentDat
end
local Config = Instance.new("Configuration")
Config.Name = UniqueId
-- TODO: 子表数据也要处理
Utils:SetAttributesList(Config, EquipmentData)
Config.Parent = Folder
for KeyName, Value in EquipmentData do
if type(Value) == "table" then
local newKeyConfig = Instance.new("Configuration")
newKeyConfig.Name = KeyName
Utils:SetAttributesList(newKeyConfig, Value)
newKeyConfig.Parent = Config
end
end
return Config
end
@ -165,6 +195,30 @@ function Utils:DeepCopyTable(t: table)
end
return newTable
end
-- 合并表(加法合并)
function Utils:MergeTable(t1: table, t2: table)
for k, v in pairs(t2) do
if type(v) == "number" then
t1[k] = t1[k] + v
end
end
return t1
end
-- 给表增加keyvalue加法计算
function Utils:TableSafeAddValue(AttributesData: table, AttributeName: string, AttributeValue: number)
AttributesData[AttributeName] = (AttributesData[AttributeName] or 0) + AttributeValue
end
-- 给表增加keyvalue加法计算按第二个参数表的内容增加
function Utils:TableSafeAddTableValue(AttributesData: table, AddTableValue: table)
for AttributeName, AttributeValue in AddTableValue do
AttributesData[AttributeName] = (AttributesData[AttributeName] or 0) + AttributeValue
end
end
--------------------------------------------------------------------------------
return Utils

View File

@ -94,6 +94,9 @@ local function OnPlayerAdded(Player: Player)
Proxies.PlayerInfoProxy:InitPlayer(Player)
Proxies.MobsProxy:InitPlayer(Player)
Proxies.LevelProxy:InitPlayer(Player)
Proxies.AbilityProxy:InitPlayer(Player)
Proxies.GemProxy:InitPlayer(Player)
Proxies.BookProxy:InitPlayer(Player)
Proxies.PlayerFightProxy:InitPlayer(Player)
end

View File

@ -27,6 +27,7 @@ function SwordWave:Init(PlayerAI, Character: TypeList.Character, Player: Player)
self.Player = Player
setmetatable(self, SwordWave)
self.OrgCooldown = COOLDOWN
self:StartCooldownTask()
-- 客户端表现
self:SendPerformanceEvent("Init", self.Player, script.Name, true, {})

View File

@ -1,4 +1,4 @@
-- 玩家通用信息
-- 技能系统(存储用)
local AbilityProxy = {}
--> Services
@ -168,7 +168,16 @@ function AbilityProxy:WearAbility(Player: Player, AbilityUniqueId: number, Equip
end
end
-- TODO: 获取这个装备最多穿几个技能,穿戴数量>=穿戴上限就返回
if EquipmentData.abilitySlotNumber <= 0 then
RE_PlayerTip:FireClient(Player, "装备没有技能槽位")
return
end
-- 检查槽位数量是否充足
if wearingCount >= EquipmentData.abilitySlotNumber then
RE_PlayerTip:FireClient(Player, "装备已满技能槽位")
return
end
-- 穿戴技能
UniqueData.wearing = EquipmentUniqueId
@ -211,6 +220,22 @@ function AbilityProxy:GetRandomAbilityId(ExceptIdList: table)
return candidateIds[idx]
end
-- 获取穿戴中的技能
function AbilityProxy:GetPlayerWearingAbilityData(Player: Player)
local wearingAbilityUniqueId = {}
local behaviourNames = {}
-- 穿戴中的填入
local EquipmentProxy = require(ServerStorage.Proxy.EquipmentProxy)
local wearingEquipments = EquipmentProxy:GetPlayerWearingEquipmentUniqueId(Player)
for _, AbilityData in ArchiveProxy.pData[Player.UserId][STORE_NAME].Ability do
if AbilityData.wearing > 0 and table.find(wearingEquipments, AbilityData.wearing) then
table.insert(wearingAbilityUniqueId, AbilityData.id)
local AbilityData = Utils:GetIdDataFromJson(JsonAbility, AbilityData.orgId)
table.insert(behaviourNames, AbilityData.behaviourName)
end
end
return wearingAbilityUniqueId, behaviourNames
end
--------------------------------------------------------------------------------
-- 获取技能属性

View File

@ -0,0 +1,126 @@
-- 图鉴系统
local BookProxy = {}
--> Services
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
--> Variables
local Utils = require(ReplicatedStorage.Tools.Utils)
local ArchiveProxy = require(ServerStorage.Proxy.ArchiveProxy)
--> Json
local JsonItem = require(ReplicatedStorage.Json.ItemProp)
local JsonGem = require(ReplicatedStorage.Json.Gem)
--> Events
local RE_PlayerTip = ReplicatedStorage.Events.RE_PlayerTip
local RE_UpgradeAttributes = ReplicatedStorage.Events.RE_UpgradeAttributes
--> Constants
local STORE_NAME = "Book"
--------------------------------------------------------------------------------
-- 获取玩家信息文件夹
local function GetPlayerBookFolder(Player: Player)
local pData = Utils:GetPlayerDataFolder(Player)
if not pData then return end
local BookFolder = pData:FindFirstChild("Book")
return BookFolder
end
--------------------------------------------------------------------------------
-- 初始化玩家
function BookProxy:InitPlayer(Player: Player)
local pData = Utils:GetPlayerDataFolder(Player)
if not pData then return end
local BookFolder = Utils:CreateFolder("Book", pData)
-- 新玩家数据初始化
if not ArchiveProxy.pData[Player.UserId][STORE_NAME] then
ArchiveProxy.pData[Player.UserId][STORE_NAME] = {}
ArchiveProxy.pData[Player.UserId][STORE_NAME].Books = {}
end
-- 创建玩家信息实例
for BookId, BookData in ArchiveProxy.pData[Player.UserId][STORE_NAME].Books do
Utils:CreateDataInstance(Player, BookId, BookData, BookFolder)
end
end
--------------------------------------------------------------------------------
-- 添加图鉴记录
function BookProxy:AddBook(Player: Player, BookId: number, UniqueEquipmentId: number)
local pData = Utils:GetPlayerDataFolder(Player)
if not pData then return end
local BookFolder = GetPlayerBookFolder(Player)
if not BookFolder then return end
local EquipmentProxy = require(ServerStorage.Proxy.EquipmentProxy)
local EquipmentData = EquipmentProxy:GetEquipmentData(Player, UniqueEquipmentId)
if not EquipmentData then return end
local orgBookData = ArchiveProxy.pData[Player.UserId][STORE_NAME].Books[BookId]
-- 检查是否已经存在
if orgBookData then
-- 图鉴没原先品质高就返回
if orgBookData.quality > EquipmentData.quality then return end
else
-- 原来没有时解锁图鉴
BookProxy:UnlockBook(Player, BookId)
end
-- 添加图鉴记录
ArchiveProxy.pData[Player.UserId][STORE_NAME].Books[BookId] = {
timestamp = tick(),
quality = EquipmentData.quality,
}
local bookInstance = BookFolder:FindFirstChild(BookId)
bookInstance:SetAttribute("quality", ArchiveProxy.pData[Player.UserId][STORE_NAME].Books[BookId].quality)
bookInstance:SetAttribute("timestamp", ArchiveProxy.pData[Player.UserId][STORE_NAME].Books[BookId].timestamp)
end
-- 解锁图鉴
function BookProxy:UnlockBook(Player: Player, BookId: number)
local pData = Utils:GetPlayerDataFolder(Player)
if not pData then return end
local BookFolder = GetPlayerBookFolder(Player)
if not BookFolder then return end
-- 添加图鉴记录
ArchiveProxy.pData[Player.UserId][STORE_NAME].Books[BookId] = {
timestamp = 0,
quality = 0,
}
Utils:CreateDataInstance(Player, BookId, ArchiveProxy.pData[Player.UserId][STORE_NAME].Books[BookId], BookFolder)
end
-- 检查是否解锁对应图鉴
function BookProxy:IsBookUnlocked(Player: Player, BookId: number)
return ArchiveProxy.pData[Player.UserId][STORE_NAME].Books[BookId] ~= nil
end
--------------------------------------------------------------------------------
-- TODO: 获取玩家属性(之后要是图鉴加属性就在这)
function BookProxy:GetPlayerAttributes(Player: Player)
local attributesList = {}
return attributesList
end
--------------------------------------------------------------------------------
function BookProxy:OnPlayerRemoving(Player: Player)
end
ReplicatedStorage.Remotes.PlayerRemoving.Event:Connect(function(Player: Player)
BookProxy:OnPlayerRemoving(Player)
end)
return BookProxy

View File

@ -9,11 +9,16 @@ local ServerStorage = game:GetService("ServerStorage")
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
--> Constants
local STORE_NAME = "Equipment"
@ -28,6 +33,22 @@ local function GetPlayerEquipmentFolder(Player: Player)
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
--------------------------------------------------------------------------------
-- 初始化玩家
@ -71,11 +92,35 @@ function EquipmentProxy:AddEquipment(Player: Player, EquipmentId: number)
-- 到时候记录穿戴槽位
ResultData.wearing = 0
-- TODO: 其他随机词条内容添加在下面
-- 随机生成额外属性数量
-- 随机生成总变量
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)
ResultData.quality = quality
-- 生成装备基础词条(固定的)
ResultData.attributes = {}
for i = 1, EquipmentData.attributesNumber, 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.name] = qualityEffectValue
end
-- TODO: 其他随机词条内容添加在下面
-- 随机生成额外属性数量
local maxExAttributeNumber = PlayerInfoProxy:GetPlayerInfo(Player).exAttributeNumber or 0
local exAttributeNumber = rng:NextInteger(0, maxExAttributeNumber)
ResultData.maxExAttributeNumber = exAttributeNumber
@ -87,7 +132,9 @@ function EquipmentProxy:AddEquipment(Player: Player, EquipmentId: number)
table.insert(spawnExAttributesId, newExAttributeId)
local ExAttributeData = Utils:GetIdDataFromJson(JsonExAttributes, newExAttributeId)
local randomExAttributeValue = rng:NextInteger(ExAttributeData.randomValue[1], ExAttributeData.randomValue[2])
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
@ -106,7 +153,9 @@ function EquipmentProxy:AddEquipment(Player: Player, EquipmentId: number)
table.insert(spawnElementsId, newElementAttributeId)
local ElementAttributeData = Utils:GetIdDataFromJson(JsonExAttributes, newElementAttributeId)
local randomElementAttributeValue = rng:NextInteger(ElementAttributeData.randomValue[1], ElementAttributeData.randomValue[2])
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
@ -125,7 +174,9 @@ function EquipmentProxy:AddEquipment(Player: Player, EquipmentId: number)
table.insert(spawnElementDefId, newElementDefId)
local ElementDefAttributeData = Utils:GetIdDataFromJson(JsonExAttributes, newElementDefId)
local randomElementDefAttributeValue = rng:NextInteger(ElementDefAttributeData.randomValue[1], ElementDefAttributeData.randomValue[2])
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
@ -167,6 +218,10 @@ function EquipmentProxy:AddEquipment(Player: Player, EquipmentId: number)
ArchiveProxy.pData[Player.UserId][UniqueId] = ResultData
Utils:CreateDataInstance(Player, UniqueId, ResultData, GetPlayerEquipmentFolder(Player))
-- 添加图鉴记录
local BookProxy = require(ServerStorage.Proxy.BookProxy)
BookProxy:AddBook(Player, EquipmentId, UniqueId)
end
-- 回收装备
@ -177,9 +232,14 @@ function EquipmentProxy:RecycleEquipment(Player: Player, EquipmentId: number)
local EquipmentData = ArchiveProxy.pData[Player.UserId][STORE_NAME][EquipmentId]
if not EquipmentData then return end
-- TODO根据对应功能模块生成对应技能
-- 根据对应功能模块进行对应回收
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
@ -190,12 +250,95 @@ function EquipmentProxy:RecycleEquipment(Player: Player, EquipmentId: number)
end
-- 穿戴装备
function EquipmentProxy:WearEquipment(Player: Player, EquipmentId: number)
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.wearingNumber 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
-- 获取装备数据

View File

@ -1,4 +1,4 @@
-- 玩家通用信息
-- 宝石系统
local GemProxy = {}
--> Services
@ -157,7 +157,25 @@ function GemProxy:WearGem(Player: Player, GemUniqueId: number, EquipmentUniqueId
return
end
-- TODO: 检查对应装备是否有充足的宝石槽位
-- 检查对应装备是否有充足的宝石槽位
local EquipmentData = EquipmentProxy:GetEquipmentData(Player, EquipmentUniqueId)
if not EquipmentData then warn('无法获取装备数据: ' , Player.Name, EquipmentUniqueId) return end
if EquipmentData.gemSlotNumber <= 0 then
RE_PlayerTip:FireClient(Player, "装备没有宝石槽位")
return
end
-- 检查槽位数量是否充足
local wearingGemNumber = 0
for _, gemData in ArchiveProxy.pData[Player.UserId][STORE_NAME].Gems do
if gemData.wearing == EquipmentUniqueId then
wearingGemNumber += 1
end
end
if wearingGemNumber >= EquipmentData.gemSlotNumber then
RE_PlayerTip:FireClient(Player, "装备已满宝石槽位")
return
end
-- 穿戴
GemData.wearing = EquipmentUniqueId
@ -202,14 +220,14 @@ end
function GemProxy:GetPlayerGemWearingAttributes(Player: Player)
if not Player then warn('获取玩家属性失败: ', Player.Name) return end
local playerGems = ArchiveProxy.pData[Player.UserId][STORE_NAME].Gems
local EquipmentProxy = require(ServerStorage.Proxy.EquipmentProxy)
local wearingEquipments = EquipmentProxy:GetPlayerWearingEquipmentUniqueId(Player)
local attributes = {}
for _, gemData in playerGems do
if gemData.wearing ~= 0 then
if attributes[gemData.effectAttribute] then
attributes[gemData.effectAttribute] = attributes[gemData.effectAttribute] + gemData.attributeValue
else
attributes[gemData.effectAttribute] = gemData.attributeValue
end
if gemData.wearing ~= 0 and table.find(wearingEquipments, gemData.wearing) then
Utils:TableSafeAddValue(attributes, gemData.effectAttribute, gemData.attributeValue)
end
end
return attributes

View File

@ -88,6 +88,8 @@ end
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 then warn("LevelProxy ChangeValue", Player.UserId, Folder.Name, LevelKey, LevelValue) return end
if table.find(EXCEPT_KEY, LevelKey) then return end
local ValueInstance = Folder:FindFirstChild(LevelKey)
if not ValueInstance then warn("ValueInstance not found", LevelKey) return end
@ -99,7 +101,7 @@ local function ChangeValue(Player: Player, Folder: Instance, LevelKey: string, L
end
storeTable[LevelKey] = LevelValue
if not table.find(EXCEPT_KEY, LevelKey) then ValueInstance.Value = LevelValue end
ValueInstance.Value = LevelValue
end
-- 怪物死亡,由初始化时传入
@ -249,7 +251,6 @@ function LevelProxy:ChallengeEnd(Player: Player, result: boolean)
end
-- 清除剩余怪物
print("清除剩余怪物", LevelProxy.pData[Player.UserId].Mobs)
for _, mob in LevelProxy.pData[Player.UserId].Mobs do mob:Died(true) end
LevelProxy.pData[Player.UserId].Mobs = {}

View File

@ -41,8 +41,6 @@ function LevelLoop:AutoChallenge()
print("AutoChallenge")
-- TODO: 回退有bug不能一关一关回退
-- 重置玩家状态(先临时调用角色复活,之后复杂的内容再说)
self.PlayerRole:Respawn()
local LevelFolder = game.Workspace:WaitForChild("Level"):WaitForChild(self.Player.UserId)
local ProgressFolder = LevelFolder:FindFirstChild("Progress")
@ -60,6 +58,8 @@ end
function LevelLoop:OnChallengeEnd(Player: Player, LevelId: number, result: boolean)
self.TaskAutoChallenge = task.spawn(function()
task.wait(3)
-- 重置玩家状态(先临时调用角色复活,之后复杂的内容再说)
self.PlayerRole:Respawn()
self:AutoChallenge()
end)
end

View File

@ -105,6 +105,12 @@ function PlayerAI:RemoveBehaviour(BehaviourName: string)
end
end
-- 清除所有行为
function PlayerAI:ClearAllBehaviour()
for _, behaviour in self.BehaviourList do behaviour:Destroy() end
self.BehaviourList = {}
end
-- 销毁AI
function PlayerAI:Destroy()
for _, behaviour in self.BehaviourList do behaviour:Destroy() end

View File

@ -13,6 +13,7 @@ local LevelProxy = require(ServerStorage.Proxy.LevelProxy)
--> Json
local JsonCharacter = require(ReplicatedStorage.Json.Character)
local JsonAttributes = require(ReplicatedStorage.Json.Attributes)
--> Dependencies
local LevelLoop = require(script.LevelLoop)
@ -40,14 +41,24 @@ setmetatable(PlayerRole, {__index = Character})
function PlayerRole.new(Player: Player, CharacterId: number)
local playerCharacter = WaitForCharacter(Player)
-- 获取玩家初始数据
-- 获取玩家初始数据(临时初始化使用,不是真属性配置部分)
local CharacterData = Utils:GetIdDataFromJson(JsonCharacter, CharacterId)
if not CharacterData then warn("CharacterId Data not found", CharacterId) return end
-- 补充默认没设置的属性,暂时不添加特殊属性,因为特殊属性是系统调用的,添加也没啥用
for _, AttributeData in JsonCharacter do
if AttributeData.id < 50 then
if not CharacterData[AttributeData.name] then CharacterData[AttributeData.name] = 0 end
end
end
-- 调用父类Character的new方法初始化通用属性
local self = Character.new(Player, playerCharacter, CharacterData)
setmetatable(self, PlayerRole)
self.CharacterId = CharacterId
-- 玩家放到Character目录下
playerCharacter.Parent = game.Workspace.Characters
return self
@ -63,8 +74,9 @@ function PlayerRole:Respawn()
self:ChangeState("Died", false)
self.Humanoid.WalkSpeed = self.Config.walkSpeed
self:ChangeAttributeValue("hp", self.Config.maxhp)
-- 重置玩家位置
-- TODO: 重置玩家位置
PlayerFightProxy:UpdatePlayerFightData(self.Player)
end
--------------------------------------------------------------------------------
@ -86,8 +98,9 @@ function PlayerFightProxy:InitPlayer(Player: Player)
-- 生成玩家AI
local PlayerAI = PlayerAI.new(Player, PlayerRole)
PlayerFightProxy.pData[Player.UserId].PlayerAI = PlayerAI
PlayerAI:AddBehaviour("Move")
PlayerAI:AddBehaviour("SwordWave")
-- 更新玩家战斗数据
self:UpdatePlayerFightData(Player)
end
function PlayerFightProxy:GetPlayerRole(Player: Player)
@ -95,9 +108,74 @@ function PlayerFightProxy:GetPlayerRole(Player: Player)
end
function PlayerFightProxy:GetPlayerAI(Player: Player)
print(PlayerFightProxy.pData[Player.UserId])
return PlayerFightProxy.pData[Player.UserId].PlayerAI
end
-- 更新玩家战斗数据(所有变动全部从这调用)
function PlayerFightProxy:UpdatePlayerFightData(Player: Player)
local PlayerInfoProxy = require(ServerStorage.Proxy.PlayerInfoProxy)
local EquipmentProxy = require(ServerStorage.Proxy.EquipmentProxy)
local AbilityProxy = require(ServerStorage.Proxy.AbilityProxy)
local GemProxy = require(ServerStorage.Proxy.GemProxy)
local AttributesData = {}
-- 计算角色基础属性值 + 装备属性值 + 宝石属性值,赋值属性
local PlayerInfoAttributes = PlayerInfoProxy:GetPlayerAttributes(Player)
AttributesData = Utils:MergeTable(AttributesData, PlayerInfoAttributes)
local EquipmentAttributes = EquipmentProxy:GetPlayerAttributes(Player)
AttributesData = Utils:MergeTable(AttributesData, EquipmentAttributes)
local GemAttributes = GemProxy:GetPlayerAttributes(Player)
AttributesData = Utils:MergeTable(AttributesData, GemAttributes)
-- 角色基础数据
local PlayerRole = self:GetPlayerRole(Player)
local CharacterData = Utils:GetIdDataFromJson(JsonCharacter, PlayerRole.CharacterId)
if not CharacterData then warn("CharacterId Data not found", PlayerRole.CharacterId) return end
-- 如果玩家装备的武器里面有了攻击速度属性,就不用默认的攻击属性进行配置
local ExceptAttributes = {"id", "name"}
if AttributesData.atkSpeed then table.insert(ExceptAttributes, "atkSpeed") end
for AttributeName, AttributeValue in CharacterData do
if not table.find(ExceptAttributes, AttributeName) then
Utils:TableSafeAddValue(AttributesData, AttributeName, AttributeValue)
end
end
-- 根据汇总更新玩家属性——————实际生效计算部分
local PlayerRole = self:GetPlayerRole(Player)
-- 针对百分比特殊属性直接进行计算修改
if AttributesData["hpRate"] then
AttributesData["hp"] = math.floor(AttributesData["hp"] * AttributesData["hpRate"] / 100)
end
if AttributesData["atkRate"] then
AttributesData["atk"] = math.floor(AttributesData["atk"] * AttributesData["atkRate"] / 100)
end
-- 更新玩家属性
for AttributeName, AttributeValue in AttributesData do
-- TODO这里可能涉及到战斗时更换装备的属性处理还需要再函数内部再根据剩余百分比数值变化
PlayerRole:ChangeAttributeValue(AttributeName, AttributeValue)
end
-- 根据技能添加玩家AI行为
local abilityIdList, behaviourNameList = AbilityProxy:GetPlayerWearingAbilityData(Player)
local playerAI = PlayerFightProxy:GetPlayerAI(Player)
-- TODO设置AI行为临时清除所有行为添加新的玩家行为
playerAI:ClearAllBehaviour()
for _, behaviourName in behaviourNameList do
playerAI:AddBehaviour(behaviourName)
end
playerAI:AddBehaviour("Move")
playerAI:AddBehaviour("SwordWave")
end
-- 重置玩家状态,但是不删除
function PlayerFightProxy:CleanPlayer(Player: Player)
-- 玩家角色重生

View File

@ -8,14 +8,17 @@ local ServerStorage = game:GetService("ServerStorage")
--> Variables
local Utils = require(ReplicatedStorage.Tools.Utils)
local ArchiveProxy = require(ServerStorage.Proxy.ArchiveProxy)
local BookProxy = require(ServerStorage.Proxy.BookProxy)
--> Json
local JsonPlayerLv = require(ReplicatedStorage.Json.PlayerLv)
local JsonLvUpgrade = require(ReplicatedStorage.Json.LvUpgrade)
local JsonItem = require(ReplicatedStorage.Json.ItemProp)
local JsonAttributesUpgrade = require(ReplicatedStorage.Json.AttributesUpgrade)
local JsonForge = require(ReplicatedStorage.Json.Forge)
--> Events
local RE_PlayerTip = ReplicatedStorage.Events.RE_PlayerTip
local RE_Forge = ReplicatedStorage.Events.RE_Forge
local RE_UpgradeAttributes = ReplicatedStorage.Events.RE_UpgradeAttributes
--> Constants
@ -66,7 +69,7 @@ local STATS_DATA = {
exp = {type = ENUM_STATE_TYPE.Number, value = 0},
}
-- 初始化玩家状态信息
-- 初始化玩家状态信息(采用额外添加的模式,如果没有写值,就覆盖写入)
local function ExtraAddPlayerStats(Player: Player, StatsData: table)
if not Player or not StatsData then return end
-- 如果列表中不包含信息就添加到表中
@ -94,6 +97,7 @@ function PlayerInfoProxy:InitPlayer(Player: Player)
ArchiveProxy.pData[Player.UserId][STORE_NAME].Stats = {}
ArchiveProxy.pData[Player.UserId][STORE_NAME].Items = {}
ArchiveProxy.pData[Player.UserId][STORE_NAME].AttributesUpgrade = {}
ArchiveProxy.pData[Player.UserId][STORE_NAME].Forge = 1
end
-- 放在外面是为了以后系统新增内容方便(同时不用在初始化数据是做写入了)
@ -109,6 +113,7 @@ function PlayerInfoProxy:InitPlayer(Player: Player)
for AttributeId, AttributeLv in ArchiveProxy.pData[Player.UserId][STORE_NAME].AttributesUpgrade do
CreateInfoInstance(Player, AttributesUpgradeFolder, AttributeId, "NumberValue", AttributeLv)
end
CreateInfoInstance(Player, PlayerInfoFolder, "Forge", ENUM_STATE_TYPE.Number, ArchiveProxy.pData[Player.UserId][STORE_NAME].Forge)
end
-- 获取玩家信息
@ -118,6 +123,19 @@ function PlayerInfoProxy:GetPlayerInfo(Player: Player)
return playerInfoData
end
-- 获取玩家等级
function PlayerInfoProxy:GetPlayerLevel(Player: Player)
if not Player then warn('获取玩家等级失败: ', Player.Name) return end
local playerInfoData = ArchiveProxy.pData[Player.UserId][STORE_NAME]
return playerInfoData.Stats.level
end
function PlayerInfoProxy:GetPlayerAttributesUpgrade(Player: Player, AttributeName: string)
if not Player or not AttributeName then warn('获取玩家属性升级失败: ', Player.Name, AttributeName) return end
local playerInfoData = ArchiveProxy.pData[Player.UserId][STORE_NAME]
return playerInfoData.AttributesUpgrade[AttributeName] or 0
end
-- 玩家属性升级
function PlayerInfoProxy:UpgradeAttribute(Player: Player, AttributeId: number)
if not Player or not AttributeId then warn('升级属性失败: ', Player.Name, AttributeId) return end
@ -142,7 +160,6 @@ function PlayerInfoProxy:UpgradeAttribute(Player: Player, AttributeId: number)
-- TODO 判断战力是否足够(暂无战力计算)
-- 判断是否到达等级上限
print(nowLv, attributeData["maxLv"])
if attributeData["maxLv"] ~= nil then
if nowLv >= attributeData["maxLv"] then
local tip = '升级属性失败: ' .. AttributeId .. ' 已到达等级上限'
@ -180,9 +197,9 @@ function PlayerInfoProxy:AddExp(Player: Player, Exp: number)
-- 数据变化
local currentLevel = playerInfoData.Stats.level
local maxLevel = Utils:GetMaxIdFromJson(JsonPlayerLv)
local maxLevel = Utils:GetMaxIdFromJson(JsonLvUpgrade)
if currentLevel < maxLevel then
local requireExp = Utils:GetIdDataFromJson(JsonPlayerLv, currentLevel)
local requireExp = Utils:GetIdDataFromJson(JsonLvUpgrade, currentLevel)
if playerInfoData.Stats.exp >= requireExp then
playerInfoData.Stats.level = currentLevel + 1
playerInfoData.Stats.exp = playerInfoData.Stats.exp - requireExp
@ -229,12 +246,58 @@ end
-- 获取物品数量
function PlayerInfoProxy:GetItemCount(Player: Player, ItemId: number)
if not Player or not ItemId then warn('获取物品数量失败: ' .. Player.Name .. ' ' .. ItemId) return end
if not Player or not ItemId then warn('获取物品数量失败: ' , Player.Name, ItemId) return end
local playerInfoData = ArchiveProxy.pData[Player.UserId][STORE_NAME].Items
if not playerInfoData[ItemId] then return 0 end
return playerInfoData[ItemId]
end
-- 打造装备
function PlayerInfoProxy:MakeForge(Player: Player, EquipmentId: number, Count: number)
if not Player or not EquipmentId then warn('打造装备失败: ', Player.Name,EquipmentId) return end
local PlayerInfoFolder = GetPlayerInfoFolder(Player)
if not PlayerInfoFolder then return end
-- 检查装备图鉴是否解锁
local BookProxy = require(ServerStorage.Proxy.BookProxy)
if not BookProxy:IsBookUnlocked(Player, EquipmentId) then
RE_PlayerTip:FireClient(Player, "装备图鉴未解锁")
return
end
-- 锻造数量>1判断是否到达最高锻造等级
local ForgeLv = PlayerInfoProxy:GetPlayerInfo(Player).Forge
if Count > 1 then
local MaxForgeLv = Utils:GetMaxIdFromJson(JsonForge, ForgeLv)
if ForgeLv < MaxForgeLv then
RE_PlayerTip:FireClient(Player, "锻造等级已到达最高等级")
return
end
end
-- 判断金钱是否足够
local ShouldCostMoney = Utils:GetIdDataFromJson(JsonForge, ForgeLv)["cost"][2] * Count
if not self:HasEnoughItem(Player, 1, ShouldCostMoney) then
RE_PlayerTip:FireClient(Player, "金钱不足")
return
end
-- 扣钱
self:ChangeItemCount(Player, 1, -ShouldCostMoney)
-- 生成对应装备
local EquipmentProxy = require(ServerStorage.Proxy.EquipmentProxy)
for i = 1, Count do
EquipmentProxy:AddEquipment(Player, EquipmentId)
end
-- 锻造升级
ForgeLv = ForgeLv + Count
ChangeInfoInstance(Player, PlayerInfoFolder, "Forge", ForgeLv)
-- TODO: 添加对应奖励弹窗
end
--------------------------------------------------------------------------------
-- 获取升级加点属性
@ -262,6 +325,10 @@ function PlayerInfoProxy:OnPlayerRemoving(Player: Player)
end
RE_Forge.OnServerEvent:Connect(function(Player: Player, EquipmentId: number, Count: number)
PlayerInfoProxy:MakeForge(Player, EquipmentId, Count)
end)
ReplicatedStorage.Remotes.PlayerRemoving.Event:Connect(function(Player: Player)
PlayerInfoProxy:OnPlayerRemoving(Player)
end)