更新
This commit is contained in:
parent
083331454f
commit
9b6a1e3a6d
Binary file not shown.
BIN
excel/cha.xlsx
BIN
excel/cha.xlsx
Binary file not shown.
Binary file not shown.
BIN
excel/global.xlsx
Normal file
BIN
excel/global.xlsx
Normal file
Binary file not shown.
BIN
excel/item.xlsx
BIN
excel/item.xlsx
Binary file not shown.
BIN
excel/language.xlsx
Normal file
BIN
excel/language.xlsx
Normal file
Binary file not shown.
Binary file not shown.
@ -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]},
|
||||
|
@ -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},
|
||||
|
@ -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}
|
||||
]
|
@ -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}
|
||||
]
|
@ -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]}
|
||||
]
|
17
src/ReplicatedStorage/Json/Forge.json
Normal file
17
src/ReplicatedStorage/Json/Forge.json
Normal 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]}
|
||||
]
|
@ -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},
|
||||
|
62
src/ReplicatedStorage/Json/LvUpgrade.json
Normal file
62
src/ReplicatedStorage/Json/LvUpgrade.json
Normal 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}
|
||||
]
|
3
src/ReplicatedStorage/Json/Param.json
Normal file
3
src/ReplicatedStorage/Json/Param.json
Normal file
@ -0,0 +1,3 @@
|
||||
[
|
||||
{"id":1,"key":"quality_bonus","intValue":null,"stringValue":null,"intArray":[100,125,150,200,275,375]}
|
||||
]
|
7
src/ReplicatedStorage/Json/Reward.json
Normal file
7
src/ReplicatedStorage/Json/Reward.json
Normal 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]}
|
||||
]
|
@ -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
|
||||
|
||||
-- 给表增加key,value(加法计算)
|
||||
function Utils:TableSafeAddValue(AttributesData: table, AttributeName: string, AttributeValue: number)
|
||||
AttributesData[AttributeName] = (AttributesData[AttributeName] or 0) + AttributeValue
|
||||
end
|
||||
|
||||
-- 给表增加key,value(加法计算),按第二个参数表的内容增加
|
||||
function Utils:TableSafeAddTableValue(AttributesData: table, AddTableValue: table)
|
||||
for AttributeName, AttributeValue in AddTableValue do
|
||||
AttributesData[AttributeName] = (AttributesData[AttributeName] or 0) + AttributeValue
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
return Utils
|
@ -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
|
||||
|
||||
|
@ -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, {})
|
||||
|
@ -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
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
-- 获取技能属性
|
||||
|
126
src/ServerStorage/Proxy/BookProxy.luau
Normal file
126
src/ServerStorage/Proxy/BookProxy.luau
Normal 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
|
@ -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
|
||||
|
||||
-- 获取装备数据
|
||||
|
@ -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
|
||||
|
@ -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 = {}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
-- 玩家角色重生
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user