This commit is contained in:
gechangfu 2025-08-25 19:35:15 +08:00
parent e80640ecc2
commit 027f40481f
26 changed files with 236 additions and 151 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -34,7 +34,7 @@
{"id":36,"type":2,"specialType":null,"effectAttribute":"critDamageRateDark","battleValue":[1,10],"iconId":29,"nameId":236}, {"id":36,"type":2,"specialType":null,"effectAttribute":"critDamageRateDark","battleValue":[1,10],"iconId":29,"nameId":236},
{"id":37,"type":2,"specialType":null,"effectAttribute":"ironBonus","battleValue":[1,0],"iconId":37,"nameId":237}, {"id":37,"type":2,"specialType":null,"effectAttribute":"ironBonus","battleValue":[1,0],"iconId":37,"nameId":237},
{"id":50,"type":1,"specialType":null,"effectAttribute":"wearNumber","battleValue":[1,10],"iconId":50,"nameId":250}, {"id":50,"type":1,"specialType":null,"effectAttribute":"wearNumber","battleValue":[1,10],"iconId":50,"nameId":250},
{"id":51,"type":1,"specialType":null,"effectAttribute":"skillNumber","battleValue":[1,10],"iconId":51,"nameId":251}, {"id":51,"type":1,"specialType":null,"effectAttribute":"abilityNumber","battleValue":[1,10],"iconId":51,"nameId":251},
{"id":52,"type":1,"specialType":null,"effectAttribute":"extraAttributeNumber","battleValue":[1,10],"iconId":52,"nameId":252}, {"id":52,"type":1,"specialType":null,"effectAttribute":"extraAttributeNumber","battleValue":[1,10],"iconId":52,"nameId":252},
{"id":53,"type":1,"specialType":null,"effectAttribute":"elementNumber","battleValue":[1,10],"iconId":53,"nameId":253}, {"id":53,"type":1,"specialType":null,"effectAttribute":"elementNumber","battleValue":[1,10],"iconId":53,"nameId":253},
{"id":54,"type":1,"specialType":null,"effectAttribute":"elementDefNumber","battleValue":[1,10],"iconId":54,"nameId":254}, {"id":54,"type":1,"specialType":null,"effectAttribute":"elementDefNumber","battleValue":[1,10],"iconId":54,"nameId":254},

View File

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

View File

@ -32,12 +32,13 @@
{"id":226,"text":"资源回复速度"}, {"id":226,"text":"资源回复速度"},
{"id":227,"text":"吸血"}, {"id":227,"text":"吸血"},
{"id":228,"text":"金币掉落加成"}, {"id":228,"text":"金币掉落加成"},
{"id":250,"text":"上阵穿戴数量上限"}, {"id":250,"text":"上阵武器上限"},
{"id":251,"text":"技能数量上限"}, {"id":251,"text":"技能上限"},
{"id":252,"text":"额外属性数量上限"}, {"id":252,"text":"额外属性上限"},
{"id":253,"text":"元素属性数量上限"}, {"id":253,"text":"元素属性上限"},
{"id":254,"text":"元素抗性数量上限"}, {"id":254,"text":"元素抗性上限"},
{"id":255,"text":"宝石数量上限"}, {"id":255,"text":"宝石上限"},
{"id":256,"text":"符文上限"},
{"id":1001,"text":"鉴定出{0}属性时 {1}+{2}"}, {"id":1001,"text":"鉴定出{0}属性时 {1}+{2}"},
{"id":1002,"text":"鉴定出{0}技能时 {1}+{2}"}, {"id":1002,"text":"鉴定出{0}技能时 {1}+{2}"},
{"id":1003,"text":"鉴定出{0}晶石时 {1}+{2}"}, {"id":1003,"text":"鉴定出{0}晶石时 {1}+{2}"},

View File

@ -32,12 +32,13 @@
{"id":226,"text":"资源回复速度"}, {"id":226,"text":"资源回复速度"},
{"id":227,"text":"吸血"}, {"id":227,"text":"吸血"},
{"id":228,"text":"金币掉落加成"}, {"id":228,"text":"金币掉落加成"},
{"id":250,"text":"上阵穿戴数量上限"}, {"id":250,"text":"上阵武器上限"},
{"id":251,"text":"技能数量上限"}, {"id":251,"text":"技能上限"},
{"id":252,"text":"额外属性数量上限"}, {"id":252,"text":"额外属性上限"},
{"id":253,"text":"元素属性数量上限"}, {"id":253,"text":"元素属性上限"},
{"id":254,"text":"元素抗性数量上限"}, {"id":254,"text":"元素抗性上限"},
{"id":255,"text":"宝石数量上限"}, {"id":255,"text":"宝石上限"},
{"id":256,"text":"符文上限"},
{"id":1001,"text":"鉴定出{0}属性时 {1}+{2}"}, {"id":1001,"text":"鉴定出{0}属性时 {1}+{2}"},
{"id":1002,"text":"鉴定出{0}技能时 {1}+{2}"}, {"id":1002,"text":"鉴定出{0}技能时 {1}+{2}"},
{"id":1003,"text":"鉴定出{0}晶石时 {1}+{2}"}, {"id":1003,"text":"鉴定出{0}晶石时 {1}+{2}"},

View File

@ -1,86 +1,88 @@
--[[ -- --[[
EventFilter快速入门指南 -- EventFilter快速入门指南
最简单的使用方式 -- 最简单的使用方式
]] -- ]]
local EventFilter = require(script.Parent.EventFilter) -- local EventFilter = require(script.Parent.EventFilter)
-- ===== 最简单的使用方式 ===== -- -- ===== 最简单的使用方式 =====
-- 1. 创建符文对象 -- -- 1. 创建符文对象
local myRune = { -- local myRune = {
name = "我的符文", -- name = "我的符文",
level = 1 -- level = 1
} -- }
-- 2. 添加Destroy方法用于自动回收 -- -- 2. 添加Destroy方法用于自动回收
function myRune:Destroy() -- function myRune:Destroy()
print("销毁符文:", self.name) -- print("销毁符文:", self.name)
for k, v in pairs(self) do self[k] = nil end -- for k, v in pairs(self) do self[k] = nil end
self = nil -- self = nil
end -- end
-- 3. 让符文订阅事件 -- -- 3. 让符文订阅事件
EventFilter.SubscribeGlobalFilter("OnAttack", function(eventData) -- EventFilter.SubscribeGlobalFilter("OnAttack", function(eventData)
print("符文生效:伤害 +50%") -- print("符文生效:伤害 +50%")
eventData.damage = eventData.damage * 1.5 -- eventData.damage = eventData.damage * 1.5
return eventData -- return eventData
end, 10, myRune) -- 事件名, 处理函数, 优先级, 所有者 -- end, 10, myRune) -- 事件名, 处理函数, 优先级, 所有者
-- 4. 发送事件 -- -- 4. 发送事件
local attackData = {damage = 100} -- local attackData = {damage = 100}
EventFilter.FireGlobalWithFilter("OnAttack", attackData, function(processedData) -- EventFilter.FireGlobalWithFilter("OnAttack", attackData, function(processedData)
print("最终伤害:", processedData.damage) -- 输出150 -- print("最终伤害:", processedData.damage) -- 输出150
end) -- end)
-- 5. 销毁符文(自动回收) -- -- 5. 销毁符文(自动回收)
myRune:Destroy() -- Filter自动失效不需要手动取消订阅 -- myRune:Destroy() -- Filter自动失效不需要手动取消订阅
-- ===== 实际游戏中的使用 ===== -- -- ===== 实际游戏中的使用 =====
-- 在攻击脚本中: -- -- 在攻击脚本中:
local function playerAttack() -- local function playerAttack()
local attackData = { -- local attackData = {
damage = 100, -- damage = 100,
attackType = "melee", -- attackType = "melee",
target = enemy -- target = enemy
} -- }
-- 发送攻击事件,让符文系统处理 -- -- 发送攻击事件,让符文系统处理
EventFilter.FireGlobalWithFilter("OnAttack", attackData, function(finalData) -- EventFilter.FireGlobalWithFilter("OnAttack", attackData, function(finalData)
-- 使用处理后的数据执行实际攻击 -- -- 使用处理后的数据执行实际攻击
DealDamage(finalData.damage, finalData.target) -- DealDamage(finalData.damage, finalData.target)
end) -- end)
end -- end
-- 在符文脚本中: -- -- 在符文脚本中:
local function setupRune(runeInstance) -- local function setupRune(runeInstance)
-- 符文订阅攻击事件 -- -- 符文订阅攻击事件
EventFilter.SubscribeGlobalFilter("OnAttack", function(data) -- EventFilter.SubscribeGlobalFilter("OnAttack", function(data)
-- 符文效果:增加伤害 -- -- 符文效果:增加伤害
data.damage = data.damage * 1.2 -- data.damage = data.damage * 1.2
return data -- return data
end, 5, runeInstance) -- end, 5, runeInstance)
end -- end
-- ===== 常用事件类型 ===== -- -- ===== 常用事件类型 =====
-- "OnAttack" - 攻击事件 -- -- "OnAttack" - 攻击事件
-- "OnMove" - 移动事件 -- -- "OnMove" - 移动事件
-- "OnSkill" - 技能事件 -- -- "OnSkill" - 技能事件
-- "OnDamage" - 受伤事件 -- -- "OnDamage" - 受伤事件
-- "OnHeal" - 治疗事件 -- -- "OnHeal" - 治疗事件
-- ===== 优先级说明 ===== -- -- ===== 优先级说明 =====
-- 数字越大,优先级越高,越先执行 -- -- 数字越大,优先级越高,越先执行
-- 10: 最高优先级(比如基础属性修改) -- -- 10: 最高优先级(比如基础属性修改)
-- 5: 中等优先级(比如元素转换) -- -- 5: 中等优先级(比如元素转换)
-- 1: 最低优先级(比如暴击判定) -- -- 1: 最低优先级(比如暴击判定)
-- ===== 自动回收的好处 ===== -- -- ===== 自动回收的好处 =====
-- 1. 不需要手动管理符文销毁时Filter自动失效 -- -- 1. 不需要手动管理符文销毁时Filter自动失效
-- 2. 内存安全:不会造成内存泄露 -- -- 2. 内存安全:不会造成内存泄露
-- 3. 代码简洁:不需要写清理代码 -- -- 3. 代码简洁:不需要写清理代码
return { -- return {
-- 这里可以添加一些辅助函数 -- -- 这里可以添加一些辅助函数
} -- }
return{}

View File

@ -140,7 +140,7 @@ function Utils:GetRandomIdFromJsonWithSpecialKey(JsonData: table, Key: string, V
while ExceptIdList and table.find(ExceptIdList, randomId) do while ExceptIdList and table.find(ExceptIdList, randomId) do
randomId = rng:NextInteger(1, #result) randomId = rng:NextInteger(1, #result)
end end
return randomId return result[randomId]
end end
-- 随机获取权重Index -- 随机获取权重Index
@ -191,6 +191,15 @@ function Utils:StringArrayToTable(StringArray: string)
return result return result
end end
-- 获取表的长度
function Utils:GetTableLength(t: table)
local length = 0
for _, _ in pairs(t) do
length = length + 1
end
return length
end
function Utils:GetFlatDirectionAndEndPos(startPos: Vector3, targetPos: Vector3, length: number) function Utils:GetFlatDirectionAndEndPos(startPos: Vector3, targetPos: Vector3, length: number)
local flatStartPos = Vector3.new(startPos.X, 0, startPos.Z) local flatStartPos = Vector3.new(startPos.X, 0, startPos.Z)
local flatTarget = Vector3.new(targetPos.X, 0, targetPos.Z) local flatTarget = Vector3.new(targetPos.X, 0, targetPos.Z)

View File

@ -124,7 +124,9 @@ function Rune:Execute(index: number, AttributesData: table?, BehaviorNameList: t
-- 使用PlayerAI的专用方法 -- 使用PlayerAI的专用方法
local beginNextIndex = self.PlayerAI:TriggerAllRunesExcept(self, "OnTriggerBeginEvent", index, AttributesData, BehaviorNameList) local beginNextIndex = self.PlayerAI:TriggerAllRunesExcept(self, "OnTriggerBeginEvent", index, AttributesData, BehaviorNameList)
if type(beginNextIndex) == "number" then if type(beginNextIndex) == "number" then
self:RecordExecution(index, attributesBefore, AttributesData, behaviorListBefore, BehaviorNameList, beginNextIndex) local attributesAfter = Utils:DeepCopyTable(AttributesData or {})
local behaviorListAfter = Utils:DeepCopyTable(BehaviorNameList or {})
self:RecordExecution(index, attributesBefore, attributesAfter, behaviorListBefore, behaviorListAfter, beginNextIndex)
return beginNextIndex return beginNextIndex
end end
@ -132,18 +134,24 @@ function Rune:Execute(index: number, AttributesData: table?, BehaviorNameList: t
local nextIndex = self:OnExecute(index, AttributesData, BehaviorNameList) local nextIndex = self:OnExecute(index, AttributesData, BehaviorNameList)
if type(nextIndex) == "number" then if type(nextIndex) == "number" then
self.PlayerAI:TriggerAllRunesExcept(self, "OnTriggerEndEvent", index, AttributesData, BehaviorNameList) self.PlayerAI:TriggerAllRunesExcept(self, "OnTriggerEndEvent", index, AttributesData, BehaviorNameList)
self:RecordExecution(index, attributesBefore, AttributesData, behaviorListBefore, BehaviorNameList, nextIndex) local attributesAfter = Utils:DeepCopyTable(AttributesData or {})
local behaviorListAfter = Utils:DeepCopyTable(BehaviorNameList or {})
self:RecordExecution(index, attributesBefore, attributesAfter, behaviorListBefore, behaviorListAfter, nextIndex)
return nextIndex return nextIndex
end end
local endNextIndex = self.PlayerAI:TriggerAllRunesExcept(self, "OnTriggerEndEvent", index, AttributesData, BehaviorNameList) local endNextIndex = self.PlayerAI:TriggerAllRunesExcept(self, "OnTriggerEndEvent", index, AttributesData, BehaviorNameList)
if type(endNextIndex) == "number" then if type(endNextIndex) == "number" then
self:RecordExecution(index, attributesBefore, AttributesData, behaviorListBefore, BehaviorNameList, endNextIndex) local attributesAfter = Utils:DeepCopyTable(AttributesData or {})
local behaviorListAfter = Utils:DeepCopyTable(BehaviorNameList or {})
self:RecordExecution(index, attributesBefore, attributesAfter, behaviorListBefore, behaviorListAfter, endNextIndex)
return endNextIndex return endNextIndex
end end
self.TriggerTime = self.TriggerTime + 1 self.TriggerTime = self.TriggerTime + 1
self:RecordExecution(index, attributesBefore, AttributesData, behaviorListBefore, BehaviorNameList, nextIndex) local attributesAfter = Utils:DeepCopyTable(AttributesData or {})
local behaviorListAfter = Utils:DeepCopyTable(BehaviorNameList or {})
self:RecordExecution(index, attributesBefore, attributesAfter, behaviorListBefore, behaviorListAfter, nextIndex)
return nextIndex return nextIndex
end end

View File

@ -107,11 +107,25 @@ function Attack:Execute()
-- 暴击判定走通用属性 -- 暴击判定走通用属性
local critCheckRate = self:GetAttributeValue("critRate") or 0 local critCheckRate = self:GetAttributeValue("critRate") or 0
local isCrit = Rng:RandomPercent(critCheckRate) local isCrit = Rng:RandomPercent(critCheckRate)
local baseAttack = self.PlayerAI:GetBaseAttack()
-- 伤害逻辑计算部分 -- 伤害逻辑计算部分
-- TODO之后这里逻辑要优化
local damageData = {} local damageData = {}
for _, attribute in ATTRIBUTE_LIST do for _, attribute in ATTRIBUTE_LIST do
local attributeValue = self:GetAttributeValue(attribute.Name) local attributeValue = self:GetAttributeValue(attribute.Name)
-- 普攻基础值
if attribute.Name == "attack" then
attributeValue = baseAttack
end
-- 元素是百分比值
if attributeValue ~= nil then
if attribute.ElementType ~= DamageProxy.ElementType.NONE then
attributeValue = math.floor(baseAttack * attributeValue)
end
end
if attributeValue then if attributeValue then
-- 计算暴击加成 -- 计算暴击加成
local DamageType = DamageProxy.DamageType.NORMAL local DamageType = DamageProxy.DamageType.NORMAL
@ -140,6 +154,7 @@ function Attack:Execute()
}, function(processedData) }, function(processedData)
damageData = processedData.damageData damageData = processedData.damageData
end) end)
print("damageData", damageData)
DamageProxy:TakeDamage(self.Character, self.CheckData["ClosestCharacter"], damageData) DamageProxy:TakeDamage(self.Character, self.CheckData["ClosestCharacter"], damageData)
-- 发送攻击后事件 -- 发送攻击后事件

View File

@ -21,17 +21,26 @@ end
function RuneBookQualityPurple:Check(index: number, AttributesData: table, BehaviorNameList: table) function RuneBookQualityPurple:Check(index: number, AttributesData: table, BehaviorNameList: table)
local pDataFolder = ReplicatedStorage:FindFirstChild("PlayerData") local pDataFolder = ReplicatedStorage:FindFirstChild("PlayerData")
if not pDataFolder then return nil end if not pDataFolder then
return false
end
local pData = pDataFolder:FindFirstChild(self.PlayerAI.Player.UserId) local pData = pDataFolder:FindFirstChild(self.PlayerAI.Player.UserId)
if not pData then return nil end if not pData then
return false
end
local bookFolder = pData:FindFirstChild("Book") local bookFolder = pData:FindFirstChild("Book")
if not bookFolder then return nil end if not bookFolder then
return false
end
local bookList = bookFolder:GetChildren() local bookList = bookFolder:GetChildren()
if #bookList == 0 then return nil end if #bookList == 0 then
return false
end
self.Data = bookList self.Data = bookList
return true return true
end end
@ -43,9 +52,8 @@ function RuneBookQualityPurple:OnExecute(index: number, AttributesData: table, B
qualityNumber = qualityNumber + 1 qualityNumber = qualityNumber + 1
end end
end end
local attackRate = math.floor(qualityNumber * 25 / 100) local attackRate = qualityNumber * 25
Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate) Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate)
return nil return nil
end end

View File

@ -25,7 +25,9 @@ end
function RuneFireDamage:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) function RuneFireDamage:OnExecute(index: number, AttributesData: table, BehaviorNameList: table)
local baseAttribute = AttributesData.fireAtk or 100 local baseAttribute = AttributesData.fireAtk or 100
local addAttribute = math.floor(baseAttribute * 50 / 100) local addAttribute = math.floor(baseAttribute * 50 / 100)
print("before fireAtk", baseAttribute)
Utils:TableSafeAddValue(AttributesData, "fireAtk", addAttribute) Utils:TableSafeAddValue(AttributesData, "fireAtk", addAttribute)
print("after fireAtk", AttributesData.fireAtk)
return nil return nil
end end

View File

@ -51,8 +51,10 @@ function RuneWearKnife:OnExecute(index: number, AttributesData: table, BehaviorN
subTypeNumber = subTypeNumber + self.PlayerAI:GetSharedData(CheckShareName) subTypeNumber = subTypeNumber + self.PlayerAI:GetSharedData(CheckShareName)
end end
local attackRate = math.floor((AttributesData.attackRate or 100) * subTypeNumber * 25 / 100) local attackRate = math.floor(subTypeNumber * 25)
print("Before attackRate", attackRate)
Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate) Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate)
print("After attackRate", AttributesData.attackRate)
return nil return nil
end end

View File

@ -44,7 +44,7 @@ end
-- 计算词条等级加成上限 -- 计算词条等级加成上限
local function GetEntryLvBonus(PlayerLv: number, BonusData: table) local function GetEntryLvBonus(PlayerLv: number, BonusData: table)
local bonus = math.floor(PlayerLv / BonusData[1]) * BonusData[2] local bonus = math.floor(PlayerLv / BonusData[1]) * BonusData[2]
return math.min(bonus, BonusData[3]) return math.min(bonus, BonusData[3] or math.huge)
end end
-- 改变装备数据 -- 改变装备数据
@ -136,67 +136,68 @@ function EquipmentProxy:AddEquipment(Player: Player, EquipmentId: number)
ResultData.attributes[AttributeData.effectAttribute] = qualityEffectValue ResultData.attributes[AttributeData.effectAttribute] = qualityEffectValue
end end
local playerInfo = PlayerInfoProxy:GetPlayerInfo(Player)
-- TODO: 其他随机词条内容添加在下面 -- TODO: 其他随机词条内容添加在下面
-- 随机生成额外属性数量 -- 随机生成额外属性数量
local maxExAttributeNumber = PlayerInfoProxy:GetPlayerInfo(Player).exAttributeNumber or 0 local maxExAttributeNumber = playerInfo["AttributesUpgrade"]["12"] or 0
local exAttributeNumber = rng:NextInteger(0, maxExAttributeNumber) local exAttributeNumber = rng:NextInteger(0, maxExAttributeNumber)
ResultData.maxExAttributeNumber = exAttributeNumber ResultData.maxExAttributeNumber = exAttributeNumber
ResultData.exAttributes = {} ResultData.exAttributes = {}
if exAttributeNumber > 0 then if exAttributeNumber > 0 then
local spawnExAttributesId = {} local spawnExAttributesId = {}
for i = 1, exAttributeNumber do for i = 1, exAttributeNumber do
local newExAttributeId = Utils:GetRandomIdFromJsonWithSpecialKey(JsonExAttributes, "specialType", 1, spawnExAttributesId) local newExAttributeId = Utils:GetRandomIdFromJsonWithSpecialKey(JsonAttributes, "specialType", 1, spawnExAttributesId)
table.insert(spawnExAttributesId, newExAttributeId) table.insert(spawnExAttributesId, newExAttributeId)
local ExAttributeData = Utils:GetIdDataFromJson(JsonExAttributes, newExAttributeId) local ExAttributeData = Utils:GetIdDataFromJson(JsonExAttributes, newExAttributeId)
local minValue = ExAttributeData.randomValue[1] local minValue = ExAttributeData.randomValue[1]
local maxValue = ExAttributeData.randomValue[2] + GetEntryLvBonus(PlayerLevel, ExAttributeData.bonus) local maxValue = ExAttributeData.randomValue[2] + GetEntryLvBonus(PlayerLevel, ExAttributeData.lvBonus)
local randomExAttributeValue = rng:NextInteger(minValue, maxValue) local randomExAttributeValue = rng:NextInteger(minValue, maxValue)
local AttributeData = Utils:GetIdDataFromJson(JsonAttributes, newExAttributeId) local AttributeData = Utils:GetIdDataFromJson(JsonAttributes, newExAttributeId)
ResultData.exAttributes[AttributeData.name] = randomExAttributeValue ResultData.exAttributes[AttributeData.effectAttribute] = randomExAttributeValue
end end
end end
-- 随机生成元素属性数量(暂时跟额外属性相同,之后可以改逻辑) -- 随机生成元素属性数量(暂时跟额外属性相同,之后可以改逻辑)
local maxElementNumber = PlayerInfoProxy:GetPlayerInfo(Player).elementNumber or 0 local maxElementNumber = playerInfo["AttributesUpgrade"]["13"] or 0
local elementNumber = rng:NextInteger(0, maxElementNumber) local elementNumber = rng:NextInteger(0, maxElementNumber)
ResultData.maxElementNumber = elementNumber ResultData.maxElementNumber = elementNumber
ResultData.elements = {} ResultData.elements = {}
if elementNumber > 0 then if elementNumber > 0 then
local spawnElementsId = {} local spawnElementsId = {}
for i = 1, elementNumber do for i = 1, elementNumber do
local newElementAttributeId = Utils:GetRandomIdFromJsonWithSpecialKey(JsonExAttributes, "specialType", 2, spawnElementsId) local newElementAttributeId = Utils:GetRandomIdFromJsonWithSpecialKey(JsonAttributes, "specialType", 2, spawnElementsId)
table.insert(spawnElementsId, newElementAttributeId) table.insert(spawnElementsId, newElementAttributeId)
local ElementAttributeData = Utils:GetIdDataFromJson(JsonExAttributes, newElementAttributeId) local ElementAttributeData = Utils:GetIdDataFromJson(JsonExAttributes, newElementAttributeId)
local minValue = ElementAttributeData.randomValue[1] local minValue = ElementAttributeData.randomValue[1]
local maxValue = ElementAttributeData.randomValue[2] + GetEntryLvBonus(PlayerLevel, ElementAttributeData.bonus) local maxValue = ElementAttributeData.randomValue[2] + GetEntryLvBonus(PlayerLevel, ElementAttributeData.lvBonus)
local randomElementAttributeValue = rng:NextInteger(minValue, maxValue) local randomElementAttributeValue = rng:NextInteger(minValue, maxValue)
local AttributeData = Utils:GetIdDataFromJson(JsonAttributes, newElementAttributeId) local AttributeData = Utils:GetIdDataFromJson(JsonAttributes, newElementAttributeId)
ResultData.elements[AttributeData.name] = randomElementAttributeValue ResultData.elements[AttributeData.effectAttribute] = randomElementAttributeValue
end end
end end
-- 随机生成元素抗性数量 -- 随机生成元素抗性数量
local maxElementDefNumber = PlayerInfoProxy:GetPlayerInfo(Player).elementDefNumber or 0 local maxElementDefNumber = playerInfo["AttributesUpgrade"]["14"] or 0
local elementDefNumber = rng:NextInteger(0, maxElementDefNumber) local elementDefNumber = rng:NextInteger(0, maxElementDefNumber)
ResultData.maxElementDefNumber = elementDefNumber ResultData.maxElementDefNumber = elementDefNumber
ResultData.elementDef = {} ResultData.elementDef = {}
if elementDefNumber > 0 then if elementDefNumber > 0 then
local spawnElementDefId = {} local spawnElementDefId = {}
for i = 1, elementDefNumber do for i = 1, elementDefNumber do
local newElementDefId = Utils:GetRandomIdFromJsonWithSpecialKey(JsonExAttributes, "specialType", 3, spawnElementDefId) local newElementDefId = Utils:GetRandomIdFromJsonWithSpecialKey(JsonAttributes, "specialType", 3, spawnElementDefId)
table.insert(spawnElementDefId, newElementDefId) table.insert(spawnElementDefId, newElementDefId, spawnElementDefId)
local ElementDefAttributeData = Utils:GetIdDataFromJson(JsonExAttributes, newElementDefId) local ElementDefAttributeData = Utils:GetIdDataFromJson(JsonExAttributes, newElementDefId)
local minValue = ElementDefAttributeData.randomValue[1] local minValue = ElementDefAttributeData.randomValue[1]
local maxValue = ElementDefAttributeData.randomValue[2] + GetEntryLvBonus(PlayerLevel, ElementDefAttributeData.bonus) local maxValue = ElementDefAttributeData.randomValue[2] + GetEntryLvBonus(PlayerLevel, ElementDefAttributeData.lvBonus)
local randomElementDefAttributeValue = rng:NextInteger(minValue, maxValue) local randomElementDefAttributeValue = rng:NextInteger(minValue, maxValue)
local AttributeData = Utils:GetIdDataFromJson(JsonAttributes, newElementDefId) local AttributeData = Utils:GetIdDataFromJson(JsonAttributes, newElementDefId)
ResultData.elementDef[AttributeData.name] = randomElementDefAttributeValue ResultData.elementDef[AttributeData.effectAttribute] = randomElementDefAttributeValue
end end
end end
@ -252,19 +253,20 @@ function EquipmentProxy:AddEquipment(Player: Player, EquipmentId: number)
-- 随机生成技能槽位数量 -- 随机生成技能槽位数量
local AbilityProxy = require(ServerStorage.Proxy.AbilityProxy) local AbilityProxy = require(ServerStorage.Proxy.AbilityProxy)
local maxAbilityNumber = PlayerInfoProxy:GetPlayerInfo(Player)["AttributesUpgrade"]["11"] or 0 local maxAbilityNumber = playerInfo["AttributesUpgrade"]["11"] or 0
local abilityNumber = rng:NextInteger(0, maxAbilityNumber) local abilityNumber = rng:NextInteger(0, maxAbilityNumber)
ResultData.maxAbilityNumber = abilityNumber ResultData.maxAbilityNumber = abilityNumber
-- 随机生成宝石数量 -- 随机生成宝石数量
-- TODO:暂时没有宝石所以配置的maxGemNumber是不对的
local GemProxy = require(ServerStorage.Proxy.GemProxy) local GemProxy = require(ServerStorage.Proxy.GemProxy)
local maxGemNumber = PlayerInfoProxy:GetPlayerInfo(Player).gemNumber or 0 local maxGemNumber = playerInfo["AttributesUpgrade"].gemNumber or 0
local gemNumber = rng:NextInteger(0, maxGemNumber) local gemNumber = rng:NextInteger(0, maxGemNumber)
ResultData.maxGemNumber = gemNumber ResultData.maxGemNumber = gemNumber
-- 随机生成符文数量 -- 随机生成符文数量
local RuneProxy = require(ServerStorage.Proxy.RuneProxy) local RuneProxy = require(ServerStorage.Proxy.RuneProxy)
local maxRuneNumber = PlayerInfoProxy:GetPlayerInfo(Player)["AttributesUpgrade"]["15"] or 0 local maxRuneNumber = playerInfo["AttributesUpgrade"]["15"] or 0
local runeNumber = rng:NextInteger(0, maxRuneNumber) local runeNumber = rng:NextInteger(0, maxRuneNumber)
ResultData.maxRuneNumber = runeNumber ResultData.maxRuneNumber = runeNumber

View File

@ -113,6 +113,10 @@ function PlayerAI:AddRune(RuneName: string, WearingSlot: number?)
self:UpdateRuneTriggerSlots() self:UpdateRuneTriggerSlots()
end end
function PlayerAI:GetBaseAttack()
return math.floor(self.Character:GetAttributeValue("attack") * (1 + self.Character:GetAttributeValue("attackRate") / 100))
end
-- 触发所有符文初始化完成 -- 触发所有符文初始化完成
function PlayerAI:TriggerAllRunesInitFinish() function PlayerAI:TriggerAllRunesInitFinish()
for _, data in self.RuneList do for _, data in self.RuneList do

View File

@ -184,11 +184,6 @@ function PlayerFightProxy:UpdatePlayerFightData(Player: Player)
end end
end end
-- 更新玩家属性
for AttributeName, AttributeValue in AttributesData do
-- TODO这里可能涉及到战斗时更换装备的属性处理还需要再函数内部再根据剩余百分比数值变化
PlayerRole:ChangeAttributeValue(AttributeName, AttributeValue)
end
-- 根据技能添加玩家AI行为 -- 根据技能添加玩家AI行为
local abilityIdList, behaviorNameList = AbilityProxy:GetPlayerWearingAbilityData(Player) local abilityIdList, behaviorNameList = AbilityProxy:GetPlayerWearingAbilityData(Player)
@ -198,6 +193,12 @@ function PlayerFightProxy:UpdatePlayerFightData(Player: Player)
local RuneProxy = require(ServerStorage.Proxy.RuneProxy) local RuneProxy = require(ServerStorage.Proxy.RuneProxy)
RuneProxy:GetRuneAttributes(Player, playerAI, AttributesData, behaviorNameList) RuneProxy:GetRuneAttributes(Player, playerAI, AttributesData, behaviorNameList)
-- 更新玩家属性
for AttributeName, AttributeValue in AttributesData do
-- TODO这里可能涉及到战斗时更换装备的属性处理还需要再函数内部再根据剩余百分比数值变化
PlayerRole:ChangeAttributeValue(AttributeName, AttributeValue)
end
-- TODO设置AI行为临时清除所有行为添加新的玩家行为 -- TODO设置AI行为临时清除所有行为添加新的玩家行为
playerAI:ClearAllBehaviour() playerAI:ClearAllBehaviour()
for _, behaviorName in behaviorNameList do for _, behaviorName in behaviorNameList do

View File

@ -71,19 +71,39 @@ function RuneCalculation:GetRuneAttributes(Player: Player, PlayerAI: table, Attr
warn("RuneCalculation: 发送符文执行记录失败:", error) warn("RuneCalculation: 发送符文执行记录失败:", error)
end end
end end
end end
-- 执行符文循环的辅助函数 -- 执行符文循环的辅助函数
function RuneCalculation:ExecuteRuneLoop(PlayerAI: table, wearingRuneName: table, wearingRuneUniqueId: table, startIndex: number, maxSteps: number, AttributesData: table, BehaviorNameList: table) function RuneCalculation:ExecuteRuneLoop(PlayerAI: table, wearingRuneName: table, wearingRuneUniqueId: table, startIndex: number, maxSteps: number, AttributesData: table, BehaviorNameList: table)
local index = startIndex local index = startIndex
while index <= #wearingRuneUniqueId and maxSteps > 0 do -- 将wearingRuneName转换为数组格式按槽位顺序排列
local result = PlayerAI:TriggerRune(wearingRuneName[index], "Check", index, AttributesData, BehaviorNameList) local wearingRuneNameArray = {}
if result then local maxSlot = 0
local nextIndex = PlayerAI:TriggerRune(wearingRuneName[index], "Execute", index, AttributesData, BehaviorNameList) for slot, runeName in pairs(wearingRuneName) do
maxSlot = math.max(maxSlot, slot)
end
if type(nextIndex) == "number" then for slot = 1, maxSlot do
index = nextIndex if wearingRuneName[slot] then
table.insert(wearingRuneNameArray, wearingRuneName[slot])
end
end
while index <= #wearingRuneUniqueId and maxSteps > 0 do
local runeName = wearingRuneNameArray[index]
if runeName then
local result = PlayerAI:TriggerRune(runeName, "Check", index, AttributesData, BehaviorNameList)
if result then
local nextIndex = PlayerAI:TriggerRune(runeName, "Execute", index, AttributesData, BehaviorNameList)
if type(nextIndex) == "number" then
index = nextIndex
else
index += 1
end
else else
index += 1 index += 1
end end

View File

@ -253,6 +253,7 @@ function RuneProxy:GetPlayerWearingRuneData(Player: Player)
-- 穿戴中的填入 -- 穿戴中的填入
local EquipmentProxy = require(ServerStorage.Proxy.EquipmentProxy) local EquipmentProxy = require(ServerStorage.Proxy.EquipmentProxy)
local wearingEquipments = EquipmentProxy:GetPlayerWearingEquipmentUniqueId(Player) local wearingEquipments = EquipmentProxy:GetPlayerWearingEquipmentUniqueId(Player)
for _, RuneData in ArchiveProxy.pData[Player.UserId][STORE_NAME] do for _, RuneData in ArchiveProxy.pData[Player.UserId][STORE_NAME] do
if tonumber(RuneData.wearing) > 0 and table.find(wearingEquipments, RuneData.wearing) then if tonumber(RuneData.wearing) > 0 and table.find(wearingEquipments, RuneData.wearing) then
table.insert(wearingRuneUniqueId, RuneData.id) table.insert(wearingRuneUniqueId, RuneData.id)
@ -265,6 +266,7 @@ function RuneProxy:GetPlayerWearingRuneData(Player: Player)
end end
end end
end end
return wearingRuneUniqueId, wearingRuneName, wearingRuneBehaviorName return wearingRuneUniqueId, wearingRuneName, wearingRuneBehaviorName
end end

View File

@ -43,14 +43,14 @@ function RuneShow:Refresh()
end end
function RuneShow:OnInitFinish() function RuneShow:OnInitFinish()
local con = self.Variables._btnClick.MouseButton1Click:Connect(function() -- local con = self.Variables._btnClick.MouseButton1Click:Connect(function()
if self.Data.instance then -- if self.Data.instance then
self.TopUI:ShowDetailData(self.Data.id) -- self.TopUI:ShowDetailData(self.Data.id)
else -- else
-- TODO: 之后做提示弹窗 -- -- TODO: 之后做提示弹窗
end -- end
end) -- end)
table.insert(self.Connections, con) -- table.insert(self.Connections, con)
if self.Data.instance then if self.Data.instance then
local wearingCon = self.Data.instance:GetAttributeChangedSignal("wearing"):Connect(function() local wearingCon = self.Data.instance:GetAttributeChangedSignal("wearing"):Connect(function()

View File

@ -51,9 +51,11 @@ function AttributeLvupShow:Refresh()
self.instanceCon = instanceCon self.instanceCon = instanceCon
end end
local attributeData = Utils:GetIdDataFromJson(JsonAttributes, self.Data.id) local attributesUpgradeData = Utils:GetIdDataFromJson(JsonAttributesUpgrade, self.Data.id)
local attributeData = Utils:GetSpecialKeyDataFromJson(JsonAttributes, "effectAttribute", attributesUpgradeData.effectAttribute)
self.Variables._imgIcon.Image = Localization:GetImageData(attributeData.iconId) self.Variables._imgIcon.Image = Localization:GetImageData(attributeData.iconId)
self.Variables._tmpAttributeName.Text = self.Data.id self.Variables._tmpAttributeName.Text = Localization:GetLanguageData(attributeData.nameId)
local nowLv = self:GetNowLv() local nowLv = self:GetNowLv()
self.Variables._tmpLv.Text = "Lv." .. nowLv self.Variables._tmpLv.Text = "Lv." .. nowLv
@ -64,14 +66,18 @@ function AttributeLvupShow:Refresh()
-- 属性值显示 -- 属性值显示
local caculateValue = self.Data.lvAdd[1] + self.Data.lvAdd[2] * (self.Data.maxLv - 1) local caculateValue = self.Data.lvAdd[1] + self.Data.lvAdd[2] * (self.Data.maxLv - 1)
self.Variables._tmpValue.Text = string.format("%.2f%%", caculateValue / 100) if attributeData.type == 1 then
self.Variables._tmpValue.Text = "+"..caculateValue
else
self.Variables._tmpValue.Text = "+"..string.format("%.2f%%", caculateValue / 100)
end
else else
self.Variables._btnUpgrade.Text = self.Data.cost[2] + self.Data.cost[3] * nowLv self.Variables._btnUpgrade.Text = self.Data.cost[2] + self.Data.cost[3] * nowLv
-- 属性值显示(下一级) -- 属性值显示(下一级)
if self.Data.id == 1 or self.Data.id == 2 then if self.Data.id == 1 or self.Data.id == 2 then
self.Variables._tmpValue.Text = math.floor(self.Data.lvAdd[1] * ((self.Data.lvAdd[2] / 10000) ^ nowLv)) self.Variables._tmpValue.Text = "+"..math.floor(self.Data.lvAdd[1] * ((self.Data.lvAdd[2] / 10000) ^ nowLv))
else else
self.Variables._tmpValue.Text = self.Data.lvAdd[1] + self.Data.lvAdd[2] * nowLv self.Variables._tmpValue.Text = "+"..self.Data.lvAdd[1] + self.Data.lvAdd[2] * nowLv
end end
end end
end end

View File

@ -45,7 +45,6 @@ function PackageShow:Refresh()
self.Variables["__listRuneWearing"]:AddComponent(RuneShow) self.Variables["__listRuneWearing"]:AddComponent(RuneShow)
local runeData = Utils:GetWearingRuneData(self.Data.id) local runeData = Utils:GetWearingRuneData(self.Data.id)
print("RuneData", runeData)
self.Variables["__listRuneWearing"]:SetData(runeData) self.Variables["__listRuneWearing"]:SetData(runeData)
-- 模型展示 -- 模型展示

View File

@ -226,7 +226,7 @@ function EquipmentDetailWindow:OnOpenWindow()
self.Variables["__listBaseAttributes"]:SetData(self:TransformKeyTable(self.Data.attributes)) self.Variables["__listBaseAttributes"]:SetData(self:TransformKeyTable(self.Data.attributes))
-- 额外属性 -- 额外属性
if #self.Data.exAttributes > 0 then if Utils:GetTableLength(self.Data.exAttributes) > 0 then
self.Variables["_goExAttributesPanel"].Visible = true self.Variables["_goExAttributesPanel"].Visible = true
self.Variables["__listExAttributes"]:AddComponent(AttributeShow) self.Variables["__listExAttributes"]:AddComponent(AttributeShow)
self.Variables["__listExAttributes"]:SetData(self:TransformKeyTable(self.Data.exAttributes)) self.Variables["__listExAttributes"]:SetData(self:TransformKeyTable(self.Data.exAttributes))
@ -235,7 +235,7 @@ function EquipmentDetailWindow:OnOpenWindow()
end end
-- 元素属性 -- 元素属性
if #self.Data.elements > 0 then if Utils:GetTableLength(self.Data.elements) > 0 then
self.Variables["_goElementPanel"].Visible = true self.Variables["_goElementPanel"].Visible = true
self.Variables["__listElement"]:AddComponent(AttributeShow) self.Variables["__listElement"]:AddComponent(AttributeShow)
self.Variables["__listElement"]:SetData(self:TransformKeyTable(self.Data.elements)) self.Variables["__listElement"]:SetData(self:TransformKeyTable(self.Data.elements))
@ -244,7 +244,7 @@ function EquipmentDetailWindow:OnOpenWindow()
end end
-- 元素定义属性 -- 元素定义属性
if #self.Data.elementDef > 0 then if Utils:GetTableLength(self.Data.elementDef) > 0 then
self.Variables["_goElementDefPanel"].Visible = true self.Variables["_goElementDefPanel"].Visible = true
self.Variables["__listElementDef"]:AddComponent(AttributeShow) self.Variables["__listElementDef"]:AddComponent(AttributeShow)
self.Variables["__listElementDef"]:SetData(self:TransformKeyTable(self.Data.elementDef)) self.Variables["__listElementDef"]:SetData(self:TransformKeyTable(self.Data.elementDef))
@ -262,7 +262,7 @@ function EquipmentDetailWindow:OnOpenWindow()
end end
-- 符文属性 -- 符文属性
if #self.Data.runeWearing > 0 then if Utils:GetTableLength(self.Data.runeWearing) > 0 then
self.Variables["_goRuneWearing"].Visible = true self.Variables["_goRuneWearing"].Visible = true
self.Variables["__listRuneWearing"]:AddComponent(RuneShow) self.Variables["__listRuneWearing"]:AddComponent(RuneShow)
self.Variables["__listRuneWearing"]:SetData(self.Data.runeWearing) self.Variables["__listRuneWearing"]:SetData(self.Data.runeWearing)

View File

@ -116,7 +116,6 @@ function GetEquipmentsWindow:Init(UIManager: table, Data: table?)
} }
self.UIRootName = "ui_w_get_equipments" self.UIRootName = "ui_w_get_equipments"
self.UIParentName = UIEnums.UIParent.UIRoot self.UIParentName = UIEnums.UIParent.UIRoot
return self return self
end end
@ -148,7 +147,7 @@ function GetEquipmentsWindow:ShowDetail(equipmentInstance: Instance)
self.Variables["__listElementDef"]:SetData(self:TransformKeyTable(elementDef)) self.Variables["__listElementDef"]:SetData(self:TransformKeyTable(elementDef))
-- 额外属性 -- 额外属性
if #exAttributes > 0 then if Utils:GetTableLength(exAttributes) > 0 then
self.Variables["_goExAttributesPanel"].Visible = true self.Variables["_goExAttributesPanel"].Visible = true
self.Variables["__listExAttributes"]:SetData(self:TransformKeyTable(exAttributes)) self.Variables["__listExAttributes"]:SetData(self:TransformKeyTable(exAttributes))
else else
@ -156,7 +155,7 @@ function GetEquipmentsWindow:ShowDetail(equipmentInstance: Instance)
end end
-- 元素属性 -- 元素属性
if #elements > 0 then if Utils:GetTableLength(elements) > 0 then
self.Variables["_goElementPanel"].Visible = true self.Variables["_goElementPanel"].Visible = true
self.Variables["__listElement"]:SetData(self:TransformKeyTable(elements)) self.Variables["__listElement"]:SetData(self:TransformKeyTable(elements))
else else
@ -164,7 +163,7 @@ function GetEquipmentsWindow:ShowDetail(equipmentInstance: Instance)
end end
-- 元素定义属性 -- 元素定义属性
if #elementDef > 0 then if Utils:GetTableLength(elementDef) > 0 then
self.Variables["_goElementDefPanel"].Visible = true self.Variables["_goElementDefPanel"].Visible = true
self.Variables["__listElementDef"]:SetData(self:TransformKeyTable(elementDef)) self.Variables["__listElementDef"]:SetData(self:TransformKeyTable(elementDef))
else else

View File

@ -486,7 +486,8 @@ function RuneStateWindow:CreateAttributeChangeDisplay(runeUI: Instance, record:
table.insert(attributeChanges, { table.insert(attributeChanges, {
name = attributeName, name = attributeName,
change = change change = change,
isPercent = attributeData and attributeData.type == 2
}) })
end end
end end
@ -547,6 +548,9 @@ function RuneStateWindow:CreateAttributeChangeContainer(runeUI: Instance, attrib
-- 格式化显示文本 -- 格式化显示文本
local displayValue = change.isCombatValue and FormatNumber(change.change, "Suffix") or tostring(change.change) local displayValue = change.isCombatValue and FormatNumber(change.change, "Suffix") or tostring(change.change)
if change.isPercent then
displayValue = displayValue .. "%"
end
changeText.Text = string.format("%s %s%s", change.name, change.change > 0 and "+" or "", displayValue) changeText.Text = string.format("%s %s%s", change.name, change.change > 0 and "+" or "", displayValue)
changeText.TextColor3 = change.change > 0 and Color3.fromRGB(0, 255, 100) or Color3.fromRGB(255, 100, 100) changeText.TextColor3 = change.change > 0 and Color3.fromRGB(0, 255, 100) or Color3.fromRGB(255, 100, 100)