更新
This commit is contained in:
parent
ed086039a1
commit
532dab80a0
BIN
excel/Rune.xlsx
BIN
excel/Rune.xlsx
Binary file not shown.
10
src/ReplicatedStorage/Data/EventFilterEnum.luau
Normal file
10
src/ReplicatedStorage/Data/EventFilterEnum.luau
Normal file
@ -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
|
@ -1,7 +0,0 @@
|
||||
local ServerSignalEnum = {}
|
||||
|
||||
ServerSignalEnum = {
|
||||
SHOW_ABILITY = "SHOW_ABILITY",
|
||||
}
|
||||
|
||||
return ServerSignalEnum
|
@ -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
|
||||
}
|
@ -151,6 +151,9 @@ end
|
||||
-- 销毁
|
||||
function Rune:OnDestroy()
|
||||
self.executionRecords = nil
|
||||
for _, data in self do
|
||||
data = nil
|
||||
end
|
||||
self = nil
|
||||
end
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
51
src/ServerStorage/Modules/Runes/RuneBossAtk.luau
Normal file
51
src/ServerStorage/Modules/Runes/RuneBossAtk.luau
Normal file
@ -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
|
51
src/ServerStorage/Modules/Runes/RuneBossHp.luau
Normal file
51
src/ServerStorage/Modules/Runes/RuneBossHp.luau
Normal file
@ -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
|
47
src/ServerStorage/Modules/Runes/RuneFirstAttack.luau
Normal file
47
src/ServerStorage/Modules/Runes/RuneFirstAttack.luau
Normal file
@ -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
|
37
src/ServerStorage/Modules/Runes/RuneHpToAtk.luau
Normal file
37
src/ServerStorage/Modules/Runes/RuneHpToAtk.luau
Normal file
@ -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
|
47
src/ServerStorage/Modules/Runes/RuneKillEnemyHeal.luau
Normal file
47
src/ServerStorage/Modules/Runes/RuneKillEnemyHeal.luau
Normal file
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user