From 532dab80a0058e968de4a49b03393942fc1bebfa Mon Sep 17 00:00:00 2001 From: gechangfu Date: Thu, 21 Aug 2025 19:29:10 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- excel/Rune.xlsx | Bin 13147 -> 13227 bytes .../Data/EventFilterEnum.luau | 10 + .../Data/ServerSignalEnum.luau | 7 - .../Modules/EventFilterExample.luau | 230 ------------------ src/ServerStorage/Base/Rune.luau | 3 + .../Modules/Behaviours/Attack.luau | 13 + .../Modules/Runes/RuneBookQualityPurple.luau | 12 +- .../Modules/Runes/RuneBossAtk.luau | 51 ++++ .../Modules/Runes/RuneBossHp.luau | 51 ++++ .../Modules/Runes/RuneFirstAttack.luau | 47 ++++ .../Modules/Runes/RuneHpToAtk.luau | 37 +++ .../Modules/Runes/RuneKillEnemyHeal.luau | 47 ++++ .../Modules/Runes/RuneWearElementAttack.luau | 2 +- .../Modules/Runes/RuneWearEmptySlot.luau | 2 +- .../Runes/RuneWearExAttributeAttack.luau | 52 ++++ .../Modules/Runes/RuneWearFillSlot.luau | 2 +- .../Modules/Runes/RuneWearHeavySword.luau | 2 +- .../Modules/Runes/RuneWearKnife.luau | 2 +- .../Modules/Runes/RuneWearStick.luau | 2 +- .../Modules/Runes/RuneWearSword.luau | 2 +- src/ServerStorage/Proxy/MobsProxy/init.luau | 10 + 21 files changed, 335 insertions(+), 249 deletions(-) create mode 100644 src/ReplicatedStorage/Data/EventFilterEnum.luau delete mode 100644 src/ReplicatedStorage/Data/ServerSignalEnum.luau delete mode 100644 src/ReplicatedStorage/Modules/EventFilterExample.luau create mode 100644 src/ServerStorage/Modules/Runes/RuneBossAtk.luau create mode 100644 src/ServerStorage/Modules/Runes/RuneBossHp.luau create mode 100644 src/ServerStorage/Modules/Runes/RuneFirstAttack.luau create mode 100644 src/ServerStorage/Modules/Runes/RuneHpToAtk.luau create mode 100644 src/ServerStorage/Modules/Runes/RuneKillEnemyHeal.luau create mode 100644 src/ServerStorage/Modules/Runes/RuneWearExAttributeAttack.luau diff --git a/excel/Rune.xlsx b/excel/Rune.xlsx index 55b536cf13febf63aab06bd9059f16c51ee183bf..5da16638ab1511dc31d1bf4eada693f6460afc1f 100644 GIT binary patch delta 6116 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 E0Ja%*kpKVy delta 6035 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 JI>oU6{SQe;TSfo? diff --git a/src/ReplicatedStorage/Data/EventFilterEnum.luau b/src/ReplicatedStorage/Data/EventFilterEnum.luau new file mode 100644 index 0000000..dc644cc --- /dev/null +++ b/src/ReplicatedStorage/Data/EventFilterEnum.luau @@ -0,0 +1,10 @@ +local ServerSignalEnum = {} + +ServerSignalEnum = { + BEFORE_ATTACK = "BEFORE_ATTACK", + -- AFTER_ATTACK = "AFTER_ATTACK", + -- BEFORE_KILL_MONSTER = "BEFORE_KILL_MONSTER", + BEFORE_KILL_MONSTER = "BEFORE_KILL_MONSTER", +} + +return ServerSignalEnum \ No newline at end of file diff --git a/src/ReplicatedStorage/Data/ServerSignalEnum.luau b/src/ReplicatedStorage/Data/ServerSignalEnum.luau deleted file mode 100644 index 25de2ba..0000000 --- a/src/ReplicatedStorage/Data/ServerSignalEnum.luau +++ /dev/null @@ -1,7 +0,0 @@ -local ServerSignalEnum = {} - -ServerSignalEnum = { - SHOW_ABILITY = "SHOW_ABILITY", -} - -return ServerSignalEnum \ No newline at end of file diff --git a/src/ReplicatedStorage/Modules/EventFilterExample.luau b/src/ReplicatedStorage/Modules/EventFilterExample.luau deleted file mode 100644 index 8fc0ddd..0000000 --- a/src/ReplicatedStorage/Modules/EventFilterExample.luau +++ /dev/null @@ -1,230 +0,0 @@ ---[[ - EventFilter使用例子 - 演示如何使用事件过滤系统 -]] - -local EventFilter = require(script.Parent.EventFilter) - --- ===== 基础使用示例 ===== - --- 1. 创建符文对象(作为所有者) -local function createRunes() - local fireRune = { - name = "火焰符文", - level = 5, - element = "fire" - } - - local iceRune = { - name = "冰霜符文", - level = 3, - element = "ice" - } - - local criticalRune = { - name = "暴击符文", - level = 4, - criticalChance = 0.3 - } - - -- 添加Destroy方法(用于自动回收) - function fireRune:Destroy() - print("销毁火焰符文") - for k, v in pairs(self) do self[k] = nil end - self = nil - end - - function iceRune:Destroy() - print("销毁冰霜符文") - for k, v in pairs(self) do self[k] = nil end - self = nil - end - - function criticalRune:Destroy() - print("销毁暴击符文") - for k, v in pairs(self) do self[k] = nil end - self = nil - end - - return fireRune, iceRune, criticalRune -end - --- 2. 设置符文效果 -local function setupRuneEffects(fireRune, iceRune, criticalRune) - -- 火焰符文:增加50%伤害 - EventFilter.SubscribeGlobalFilter("OnAttack", function(eventData) - print("🔥 火焰符文生效:伤害 +50%") - eventData.damage = eventData.damage * 1.5 - eventData.element = "fire" - return eventData - end, 10, fireRune) -- 优先级10,所有者是fireRune - - -- 冰霜符文:增加30%伤害,有概率冰冻 - EventFilter.SubscribeGlobalFilter("OnAttack", function(eventData) - print("❄️ 冰霜符文生效:伤害 +30%") - eventData.damage = eventData.damage * 1.3 - eventData.element = "ice" - - -- 20%概率冰冻 - if math.random() < 0.2 then - eventData.freeze = true - print(" 💎 触发冰冻效果!") - end - - return eventData - end, 8, iceRune) -- 优先级8,所有者是iceRune - - -- 暴击符文:30%概率暴击 - EventFilter.SubscribeGlobalFilter("OnAttack", function(eventData) - if math.random() < 0.3 then - print("⚡ 暴击符文生效:暴击!") - eventData.damage = eventData.damage * 2 - eventData.isCritical = true - end - return eventData - end, 5, criticalRune) -- 优先级5,所有者是criticalRune -end - --- 3. 监听最终结果 -local function setupResultListener() - EventFilter.SubscribeGlobal("OnAttack", function(finalData) - print("=== 最终攻击结果 ===") - print("伤害:", finalData.damage) - print("元素:", finalData.element or "无") - print("暴击:", finalData.isCritical and "是" or "否") - print("冰冻:", finalData.freeze and "是" or "否") - print("==================") - end) -end - --- 4. 发送攻击事件 -local function sendAttackEvent() - local attackData = { - damage = 100, - attacker = "玩家", - target = "敌人" - } - - print("🗡️ 发送攻击事件,基础伤害:", attackData.damage) - - EventFilter.FireGlobalWithFilter("OnAttack", attackData, function(processedData) - print("✅ 攻击事件处理完成!") - -- 这里可以执行实际的攻击逻辑 - -- 比如:DealDamage(processedData.damage, processedData.target) - end) -end - --- ===== 演示自动回收 ===== - -local function demonstrateAutoCleanup() - print("\n=== 演示自动回收 ===") - - -- 第一次攻击:所有符文生效 - print("\n第一次攻击(所有符文生效):") - sendAttackEvent() - - -- 销毁火焰符文 - print("\n销毁火焰符文...") - fireRune:Destroy() - - -- 第二次攻击:只有冰霜和暴击符文生效 - print("\n第二次攻击(冰霜+暴击符文生效):") - sendAttackEvent() - - -- 销毁冰霜符文 - print("\n销毁冰霜符文...") - iceRune:Destroy() - - -- 第三次攻击:只有暴击符文生效 - print("\n第三次攻击(只有暴击符文生效):") - sendAttackEvent() - - -- 销毁暴击符文 - print("\n销毁暴击符文...") - criticalRune:Destroy() - - -- 第四次攻击:没有符文生效 - print("\n第四次攻击(没有符文生效):") - sendAttackEvent() -end - --- ===== 实际游戏场景示例 ===== - -local function gameSceneExample() - print("\n=== 实际游戏场景示例 ===") - - -- 模拟玩家攻击 - local function playerAttack() - local attackData = { - damage = 80, - attackType = "melee", - attacker = game.Players.LocalPlayer, - target = nil, -- 目标敌人 - weaponType = "sword" - } - - print("玩家发起攻击...") - - -- 发送攻击事件,让符文系统处理 - EventFilter.FireGlobalWithFilter("OnAttack", attackData, function(finalData) - print("执行攻击:", finalData.damage, "点伤害") - - -- 应用元素效果 - if finalData.element == "fire" then - print("🔥 造成燃烧效果") - elseif finalData.element == "ice" then - print("❄️ 造成冰冻效果") - end - - -- 应用暴击效果 - if finalData.isCritical then - print("⚡ 暴击!") - end - - -- 应用冰冻效果 - if finalData.freeze then - print("💎 目标被冰冻!") - end - end) - end - - -- 执行攻击 - playerAttack() -end - --- ===== 主函数:完整演示 ===== - -local function runCompleteExample() - print("=== EventFilter使用示例 ===") - - -- 1. 创建符文 - local fireRune, iceRune, criticalRune = createRunes() - print("创建了三个符文") - - -- 2. 设置符文效果 - setupRuneEffects(fireRune, iceRune, criticalRune) - print("设置了符文效果") - - -- 3. 设置结果监听 - setupResultListener() - print("设置了结果监听") - - -- 4. 演示自动回收 - demonstrateAutoCleanup() - - -- 5. 实际游戏场景 - gameSceneExample() - - print("\n=== 示例完成 ===") -end - --- ===== 导出函数 ===== - -return { - runCompleteExample = runCompleteExample, - createRunes = createRunes, - setupRuneEffects = setupRuneEffects, - sendAttackEvent = sendAttackEvent, - demonstrateAutoCleanup = demonstrateAutoCleanup, - gameSceneExample = gameSceneExample -} diff --git a/src/ServerStorage/Base/Rune.luau b/src/ServerStorage/Base/Rune.luau index f5922e5..bdd9a12 100644 --- a/src/ServerStorage/Base/Rune.luau +++ b/src/ServerStorage/Base/Rune.luau @@ -151,6 +151,9 @@ end -- 销毁 function Rune:OnDestroy() self.executionRecords = nil + for _, data in self do + data = nil + end self = nil end diff --git a/src/ServerStorage/Modules/Behaviours/Attack.luau b/src/ServerStorage/Modules/Behaviours/Attack.luau index 958edaf..acda124 100644 --- a/src/ServerStorage/Modules/Behaviours/Attack.luau +++ b/src/ServerStorage/Modules/Behaviours/Attack.luau @@ -12,6 +12,10 @@ local DamageProxy = require(ServerStorage.Proxy.DamageProxy) local Utils = require(ReplicatedStorage.Tools.Utils) local Rng = require(ReplicatedStorage.Tools.Rng) +--> EventFilter +local EventFilter = require(ReplicatedStorage.Modules.EventFilter) +local EventFilterEnum = require(ReplicatedStorage.Data.EventFilterEnum) + -------------------------------------------------------------------------------- local Attack = {} @@ -123,6 +127,15 @@ function Attack:Execute() }) end end + + -- 发送事件 + EventFilter.FireGlobalWithFilter(EventFilterEnum.BEFORE_ATTACK, { + attacker = self.Character, + target = self.CheckData["ClosestCharacter"], + damageData = damageData, + }, function(processedData) + damageData = processedData.damageData + end) DamageProxy:TakeDamage(self.Character, self.CheckData["ClosestCharacter"], damageData) -- task.wait(atkSpeed / 2) diff --git a/src/ServerStorage/Modules/Runes/RuneBookQualityPurple.luau b/src/ServerStorage/Modules/Runes/RuneBookQualityPurple.luau index 7068627..361ac2f 100644 --- a/src/ServerStorage/Modules/Runes/RuneBookQualityPurple.luau +++ b/src/ServerStorage/Modules/Runes/RuneBookQualityPurple.luau @@ -20,10 +20,6 @@ function RuneBookQualityPurple:Init(PlayerAI, Character: TypeList.Character) end function RuneBookQualityPurple:Check(index: number, AttributesData: table, BehaviorNameList: table) - return true -end - -function RuneBookQualityPurple:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) local pDataFolder = ReplicatedStorage:FindFirstChild("PlayerData") if not pDataFolder then return nil end local pData = pDataFolder:FindFirstChild(self.PlayerAI.Player.UserId) @@ -34,8 +30,14 @@ function RuneBookQualityPurple:OnExecute(index: number, AttributesData: table, B local bookList = bookFolder:GetChildren() if #bookList == 0 then return nil end + self.Data = bookList + + return true +end + +function RuneBookQualityPurple:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) local qualityNumber = 0 - for _, book in bookList do + for _, book in self.Data do local bookQuality = book:GetAttribute("quality") if bookQuality >= 3 then qualityNumber = qualityNumber + 1 diff --git a/src/ServerStorage/Modules/Runes/RuneBossAtk.luau b/src/ServerStorage/Modules/Runes/RuneBossAtk.luau new file mode 100644 index 0000000..82af640 --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RuneBossAtk.luau @@ -0,0 +1,51 @@ +--> Services +local ReplicatedStorage = game:GetService("ReplicatedStorage") +local ServerStorage = game:GetService("ServerStorage") + +--> Dependencies +local Utils = require(ReplicatedStorage.Tools.Utils) +local TypeList = require(ServerStorage.Base.TypeList) +local Rune = require(ServerStorage.Base.Rune) + +--> Json +local JsonLevel = require(ReplicatedStorage.Json.Level) + +local RuneBossAtk = {} +RuneBossAtk.__index = RuneBossAtk +setmetatable(RuneBossAtk, {__index = Rune}) + + +function RuneBossAtk:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RuneBossAtk) + + return self +end + +function RuneBossAtk:Check(index: number, AttributesData: table, BehaviorNameList: table) + local LevelFolder = game.Workspace:FindFirstChild("Level") + if not LevelFolder then return nil end + + local pLevelFolder = LevelFolder:FindFirstChild(self.PlayerAI.Player.UserId) + if not pLevelFolder then return nil end + + local pChallengeFolder = pLevelFolder:FindFirstChild("Challenge") + if not pChallengeFolder then return nil end + + local pLevelId = pChallengeFolder:FindFirstChild("LevelId") + if not pLevelId then return nil end + + local LevelData = Utils:GetIdDataFromJson(JsonLevel, pLevelId.Value) + if tostring(LevelData.type) ~= "2" then return nil end + return true +end + +function RuneBossAtk:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) + local baseAttribute = AttributesData.attackRate or 100 + local addAttribute = math.floor(baseAttribute * 50 / 100) + Utils:TableSafeAddValue(AttributesData, "attackRate", addAttribute) + return nil +end + + +return RuneBossAtk \ No newline at end of file diff --git a/src/ServerStorage/Modules/Runes/RuneBossHp.luau b/src/ServerStorage/Modules/Runes/RuneBossHp.luau new file mode 100644 index 0000000..a4c646f --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RuneBossHp.luau @@ -0,0 +1,51 @@ +--> Services +local ReplicatedStorage = game:GetService("ReplicatedStorage") +local ServerStorage = game:GetService("ServerStorage") + +--> Dependencies +local Utils = require(ReplicatedStorage.Tools.Utils) +local TypeList = require(ServerStorage.Base.TypeList) +local Rune = require(ServerStorage.Base.Rune) + +--> Json +local JsonLevel = require(ReplicatedStorage.Json.Level) + +local RuneBossHp = {} +RuneBossHp.__index = RuneBossHp +setmetatable(RuneBossHp, {__index = Rune}) + + +function RuneBossHp:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RuneBossHp) + + return self +end + +function RuneBossHp:Check(index: number, AttributesData: table, BehaviorNameList: table) + local LevelFolder = game.Workspace:FindFirstChild("Level") + if not LevelFolder then return nil end + + local pLevelFolder = LevelFolder:FindFirstChild(self.PlayerAI.Player.UserId) + if not pLevelFolder then return nil end + + local pChallengeFolder = pLevelFolder:FindFirstChild("Challenge") + if not pChallengeFolder then return nil end + + local pLevelId = pChallengeFolder:FindFirstChild("LevelId") + if not pLevelId then return nil end + + local LevelData = Utils:GetIdDataFromJson(JsonLevel, pLevelId.Value) + if tostring(LevelData.type) ~= "2" then return nil end + return true +end + +function RuneBossHp:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) + local baseAttribute = AttributesData.hpRate or 100 + local addAttribute = math.floor(baseAttribute * 50 / 100) + Utils:TableSafeAddValue(AttributesData, "hpRate", addAttribute) + return nil +end + + +return RuneBossHp \ No newline at end of file diff --git a/src/ServerStorage/Modules/Runes/RuneFirstAttack.luau b/src/ServerStorage/Modules/Runes/RuneFirstAttack.luau new file mode 100644 index 0000000..f93fcf6 --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RuneFirstAttack.luau @@ -0,0 +1,47 @@ +--> Services +local ReplicatedStorage = game:GetService("ReplicatedStorage") +local ServerStorage = game:GetService("ServerStorage") + +--> Dependencies +local Utils = require(ReplicatedStorage.Tools.Utils) +local TypeList = require(ServerStorage.Base.TypeList) +local Rune = require(ServerStorage.Base.Rune) + +--> EventFilter +local EventFilter = require(ReplicatedStorage.Modules.EventFilter) +local EventFilterEnum = require(ReplicatedStorage.Data.EventFilterEnum) + + +local RuneFirstAttack = {} +RuneFirstAttack.__index = RuneFirstAttack +setmetatable(RuneFirstAttack, {__index = Rune}) + + +function RuneFirstAttack:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RuneFirstAttack) + self.FirstAttack = true + + EventFilter.SubscribeGlobalFilter(EventFilterEnum.BEFORE_ATTACK, function(eventData) + if self.FirstAttack then + self.FirstAttack = false + for _, damageData in eventData.damageData do + damageData.Damage = damageData.Damage * 3 + end + end + return eventData + end, 10, self) + + return self +end + +function RuneFirstAttack:Check(index: number, AttributesData: table, BehaviorNameList: table) + return true +end + +function RuneFirstAttack:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) + return nil +end + + +return RuneFirstAttack \ No newline at end of file diff --git a/src/ServerStorage/Modules/Runes/RuneHpToAtk.luau b/src/ServerStorage/Modules/Runes/RuneHpToAtk.luau new file mode 100644 index 0000000..ca038d4 --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RuneHpToAtk.luau @@ -0,0 +1,37 @@ +--> Services +local ReplicatedStorage = game:GetService("ReplicatedStorage") +local ServerStorage = game:GetService("ServerStorage") + +--> Dependencies +local Utils = require(ReplicatedStorage.Tools.Utils) +local TypeList = require(ServerStorage.Base.TypeList) +local Rune = require(ServerStorage.Base.Rune) + +--> Json +local JsonLevel = require(ReplicatedStorage.Json.Level) + +local RuneHpToAtk = {} +RuneHpToAtk.__index = RuneHpToAtk +setmetatable(RuneHpToAtk, {__index = Rune}) + + +function RuneHpToAtk:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RuneHpToAtk) + + return self +end + +function RuneHpToAtk:Check(index: number, AttributesData: table, BehaviorNameList: table) + return true +end + +function RuneHpToAtk:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) + local baseAttribute = AttributesData.atkRate or 100 + local addAttribute = math.floor(baseAttribute * AttributesData.hp * 0.035) + Utils:TableSafeAddValue(AttributesData, "atkRate", addAttribute) + return nil +end + + +return RuneHpToAtk \ No newline at end of file diff --git a/src/ServerStorage/Modules/Runes/RuneKillEnemyHeal.luau b/src/ServerStorage/Modules/Runes/RuneKillEnemyHeal.luau new file mode 100644 index 0000000..185e128 --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RuneKillEnemyHeal.luau @@ -0,0 +1,47 @@ +--> Services +local ReplicatedStorage = game:GetService("ReplicatedStorage") +local ServerStorage = game:GetService("ServerStorage") + +--> Dependencies +local Utils = require(ReplicatedStorage.Tools.Utils) +local TypeList = require(ServerStorage.Base.TypeList) +local Rune = require(ServerStorage.Base.Rune) + +--> DamageProxy +local DamageProxy = require(ServerStorage.Proxy.DamageProxy) + +--> EventFilter +local EventFilter = require(ReplicatedStorage.Modules.EventFilter) +local EventFilterEnum = require(ReplicatedStorage.Data.EventFilterEnum) + + +local RuneKillEnemyHeal = {} +RuneKillEnemyHeal.__index = RuneKillEnemyHeal +setmetatable(RuneKillEnemyHeal, {__index = Rune}) + + +function RuneKillEnemyHeal:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RuneKillEnemyHeal) + self.FirstAttack = true + + EventFilter.SubscribeGlobalFilter(EventFilterEnum.BEFORE_KILL_MONSTER, function(eventData) + if self.FirstAttack then + self.FirstAttack = false + DamageProxy:Heal(PlayerAI, PlayerAI, math.floor(self.Character.Config.maxhp * 0.01)) + end + end, 10, self) + + return self +end + +function RuneKillEnemyHeal:Check(index: number, AttributesData: table, BehaviorNameList: table) + return true +end + +function RuneKillEnemyHeal:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) + return nil +end + + +return RuneKillEnemyHeal \ No newline at end of file diff --git a/src/ServerStorage/Modules/Runes/RuneWearElementAttack.luau b/src/ServerStorage/Modules/Runes/RuneWearElementAttack.luau index 6d4252b..44a46e1 100644 --- a/src/ServerStorage/Modules/Runes/RuneWearElementAttack.luau +++ b/src/ServerStorage/Modules/Runes/RuneWearElementAttack.luau @@ -42,7 +42,7 @@ function RuneWearElementAttack:OnExecute(index: number, AttributesData: table, B end end - local attackRate = math.floor(elementNumber * 25 / 100) + local attackRate = math.floor((AttributesData.attackRate or 100) * elementNumber * 25 / 100) Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate) return nil diff --git a/src/ServerStorage/Modules/Runes/RuneWearEmptySlot.luau b/src/ServerStorage/Modules/Runes/RuneWearEmptySlot.luau index 6c4508a..999744d 100644 --- a/src/ServerStorage/Modules/Runes/RuneWearEmptySlot.luau +++ b/src/ServerStorage/Modules/Runes/RuneWearEmptySlot.luau @@ -60,7 +60,7 @@ function RuneWearEmptySlot:OnExecute(index: number, AttributesData: table, Behav end end - local attackRate = math.floor((maxRuneNumber - hasSlotNumber) * 25 / 100) + local attackRate = math.floor((AttributesData.attackRate or 100) * (maxRuneNumber - hasSlotNumber) * 25 / 100) Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate) return nil diff --git a/src/ServerStorage/Modules/Runes/RuneWearExAttributeAttack.luau b/src/ServerStorage/Modules/Runes/RuneWearExAttributeAttack.luau new file mode 100644 index 0000000..b3e249c --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RuneWearExAttributeAttack.luau @@ -0,0 +1,52 @@ +--> Services +local ReplicatedStorage = game:GetService("ReplicatedStorage") +local ServerStorage = game:GetService("ServerStorage") + +--> Dependencies +local Utils = require(ReplicatedStorage.Tools.Utils) +local TypeList = require(ServerStorage.Base.TypeList) +local Rune = require(ServerStorage.Base.Rune) + +local RuneWearExAttributeAttack = {} +RuneWearExAttributeAttack.__index = RuneWearExAttributeAttack +setmetatable(RuneWearExAttributeAttack, {__index = Rune}) + + +function RuneWearExAttributeAttack:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RuneWearExAttributeAttack) + + return self +end + +function RuneWearExAttributeAttack:Check(index: number, AttributesData: table, BehaviorNameList: table) + return true +end + +function RuneWearExAttributeAttack:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) + local pDataFolder = ReplicatedStorage:FindFirstChild("PlayerData") + if not pDataFolder then return nil end + local pData = pDataFolder:FindFirstChild(self.PlayerAI.Player.UserId) + if not pData then return nil end + + local equipmentFolder = pData:FindFirstChild("Equipment") + if not equipmentFolder then return nil end + local equipmentList = equipmentFolder:GetChildren() + if #equipmentList == 0 then return nil end + + local elementNumber = 0 + for _, equipment in equipmentList do + local equipmentWearing = equipment:GetAttribute("wearing") + if equipmentWearing > 0 then + elementNumber = elementNumber + #equipment:FindFirstChild("exAttributes"):GetAttributes() + end + end + + local attackRate = math.floor((AttributesData.attackRate or 100) * elementNumber * 25 / 100) + Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate) + + return nil +end + + +return RuneWearExAttributeAttack \ No newline at end of file diff --git a/src/ServerStorage/Modules/Runes/RuneWearFillSlot.luau b/src/ServerStorage/Modules/Runes/RuneWearFillSlot.luau index ae8085a..521004d 100644 --- a/src/ServerStorage/Modules/Runes/RuneWearFillSlot.luau +++ b/src/ServerStorage/Modules/Runes/RuneWearFillSlot.luau @@ -60,7 +60,7 @@ function RuneWearFillSlot:OnExecute(index: number, AttributesData: table, Behavi end end - local attackRate = math.floor(hasSlotNumber * 25 / 100) + local attackRate = math.floor((AttributesData.attackRate or 100) * hasSlotNumber * 25 / 100) Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate) return nil diff --git a/src/ServerStorage/Modules/Runes/RuneWearHeavySword.luau b/src/ServerStorage/Modules/Runes/RuneWearHeavySword.luau index 4fe1976..8de30b3 100644 --- a/src/ServerStorage/Modules/Runes/RuneWearHeavySword.luau +++ b/src/ServerStorage/Modules/Runes/RuneWearHeavySword.luau @@ -50,7 +50,7 @@ function RuneWearHeavySword:OnExecute(index: number, AttributesData: table, Beha subTypeNumber = subTypeNumber + self.PlayerAI:GetSharedData(CheckShareName) end - local attackRate = math.floor(subTypeNumber * 25 / 100) + local attackRate = math.floor((AttributesData.attackRate or 100) * subTypeNumber * 25 / 100) Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate) return nil diff --git a/src/ServerStorage/Modules/Runes/RuneWearKnife.luau b/src/ServerStorage/Modules/Runes/RuneWearKnife.luau index c930bba..bffcd68 100644 --- a/src/ServerStorage/Modules/Runes/RuneWearKnife.luau +++ b/src/ServerStorage/Modules/Runes/RuneWearKnife.luau @@ -50,7 +50,7 @@ function RuneWearKnife:OnExecute(index: number, AttributesData: table, BehaviorN subTypeNumber = subTypeNumber + self.PlayerAI:GetSharedData(CheckShareName) end - local attackRate = math.floor(subTypeNumber * 25 / 100) + local attackRate = math.floor((AttributesData.attackRate or 100) * subTypeNumber * 25 / 100) Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate) return nil diff --git a/src/ServerStorage/Modules/Runes/RuneWearStick.luau b/src/ServerStorage/Modules/Runes/RuneWearStick.luau index ecdcf39..4aa1a87 100644 --- a/src/ServerStorage/Modules/Runes/RuneWearStick.luau +++ b/src/ServerStorage/Modules/Runes/RuneWearStick.luau @@ -50,7 +50,7 @@ function RuneWearStick:OnExecute(index: number, AttributesData: table, BehaviorN subTypeNumber = subTypeNumber + self.PlayerAI:GetSharedData(CheckShareName) end - local attackRate = math.floor(subTypeNumber * 25 / 100) + local attackRate = math.floor((AttributesData.attackRate or 100) * subTypeNumber * 25 / 100) Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate) return nil diff --git a/src/ServerStorage/Modules/Runes/RuneWearSword.luau b/src/ServerStorage/Modules/Runes/RuneWearSword.luau index 7a49424..b0ee014 100644 --- a/src/ServerStorage/Modules/Runes/RuneWearSword.luau +++ b/src/ServerStorage/Modules/Runes/RuneWearSword.luau @@ -50,7 +50,7 @@ function RuneWearSword:OnExecute(index: number, AttributesData: table, BehaviorN subTypeNumber = subTypeNumber + self.PlayerAI:GetSharedData(CheckShareName) end - local attackRate = math.floor(subTypeNumber * 25 / 100) + local attackRate = math.floor((AttributesData.attackRate or 100) * subTypeNumber * 25 / 100) Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate) return nil diff --git a/src/ServerStorage/Proxy/MobsProxy/init.luau b/src/ServerStorage/Proxy/MobsProxy/init.luau index df05089..91baf10 100644 --- a/src/ServerStorage/Proxy/MobsProxy/init.luau +++ b/src/ServerStorage/Proxy/MobsProxy/init.luau @@ -15,6 +15,10 @@ local TypeList = require(ServerStorage.Base.TypeList) --> Json local JsonMob = require(ReplicatedStorage.Json.Enemy) +--> EventFilter +local EventFilter = require(ReplicatedStorage.Modules.EventFilter) +local EventFilterEnum = require(ReplicatedStorage.Data.EventFilterEnum) + --> Constants -------------------------------------------------------------------------------- @@ -87,6 +91,12 @@ function Mob:Died(isChallengeFailed: boolean?) MobsProxy:RemoveMob(self.Player, self.Instance) if not isChallengeFailed then if self.OnDied then self.OnDied(self.Player, self) end + else + -- 发送怪物死亡事件 + EventFilter.FireGlobalWithFilter(EventFilterEnum.BEFORE_KILL_MONSTER, { + attacker = self.Player, + target = self, + }) end Character.Died(self) end