更新
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()
|
function Rune:OnDestroy()
|
||||||
self.executionRecords = nil
|
self.executionRecords = nil
|
||||||
|
for _, data in self do
|
||||||
|
data = nil
|
||||||
|
end
|
||||||
self = nil
|
self = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -12,6 +12,10 @@ local DamageProxy = require(ServerStorage.Proxy.DamageProxy)
|
|||||||
local Utils = require(ReplicatedStorage.Tools.Utils)
|
local Utils = require(ReplicatedStorage.Tools.Utils)
|
||||||
local Rng = require(ReplicatedStorage.Tools.Rng)
|
local Rng = require(ReplicatedStorage.Tools.Rng)
|
||||||
|
|
||||||
|
--> EventFilter
|
||||||
|
local EventFilter = require(ReplicatedStorage.Modules.EventFilter)
|
||||||
|
local EventFilterEnum = require(ReplicatedStorage.Data.EventFilterEnum)
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
local Attack = {}
|
local Attack = {}
|
||||||
@ -123,6 +127,15 @@ function Attack:Execute()
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
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)
|
DamageProxy:TakeDamage(self.Character, self.CheckData["ClosestCharacter"], damageData)
|
||||||
|
|
||||||
-- task.wait(atkSpeed / 2)
|
-- task.wait(atkSpeed / 2)
|
||||||
|
@ -20,10 +20,6 @@ function RuneBookQualityPurple:Init(PlayerAI, Character: TypeList.Character)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function RuneBookQualityPurple:Check(index: number, AttributesData: table, BehaviorNameList: table)
|
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")
|
local pDataFolder = ReplicatedStorage:FindFirstChild("PlayerData")
|
||||||
if not pDataFolder then return nil end
|
if not pDataFolder then return nil end
|
||||||
local pData = pDataFolder:FindFirstChild(self.PlayerAI.Player.UserId)
|
local pData = pDataFolder:FindFirstChild(self.PlayerAI.Player.UserId)
|
||||||
@ -34,8 +30,14 @@ function RuneBookQualityPurple:OnExecute(index: number, AttributesData: table, B
|
|||||||
local bookList = bookFolder:GetChildren()
|
local bookList = bookFolder:GetChildren()
|
||||||
if #bookList == 0 then return nil end
|
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
|
local qualityNumber = 0
|
||||||
for _, book in bookList do
|
for _, book in self.Data do
|
||||||
local bookQuality = book:GetAttribute("quality")
|
local bookQuality = book:GetAttribute("quality")
|
||||||
if bookQuality >= 3 then
|
if bookQuality >= 3 then
|
||||||
qualityNumber = qualityNumber + 1
|
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
|
||||||
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)
|
Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -60,7 +60,7 @@ function RuneWearEmptySlot:OnExecute(index: number, AttributesData: table, Behav
|
|||||||
end
|
end
|
||||||
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)
|
Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate)
|
||||||
|
|
||||||
return nil
|
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
|
||||||
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)
|
Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -50,7 +50,7 @@ function RuneWearHeavySword:OnExecute(index: number, AttributesData: table, Beha
|
|||||||
subTypeNumber = subTypeNumber + self.PlayerAI:GetSharedData(CheckShareName)
|
subTypeNumber = subTypeNumber + self.PlayerAI:GetSharedData(CheckShareName)
|
||||||
end
|
end
|
||||||
|
|
||||||
local attackRate = math.floor(subTypeNumber * 25 / 100)
|
local attackRate = math.floor((AttributesData.attackRate or 100) * subTypeNumber * 25 / 100)
|
||||||
Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate)
|
Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -50,7 +50,7 @@ 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(subTypeNumber * 25 / 100)
|
local attackRate = math.floor((AttributesData.attackRate or 100) * subTypeNumber * 25 / 100)
|
||||||
Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate)
|
Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -50,7 +50,7 @@ function RuneWearStick:OnExecute(index: number, AttributesData: table, BehaviorN
|
|||||||
subTypeNumber = subTypeNumber + self.PlayerAI:GetSharedData(CheckShareName)
|
subTypeNumber = subTypeNumber + self.PlayerAI:GetSharedData(CheckShareName)
|
||||||
end
|
end
|
||||||
|
|
||||||
local attackRate = math.floor(subTypeNumber * 25 / 100)
|
local attackRate = math.floor((AttributesData.attackRate or 100) * subTypeNumber * 25 / 100)
|
||||||
Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate)
|
Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -50,7 +50,7 @@ function RuneWearSword:OnExecute(index: number, AttributesData: table, BehaviorN
|
|||||||
subTypeNumber = subTypeNumber + self.PlayerAI:GetSharedData(CheckShareName)
|
subTypeNumber = subTypeNumber + self.PlayerAI:GetSharedData(CheckShareName)
|
||||||
end
|
end
|
||||||
|
|
||||||
local attackRate = math.floor(subTypeNumber * 25 / 100)
|
local attackRate = math.floor((AttributesData.attackRate or 100) * subTypeNumber * 25 / 100)
|
||||||
Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate)
|
Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -15,6 +15,10 @@ local TypeList = require(ServerStorage.Base.TypeList)
|
|||||||
--> Json
|
--> Json
|
||||||
local JsonMob = require(ReplicatedStorage.Json.Enemy)
|
local JsonMob = require(ReplicatedStorage.Json.Enemy)
|
||||||
|
|
||||||
|
--> EventFilter
|
||||||
|
local EventFilter = require(ReplicatedStorage.Modules.EventFilter)
|
||||||
|
local EventFilterEnum = require(ReplicatedStorage.Data.EventFilterEnum)
|
||||||
|
|
||||||
--> Constants
|
--> Constants
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
@ -87,6 +91,12 @@ function Mob:Died(isChallengeFailed: boolean?)
|
|||||||
MobsProxy:RemoveMob(self.Player, self.Instance)
|
MobsProxy:RemoveMob(self.Player, self.Instance)
|
||||||
if not isChallengeFailed then
|
if not isChallengeFailed then
|
||||||
if self.OnDied then self.OnDied(self.Player, self) end
|
if self.OnDied then self.OnDied(self.Player, self) end
|
||||||
|
else
|
||||||
|
-- 发送怪物死亡事件
|
||||||
|
EventFilter.FireGlobalWithFilter(EventFilterEnum.BEFORE_KILL_MONSTER, {
|
||||||
|
attacker = self.Player,
|
||||||
|
target = self,
|
||||||
|
})
|
||||||
end
|
end
|
||||||
Character.Died(self)
|
Character.Died(self)
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user