diff --git a/excel/Rune.xlsx b/excel/Rune.xlsx index 5ef1a1e..70236d8 100644 Binary files a/excel/Rune.xlsx and b/excel/Rune.xlsx differ diff --git a/excel/ability.xlsx b/excel/ability.xlsx index 8e6459d..d4a6477 100644 Binary files a/excel/ability.xlsx and b/excel/ability.xlsx differ diff --git a/excel/attribute.xlsx b/excel/attribute.xlsx index 7827a40..d347a10 100644 Binary files a/excel/attribute.xlsx and b/excel/attribute.xlsx differ diff --git a/excel/item.xlsx b/excel/item.xlsx index c4725b8..2d716dd 100644 Binary files a/excel/item.xlsx and b/excel/item.xlsx differ diff --git a/src/ReplicatedStorage/Data/EventFilterEnum.luau b/src/ReplicatedStorage/Data/EventFilterEnum.luau index dc644cc..647546c 100644 --- a/src/ReplicatedStorage/Data/EventFilterEnum.luau +++ b/src/ReplicatedStorage/Data/EventFilterEnum.luau @@ -2,9 +2,10 @@ local ServerSignalEnum = {} ServerSignalEnum = { BEFORE_ATTACK = "BEFORE_ATTACK", - -- AFTER_ATTACK = "AFTER_ATTACK", + AFTER_ATTACK = "AFTER_ATTACK", -- BEFORE_KILL_MONSTER = "BEFORE_KILL_MONSTER", BEFORE_KILL_MONSTER = "BEFORE_KILL_MONSTER", + BEFORE_HEAL = "BEFORE_HEAL", } return ServerSignalEnum \ No newline at end of file diff --git a/src/ReplicatedStorage/Json/Ability.json b/src/ReplicatedStorage/Json/Ability.json index c24fb01..8aff23f 100644 --- a/src/ReplicatedStorage/Json/Ability.json +++ b/src/ReplicatedStorage/Json/Ability.json @@ -1,5 +1,5 @@ [ -{"id":20000,"type":1,"icon":1,"nameId":20000,"behaviourName":"Attack","upgradeCost":[30000,5,0],"upgradeValue":[10,0],"recycle":[30000,0],"isInPool":null}, -{"id":20001,"type":1,"icon":1,"nameId":20001,"behaviourName":"SwordWave","upgradeCost":[30000,5,10],"upgradeValue":[10,200],"recycle":[30000,100],"isInPool":1}, -{"id":61000,"type":1,"icon":1,"nameId":61000,"behaviourName":"IceCoffine","upgradeCost":[30000,5,0],"upgradeValue":[10,0],"recycle":[30000,0],"isInPool":null} +{"id":20000,"type":1,"castType":null,"icon":1,"nameId":20000,"behaviourName":"Attack","upgradeCost":[30000,5,0],"upgradeValue":[10,0],"recycle":[30000,0],"isInPool":null}, +{"id":20001,"type":1,"castType":1,"icon":1,"nameId":20001,"behaviourName":"SwordWave","upgradeCost":[30000,5,10],"upgradeValue":[10,200],"recycle":[30000,100],"isInPool":1}, +{"id":61000,"type":1,"castType":1,"icon":1,"nameId":61000,"behaviourName":"IceCoffine","upgradeCost":[30000,5,0],"upgradeValue":[10,0],"recycle":[30000,0],"isInPool":null} ] \ No newline at end of file diff --git a/src/ReplicatedStorage/Json/Attributes.json b/src/ReplicatedStorage/Json/Attributes.json index 4e578ac..f472ebf 100644 --- a/src/ReplicatedStorage/Json/Attributes.json +++ b/src/ReplicatedStorage/Json/Attributes.json @@ -32,6 +32,7 @@ {"id":34,"type":2,"specialType":1,"effectAttribute":"critDamageRateIce","battleValue":[1,10],"iconId":27,"nameId":234}, {"id":35,"type":2,"specialType":1,"effectAttribute":"critDamageRateLight","battleValue":[1,10],"iconId":28,"nameId":235}, {"id":36,"type":2,"specialType":1,"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":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":52,"type":1,"specialType":null,"effectAttribute":"extraAttributeNumber","battleValue":[1,10],"iconId":52,"nameId":252}, diff --git a/src/ReplicatedStorage/Json/Rune.json b/src/ReplicatedStorage/Json/Rune.json index b1a366c..5dd1789 100644 --- a/src/ReplicatedStorage/Json/Rune.json +++ b/src/ReplicatedStorage/Json/Rune.json @@ -22,35 +22,34 @@ {"id":60020,"quality":1,"type":null,"icon":1,"nameId":60020,"runeName":"RuneBossHp","behaviorName":null,"recycle":[],"isInPool":1}, {"id":60021,"quality":1,"type":null,"icon":1,"nameId":60021,"runeName":"RuneHpToAtk","behaviorName":null,"recycle":[],"isInPool":1}, {"id":60022,"quality":1,"type":null,"icon":1,"nameId":60022,"runeName":"RuneAtkSpeed","behaviorName":null,"recycle":[],"isInPool":1}, -{"id":60023,"quality":1,"type":null,"icon":1,"nameId":60023,"runeName":"RuneThunderDoubleDamage","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":60023,"quality":1,"type":null,"icon":1,"nameId":60023,"runeName":"RuneThunderAddDamageTime","behaviorName":null,"recycle":[],"isInPool":1}, {"id":60024,"quality":1,"type":null,"icon":1,"nameId":60024,"runeName":"RuneWearElementAttackSpeed","behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61000,"quality":2,"type":1,"icon":1,"nameId":61000,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61001,"quality":2,"type":null,"icon":1,"nameId":61001,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61002,"quality":2,"type":null,"icon":1,"nameId":61002,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61003,"quality":2,"type":null,"icon":1,"nameId":61003,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61004,"quality":2,"type":null,"icon":1,"nameId":61004,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61005,"quality":2,"type":null,"icon":1,"nameId":61005,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61006,"quality":2,"type":null,"icon":1,"nameId":61006,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61007,"quality":2,"type":null,"icon":1,"nameId":61007,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61008,"quality":2,"type":null,"icon":1,"nameId":61008,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61009,"quality":2,"type":null,"icon":1,"nameId":61009,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61010,"quality":2,"type":null,"icon":1,"nameId":61010,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61011,"quality":2,"type":null,"icon":1,"nameId":61011,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61012,"quality":2,"type":null,"icon":1,"nameId":61012,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61013,"quality":2,"type":null,"icon":1,"nameId":61013,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61014,"quality":2,"type":null,"icon":1,"nameId":61014,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61015,"quality":2,"type":null,"icon":1,"nameId":61015,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61016,"quality":2,"type":null,"icon":1,"nameId":61016,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61017,"quality":2,"type":null,"icon":1,"nameId":61017,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61018,"quality":2,"type":null,"icon":1,"nameId":61018,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61019,"quality":2,"type":null,"icon":1,"nameId":61019,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61020,"quality":2,"type":null,"icon":1,"nameId":61020,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61021,"quality":2,"type":null,"icon":1,"nameId":61021,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61022,"quality":2,"type":null,"icon":1,"nameId":61022,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61023,"quality":2,"type":null,"icon":1,"nameId":61023,"runeName":"RuneIceCoffin","behaviorName":"IceCoffine","recycle":[],"isInPool":1}, -{"id":61024,"quality":2,"type":null,"icon":1,"nameId":61024,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61025,"quality":2,"type":null,"icon":1,"nameId":61025,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61026,"quality":2,"type":null,"icon":1,"nameId":61026,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, -{"id":61027,"quality":2,"type":null,"icon":1,"nameId":61027,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61000,"quality":2,"type":1,"icon":1,"nameId":61000,"runeName":"RuneThunderDoubleDamage","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61001,"quality":2,"type":null,"icon":1,"nameId":61001,"runeName":"RuneBookQualityYellow","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61002,"quality":2,"type":null,"icon":1,"nameId":61002,"runeName":"RuneCritToAttackRate","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61003,"quality":2,"type":null,"icon":1,"nameId":61003,"runeName":"RuneWearGenWeapon","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61004,"quality":2,"type":null,"icon":1,"nameId":61004,"runeName":"RuneNormalCritRate","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61005,"quality":2,"type":null,"icon":1,"nameId":61005,"runeName":"RuneWearSingleRuneSlot","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61006,"quality":2,"type":null,"icon":1,"nameId":61006,"runeName":"RuneSacrifice","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61007,"quality":2,"type":null,"icon":1,"nameId":61007,"runeName":"RuneNormalNoElement","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61008,"quality":2,"type":null,"icon":1,"nameId":61008,"runeName":"RuneKillCoin","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61009,"quality":2,"type":null,"icon":1,"nameId":61009,"runeName":"RuneBanActiveAbility","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61010,"quality":2,"type":null,"icon":1,"nameId":61010,"runeName":"RuneFirstElementCopy","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61011,"quality":2,"type":null,"icon":1,"nameId":61011,"runeName":"RuneLastElementCopy","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61012,"quality":2,"type":null,"icon":1,"nameId":61012,"runeName":"RuneNormalDamageToIce","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61013,"quality":2,"type":null,"icon":1,"nameId":61013,"runeName":"RuneAttackRecoverHp","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61014,"quality":2,"type":null,"icon":1,"nameId":61014,"runeName":"RuneIronBonus","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61015,"quality":2,"type":null,"icon":1,"nameId":61015,"runeName":"RuneActiveAbilityAttackRate","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61016,"quality":2,"type":null,"icon":1,"nameId":61016,"runeName":"RunePassiveAbilityAttackRate","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61017,"quality":2,"type":null,"icon":1,"nameId":61018,"runeName":"RuneLeftTrigger","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61018,"quality":2,"type":null,"icon":1,"nameId":61019,"runeName":"RuneRightTrigger","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61019,"quality":2,"type":null,"icon":1,"nameId":61020,"runeName":"RuneAllActiveAbility","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61020,"quality":2,"type":null,"icon":1,"nameId":61021,"runeName":"RuneAttack","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61021,"quality":2,"type":null,"icon":1,"nameId":61022,"runeName":"RuneHp","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61022,"quality":2,"type":null,"icon":1,"nameId":61023,"runeName":"RuneIceCoffin","behaviorName":"IceCoffine","recycle":[],"isInPool":1}, +{"id":61023,"quality":2,"type":null,"icon":1,"nameId":61024,"runeName":"RuneFirstHpDamage","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61024,"quality":2,"type":null,"icon":1,"nameId":61025,"runeName":"RuneHealCrit","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61025,"quality":2,"type":null,"icon":1,"nameId":61026,"runeName":"RuneCritRateDouble","behaviorName":null,"recycle":[],"isInPool":1}, +{"id":61026,"quality":2,"type":null,"icon":1,"nameId":61027,"runeName":"RuneAtkSpeedToAtkRate","behaviorName":null,"recycle":[],"isInPool":1}, {"id":62000,"quality":3,"type":1,"icon":1,"nameId":62000,"runeName":null,"behaviorName":null,"recycle":[],"isInPool":1} ] \ No newline at end of file diff --git a/src/ServerStorage/Base/Behaviour.luau b/src/ServerStorage/Base/Behaviour.luau index 45d1d11..fed72d9 100644 --- a/src/ServerStorage/Base/Behaviour.luau +++ b/src/ServerStorage/Base/Behaviour.luau @@ -122,6 +122,15 @@ function Behaviour:CheckStat() return false end +-- 检查特殊状态是否可执行(禁止使用技能) +function Behaviour:CheckSpecialStat() + if not self.Character then return true end + if self.PlayerAI:GetSharedData("BanAbility") then + return true + end + return false +end + -- 改变当前执行状态标记 function Behaviour:ChangeExecutingState(State: boolean) if not self.Character then warn("Behaviour Character not found") return end diff --git a/src/ServerStorage/Modules/Behaviours/Attack.luau b/src/ServerStorage/Modules/Behaviours/Attack.luau index acda124..c637d33 100644 --- a/src/ServerStorage/Modules/Behaviours/Attack.luau +++ b/src/ServerStorage/Modules/Behaviours/Attack.luau @@ -128,7 +128,7 @@ function Attack:Execute() end end - -- 发送事件 + -- 发送攻击前事件 EventFilter.FireGlobalWithFilter(EventFilterEnum.BEFORE_ATTACK, { attacker = self.Character, target = self.CheckData["ClosestCharacter"], @@ -137,6 +137,13 @@ function Attack:Execute() damageData = processedData.damageData end) DamageProxy:TakeDamage(self.Character, self.CheckData["ClosestCharacter"], damageData) + + -- 发送攻击后事件 + EventFilter.FireGlobalWithFilter(EventFilterEnum.AFTER_ATTACK, { + attacker = self.Character, + target = self.CheckData["ClosestCharacter"], + damageData = damageData, + }) -- task.wait(atkSpeed / 2) self:ChangeExecutingState(false) diff --git a/src/ServerStorage/Modules/Behaviours/IceCoffine.luau b/src/ServerStorage/Modules/Behaviours/IceCoffine.luau index 5dccc76..8e7639c 100644 --- a/src/ServerStorage/Modules/Behaviours/IceCoffine.luau +++ b/src/ServerStorage/Modules/Behaviours/IceCoffine.luau @@ -37,6 +37,7 @@ end function IceCoffine:Check(CheckInfo: table) if Behaviour.CheckStat(self) then return -1, self.CheckData end + if self:CheckSpecialStat() then return -1, self.CheckData end self:CheckClean() -- 当前血量<=20%时触发技能 diff --git a/src/ServerStorage/Modules/Behaviours/SwordWave.luau b/src/ServerStorage/Modules/Behaviours/SwordWave.luau index e8b9921..89b6ae2 100644 --- a/src/ServerStorage/Modules/Behaviours/SwordWave.luau +++ b/src/ServerStorage/Modules/Behaviours/SwordWave.luau @@ -37,6 +37,7 @@ end function SwordWave:Check(CheckInfo: table) if Behaviour.CheckStat(self) then return -1, self.CheckData end + if self:CheckSpecialStat() then return -1, self.CheckData end self:CheckClean() self.Mobs = MobsProxy:GetPlayerMobs(self.Player) diff --git a/src/ServerStorage/Modules/Runes/RuneActiveAbilityAttackRate.luau b/src/ServerStorage/Modules/Runes/RuneActiveAbilityAttackRate.luau new file mode 100644 index 0000000..e03688f --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RuneActiveAbilityAttackRate.luau @@ -0,0 +1,83 @@ +--> 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 Rng = require(ReplicatedStorage.Tools.Rng) + +--> Json +local JsonAbility = require(ReplicatedStorage.Json.Ability) + +local RuneActiveAbilityAttackRate = {} +RuneActiveAbilityAttackRate.__index = RuneActiveAbilityAttackRate +setmetatable(RuneActiveAbilityAttackRate, {__index = Rune}) + + +function RuneActiveAbilityAttackRate:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RuneActiveAbilityAttackRate) + + return self +end + +function RuneActiveAbilityAttackRate:Check(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 abilityFolder = pData:FindFirstChild("Ability") + if not abilityFolder then return nil end + local abilityList = abilityFolder:GetChildren() + if #abilityList == 0 then return nil end + + local wearingEquipmentList = {} + for _, equipment in equipmentList do + local equipmentWearing = equipment:GetAttribute("wearing") + if equipmentWearing > 0 then + table.insert(wearingEquipmentList, equipment.Name) + end + end + + self.Data = nil + self.Data = {} + for _, ability in abilityList do + local wearingEquipment = ability:GetAttribute("wearing") + if wearingEquipment > 0 then + if table.find(wearingEquipmentList, wearingEquipment) then + table.insert(self.Data, ability) + end + end + end + + return true +end + +function RuneActiveAbilityAttackRate:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) + local banAbilityNumber = 0 + for _, ability in self.Data do + local abilityId = ability:GetAttribute("orgId") + local abilityData = Utils:GetIdDataFromJson(JsonAbility, abilityId) + if abilityData.castType then + if abilityData.castType == 1 then + banAbilityNumber = banAbilityNumber + 1 + end + end + end + + local attackRate = math.floor((AttributesData.attackRate or 100) * banAbilityNumber * 50 / 100) + Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate) + + return nil +end + + +return RuneActiveAbilityAttackRate \ No newline at end of file diff --git a/src/ServerStorage/Modules/Runes/RuneAllActiveAbility.luau b/src/ServerStorage/Modules/Runes/RuneAllActiveAbility.luau new file mode 100644 index 0000000..6ff469f --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RuneAllActiveAbility.luau @@ -0,0 +1,88 @@ +--> 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 Rng = require(ReplicatedStorage.Tools.Rng) + +--> Json +local JsonAbility = require(ReplicatedStorage.Json.Ability) + +local RuneAllActiveAbility = {} +RuneAllActiveAbility.__index = RuneAllActiveAbility +setmetatable(RuneAllActiveAbility, {__index = Rune}) + + +function RuneAllActiveAbility:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RuneAllActiveAbility) + + return self +end + +function RuneAllActiveAbility:Check(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 abilityFolder = pData:FindFirstChild("Ability") + if not abilityFolder then return nil end + local abilityList = abilityFolder:GetChildren() + if #abilityList == 0 then return nil end + + local wearingEquipmentList = {} + for _, equipment in equipmentList do + local equipmentWearing = equipment:GetAttribute("wearing") + local maxAbilityNumber = equipment:GetAttribute("maxAbilityNumber") + if equipmentWearing > 0 and maxAbilityNumber > 0 then + table.insert(wearingEquipmentList, { + id = equipment.Name, + maxAbilityNumber = maxAbilityNumber, + abilityNumber = 0, + }) + end + end + + for _, ability in abilityList do + local wearingEquipment = ability:GetAttribute("wearing") + local orgId = ability:GetAttribute("orgId") + for _, equipmentData in wearingEquipmentList do + if equipmentData.id == wearingEquipment then + local abilityData = Utils:GetIdDataFromJson(JsonAbility, orgId) + if abilityData.castType then + if abilityData.castType == 1 then + equipmentData.abilityNumber = equipmentData.abilityNumber + 1 + end + end + end + end + end + + self.Data = 0 + for _, equipmentData in wearingEquipmentList do + if equipmentData.abilityNumber >= equipmentData.maxAbilityNumber then + self.Data = self.Data + 1 + end + end + + return true +end + +function RuneAllActiveAbility:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) + local attackRate = math.floor((AttributesData.attackRate or 100) * self.Data * 150 / 100) + Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate) + + return nil +end + + +return RuneAllActiveAbility \ No newline at end of file diff --git a/src/ServerStorage/Modules/Runes/RuneAtkSpeedToAtkRate.luau b/src/ServerStorage/Modules/Runes/RuneAtkSpeedToAtkRate.luau new file mode 100644 index 0000000..da34a7d --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RuneAtkSpeedToAtkRate.luau @@ -0,0 +1,40 @@ +--> 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 RuneAtkSpeedToAtkRate = {} +RuneAtkSpeedToAtkRate.__index = RuneAtkSpeedToAtkRate +setmetatable(RuneAtkSpeedToAtkRate, {__index = Rune}) + + +function RuneAtkSpeedToAtkRate:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RuneAtkSpeedToAtkRate) + + return self +end + +function RuneAtkSpeedToAtkRate:Check(index: number, AttributesData: table, BehaviorNameList: table) + return true +end + +function RuneAtkSpeedToAtkRate:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) + local baseAttribute = AttributesData.atkSpeed or 100 + local atkRate = AttributesData.atkRate or 100 + + local addAttribute = math.floor(atkRate * (25 / 100 + math.max(0, (100 - baseAttribute) * 5))) + Utils:TableSafeAddValue(AttributesData, "atkRate", addAttribute) + + return nil +end + + +return RuneAtkSpeedToAtkRate \ No newline at end of file diff --git a/src/ServerStorage/Modules/Runes/RuneAttack.luau b/src/ServerStorage/Modules/Runes/RuneAttack.luau new file mode 100644 index 0000000..91c1fd8 --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RuneAttack.luau @@ -0,0 +1,33 @@ +--> 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 RuneAttack = {} +RuneAttack.__index = RuneAttack +setmetatable(RuneAttack, {__index = Rune}) + +function RuneAttack:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RuneAttack) + + return self +end + +function RuneAttack:Check(index: number, AttributesData: table, BehaviorNameList: table) + return true +end + +function RuneAttack: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 RuneAttack \ No newline at end of file diff --git a/src/ServerStorage/Modules/Runes/RuneAttackRecoverHp.luau b/src/ServerStorage/Modules/Runes/RuneAttackRecoverHp.luau new file mode 100644 index 0000000..a93406b --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RuneAttackRecoverHp.luau @@ -0,0 +1,49 @@ +--> 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 DamageProxy = require(ServerStorage.Proxy.DamageProxy) + +--> EventFilter +local EventFilter = require(ReplicatedStorage.Modules.EventFilter) +local EventFilterEnum = require(ReplicatedStorage.Data.EventFilterEnum) + +local RuneAttackRecoverHp = {} +RuneAttackRecoverHp.__index = RuneAttackRecoverHp +setmetatable(RuneAttackRecoverHp, {__index = Rune}) + + +function RuneAttackRecoverHp:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RuneAttackRecoverHp) + + return self +end + +function RuneAttackRecoverHp:OnInitFinish() + EventFilter.SubscribeGlobalFilter(EventFilterEnum.AFTER_ATTACK, function(eventData) + local recoverHp = 0 + for _, damageData in eventData.damageData do + recoverHp = recoverHp + damageData.Damage * 0.2 + end + + recoverHp = math.floor(recoverHp) + DamageProxy:Heal(eventData.attacker, eventData.attacker, recoverHp) + return eventData + end, self.TriggerSlot, self) +end + +function RuneAttackRecoverHp:Check(index: number, AttributesData: table, BehaviorNameList: table) + return true +end + +function RuneAttackRecoverHp:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) + return nil +end + + +return RuneAttackRecoverHp \ No newline at end of file diff --git a/src/ServerStorage/Modules/Runes/RuneBanActiveAbility.luau b/src/ServerStorage/Modules/Runes/RuneBanActiveAbility.luau new file mode 100644 index 0000000..66d19ff --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RuneBanActiveAbility.luau @@ -0,0 +1,84 @@ +--> 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 Rng = require(ReplicatedStorage.Tools.Rng) + +--> Json +local JsonAbility = require(ReplicatedStorage.Json.Ability) + +local RuneBanActiveAbility = {} +RuneBanActiveAbility.__index = RuneBanActiveAbility +setmetatable(RuneBanActiveAbility, {__index = Rune}) + + +function RuneBanActiveAbility:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RuneBanActiveAbility) + + return self +end + +function RuneBanActiveAbility:Check(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 abilityFolder = pData:FindFirstChild("Ability") + if not abilityFolder then return nil end + local abilityList = abilityFolder:GetChildren() + if #abilityList == 0 then return nil end + + local wearingEquipmentList = {} + for _, equipment in equipmentList do + local equipmentWearing = equipment:GetAttribute("wearing") + if equipmentWearing > 0 then + table.insert(wearingEquipmentList, equipment.Name) + end + end + + self.Data = nil + self.Data = {} + for _, ability in abilityList do + local wearingEquipment = ability:GetAttribute("wearing") + if wearingEquipment > 0 then + if table.find(wearingEquipmentList, wearingEquipment) then + table.insert(self.Data, ability) + end + end + end + + return true +end + +function RuneBanActiveAbility:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) + local banAbilityNumber = 0 + for _, ability in self.Data do + local abilityId = ability:GetAttribute("orgId") + local abilityData = Utils:GetIdDataFromJson(JsonAbility, abilityId) + if abilityData.castType then + if abilityData.castType == 1 then + banAbilityNumber = banAbilityNumber + 1 + end + end + end + + self.PlayerAI:SetSharedData("BanAbility", 1) + local attackRate = math.floor((AttributesData.attackRate or 100) * banAbilityNumber * 150 / 100) + Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate) + + return nil +end + + +return RuneBanActiveAbility \ No newline at end of file diff --git a/src/ServerStorage/Modules/Runes/RuneCritRateDouble.luau b/src/ServerStorage/Modules/Runes/RuneCritRateDouble.luau new file mode 100644 index 0000000..3b88992 --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RuneCritRateDouble.luau @@ -0,0 +1,38 @@ +--> 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 DamageProxy = require(ServerStorage.Proxy.DamageProxy) +local Rng = require(ServerStorage.Base.Rng) + +--> EventFilter +local EventFilter = require(ReplicatedStorage.Modules.EventFilter) +local EventFilterEnum = require(ReplicatedStorage.Data.EventFilterEnum) + +local RuneCritRateDouble = {} +RuneCritRateDouble.__index = RuneCritRateDouble +setmetatable(RuneCritRateDouble, {__index = Rune}) + + +function RuneCritRateDouble:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RuneCritRateDouble) + + return self +end + +function RuneCritRateDouble:Check(index: number, AttributesData: table, BehaviorNameList: table) + return true +end + +function RuneCritRateDouble:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) + local critRate = AttributesData.critRate or 0 + Utils:TableSafeAddValue(AttributesData, "critRate", critRate) + return nil +end + +return RuneCritRateDouble \ No newline at end of file diff --git a/src/ServerStorage/Modules/Runes/RuneFireDamage.luau b/src/ServerStorage/Modules/Runes/RuneFireDamage.luau index 31aadaa..8ca0567 100644 --- a/src/ServerStorage/Modules/Runes/RuneFireDamage.luau +++ b/src/ServerStorage/Modules/Runes/RuneFireDamage.luau @@ -11,7 +11,6 @@ local RuneFireDamage = {} RuneFireDamage.__index = RuneFireDamage setmetatable(RuneFireDamage, {__index = Rune}) - function RuneFireDamage:Init(PlayerAI, Character: TypeList.Character) local self = Rune:Init(PlayerAI, Character, script.Name) setmetatable(self, RuneFireDamage) diff --git a/src/ServerStorage/Modules/Runes/RuneFirstElementCopy.luau b/src/ServerStorage/Modules/Runes/RuneFirstElementCopy.luau new file mode 100644 index 0000000..eae7f8f --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RuneFirstElementCopy.luau @@ -0,0 +1,48 @@ +--> 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 DamageProxy = require(ServerStorage.Proxy.DamageProxy) + +--> EventFilter +local EventFilter = require(ReplicatedStorage.Modules.EventFilter) +local EventFilterEnum = require(ReplicatedStorage.Data.EventFilterEnum) + +local RuneFirstElementCopy = {} +RuneFirstElementCopy.__index = RuneFirstElementCopy +setmetatable(RuneFirstElementCopy, {__index = Rune}) + + +function RuneFirstElementCopy:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RuneFirstElementCopy) + + return self +end + +function RuneFirstElementCopy:OnInitFinish() + EventFilter.SubscribeGlobalFilter(EventFilterEnum.BEFORE_ATTACK, function(eventData) + for _, damageData in eventData.damageData do + if damageData.ElementType ~= DamageProxy.ElementType.NONE then + local newDamageData = Utils:DeepCopyTable(damageData) + table.insert(eventData.damageData, newDamageData) + break + end + end + return eventData + end, self.TriggerSlot, self) +end + +function RuneFirstElementCopy:Check(index: number, AttributesData: table, BehaviorNameList: table) + return true +end + +function RuneFirstElementCopy:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) + return nil +end + +return RuneFirstElementCopy \ No newline at end of file diff --git a/src/ServerStorage/Modules/Runes/RuneFirstHpDamage.luau b/src/ServerStorage/Modules/Runes/RuneFirstHpDamage.luau new file mode 100644 index 0000000..53e0ead --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RuneFirstHpDamage.luau @@ -0,0 +1,50 @@ +--> 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 RuneFirstHpDamage = {} +RuneFirstHpDamage.__index = RuneFirstHpDamage +setmetatable(RuneFirstHpDamage, {__index = Rune}) + + +function RuneFirstHpDamage:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RuneFirstHpDamage) + self.FirstAttack = true + + return self +end + +function RuneFirstHpDamage:OnInitFinish() + EventFilter.SubscribeGlobalFilter(EventFilterEnum.BEFORE_ATTACK, function(eventData) + if self.FirstAttack then + self.FirstAttack = false + for _, damageData in eventData.damageData do + damageData.Damage = damageData.Damage + math.floor(self.PlayerAI.Config.maxhp * 40 / 100) + break + end + end + return eventData + end, self.TriggerSlot, self) + +end + +function RuneFirstHpDamage:Check(index: number, AttributesData: table, BehaviorNameList: table) + return true +end + +function RuneFirstHpDamage:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) + return nil +end + + +return RuneFirstHpDamage \ No newline at end of file diff --git a/src/ServerStorage/Modules/Runes/RuneHealCrit.luau b/src/ServerStorage/Modules/Runes/RuneHealCrit.luau new file mode 100644 index 0000000..8d9f22c --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RuneHealCrit.luau @@ -0,0 +1,48 @@ +--> 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 DamageProxy = require(ServerStorage.Proxy.DamageProxy) +local Rng = require(ServerStorage.Base.Rng) + +--> EventFilter +local EventFilter = require(ReplicatedStorage.Modules.EventFilter) +local EventFilterEnum = require(ReplicatedStorage.Data.EventFilterEnum) + +local RuneHealCrit = {} +RuneHealCrit.__index = RuneHealCrit +setmetatable(RuneHealCrit, {__index = Rune}) + + +function RuneHealCrit:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RuneHealCrit) + + return self +end + +function RuneHealCrit:OnInitFinish() + EventFilter.SubscribeGlobalFilter(EventFilterEnum.BEFORE_HEAL, function(eventData) + eventData.amount = math.floor(eventData.amount * 40 / 100) + local critRate = self.PlayerAI.Config.critRate or 0 + if Rng:RandomPercent(critRate) then + eventData.amount = math.floor(eventData.amount * 2) + end + + return eventData + end, self.TriggerSlot, self) +end + +function RuneHealCrit:Check(index: number, AttributesData: table, BehaviorNameList: table) + return true +end + +function RuneHealCrit:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) + return nil +end + +return RuneHealCrit \ No newline at end of file diff --git a/src/ServerStorage/Modules/Runes/RuneHp.luau b/src/ServerStorage/Modules/Runes/RuneHp.luau new file mode 100644 index 0000000..a418e9e --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RuneHp.luau @@ -0,0 +1,33 @@ +--> 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 RuneHp = {} +RuneHp.__index = RuneHp +setmetatable(RuneHp, {__index = Rune}) + +function RuneHp:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RuneHp) + + return self +end + +function RuneHp:Check(index: number, AttributesData: table, BehaviorNameList: table) + return true +end + +function RuneHp: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 RuneHp \ No newline at end of file diff --git a/src/ServerStorage/Modules/Runes/RuneIronBonus.luau b/src/ServerStorage/Modules/Runes/RuneIronBonus.luau new file mode 100644 index 0000000..a884509 --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RuneIronBonus.luau @@ -0,0 +1,33 @@ +--> 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 RuneIronBonus = {} +RuneIronBonus.__index = RuneIronBonus +setmetatable(RuneIronBonus, {__index = Rune}) + + +function RuneIronBonus:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RuneIronBonus) + + return self +end + +function RuneIronBonus:Check(index: number, AttributesData: table, BehaviorNameList: table) + return true +end + +function RuneIronBonus:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) + local baseAttribute = AttributesData.iron or 100 + local addAttribute = math.floor(baseAttribute * 20 / 100) + Utils:TableSafeAddValue(AttributesData, "ironBonus", addAttribute) + return nil +end + +return RuneIronBonus \ No newline at end of file diff --git a/src/ServerStorage/Modules/Runes/RuneLastElementCopy.luau b/src/ServerStorage/Modules/Runes/RuneLastElementCopy.luau new file mode 100644 index 0000000..43ac365 --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RuneLastElementCopy.luau @@ -0,0 +1,49 @@ +--> 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 DamageProxy = require(ServerStorage.Proxy.DamageProxy) + +--> EventFilter +local EventFilter = require(ReplicatedStorage.Modules.EventFilter) +local EventFilterEnum = require(ReplicatedStorage.Data.EventFilterEnum) + +local RuneLastElementCopy = {} +RuneLastElementCopy.__index = RuneLastElementCopy +setmetatable(RuneLastElementCopy, {__index = Rune}) + + +function RuneLastElementCopy:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RuneLastElementCopy) + + return self +end + +function RuneLastElementCopy:OnInitFinish() + EventFilter.SubscribeGlobalFilter(EventFilterEnum.BEFORE_ATTACK, function(eventData) + for i = #eventData.damageData, 1, -1 do + local damageData = eventData.damageData[i] + if damageData.ElementType ~= DamageProxy.ElementType.NONE then + local newDamageData = Utils:DeepCopyTable(damageData) + table.insert(eventData.damageData, newDamageData) + break + end + end + return eventData + end, self.TriggerSlot, self) +end + +function RuneLastElementCopy:Check(index: number, AttributesData: table, BehaviorNameList: table) + return true +end + +function RuneLastElementCopy:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) + return nil +end + +return RuneLastElementCopy \ No newline at end of file diff --git a/src/ServerStorage/Modules/Runes/RuneLeftTrigger.luau b/src/ServerStorage/Modules/Runes/RuneLeftTrigger.luau new file mode 100644 index 0000000..3f2dc3a --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RuneLeftTrigger.luau @@ -0,0 +1,33 @@ +--> 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 RuneLeftTrigger = {} +RuneLeftTrigger.__index = RuneLeftTrigger +setmetatable(RuneLeftTrigger, {__index = Rune}) + +function RuneLeftTrigger:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RuneLeftTrigger) + self.TriggerTime = 0 + + return self +end + +function RuneLeftTrigger:Check(index: number, AttributesData: table, BehaviorNameList: table) + if self.TriggerSlot == 1 then return false end + if self.TriggerTime ~= 0 then return false end + return true +end + +function RuneLeftTrigger:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) + self.TriggerTime = self.TriggerTime + 1 + return self.TriggerSlot - 1 +end + +return RuneLeftTrigger \ No newline at end of file diff --git a/src/ServerStorage/Modules/Runes/RuneNormalDamageToIce.luau b/src/ServerStorage/Modules/Runes/RuneNormalDamageToIce.luau new file mode 100644 index 0000000..6ea79cb --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RuneNormalDamageToIce.luau @@ -0,0 +1,74 @@ +--> 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 DamageProxy = require(ServerStorage.Proxy.DamageProxy) + +--> EventFilter +local EventFilter = require(ReplicatedStorage.Modules.EventFilter) +local EventFilterEnum = require(ReplicatedStorage.Data.EventFilterEnum) + +local RuneNormalDamageToIce = {} +RuneNormalDamageToIce.__index = RuneNormalDamageToIce +setmetatable(RuneNormalDamageToIce, {__index = Rune}) + + +function RuneNormalDamageToIce:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RuneNormalDamageToIce) + + return self +end + +function RuneNormalDamageToIce:OnInitFinish() + EventFilter.SubscribeGlobalFilter(EventFilterEnum.BEFORE_ATTACK, function(eventData) + local noneDamageValue = 0 + local hasIceDamage = false + local iceDamageIndex = nil + local lastNoneDamageData = nil + + -- 第一步:找到NONE类型的伤害并计算总值,同时检查是否有ICE伤害 + for i = #eventData.damageData, 1, -1 do + local damageData = eventData.damageData[i] + if damageData.ElementType == DamageProxy.ElementType.NONE then + noneDamageValue = noneDamageValue + damageData.Damage + if not lastNoneDamageData then + lastNoneDamageData = Utils:DeepCopyTable(damageData) + end + table.remove(eventData.damageData, i) + elseif damageData.ElementType == DamageProxy.ElementType.ICE then + hasIceDamage = true + iceDamageIndex = i + end + end + + -- 第二步:处理NONE伤害值 + if noneDamageValue > 0 then + if hasIceDamage then + -- 如果存在ICE伤害,将NONE伤害值加到ICE伤害中 + eventData.damageData[iceDamageIndex].Damage = eventData.damageData[iceDamageIndex].Damage + noneDamageValue + else + -- 如果不存在ICE伤害,复制之前的伤害记录并修改为ICE类型 + if lastNoneDamageData then + lastNoneDamageData.ElementType = DamageProxy.ElementType.ICE + table.insert(eventData.damageData, lastNoneDamageData) + end + end + end + return eventData + end, self.TriggerSlot, self) +end + +function RuneNormalDamageToIce:Check(index: number, AttributesData: table, BehaviorNameList: table) + return true +end + +function RuneNormalDamageToIce:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) + return nil +end + +return RuneNormalDamageToIce \ No newline at end of file diff --git a/src/ServerStorage/Modules/Runes/RunePassiveAbilityAttackRate.luau b/src/ServerStorage/Modules/Runes/RunePassiveAbilityAttackRate.luau new file mode 100644 index 0000000..af58026 --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RunePassiveAbilityAttackRate.luau @@ -0,0 +1,81 @@ +--> 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 Rng = require(ReplicatedStorage.Tools.Rng) + +--> Json +local JsonAbility = require(ReplicatedStorage.Json.Ability) + +local RunePassiveAbilityAttackRate = {} +RunePassiveAbilityAttackRate.__index = RunePassiveAbilityAttackRate +setmetatable(RunePassiveAbilityAttackRate, {__index = Rune}) + + +function RunePassiveAbilityAttackRate:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RunePassiveAbilityAttackRate) + + return self +end + +function RunePassiveAbilityAttackRate:Check(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 abilityFolder = pData:FindFirstChild("Ability") + if not abilityFolder then return nil end + local abilityList = abilityFolder:GetChildren() + if #abilityList == 0 then return nil end + + local wearingEquipmentList = {} + for _, equipment in equipmentList do + local equipmentWearing = equipment:GetAttribute("wearing") + if equipmentWearing > 0 then + table.insert(wearingEquipmentList, equipment.Name) + end + end + + self.Data = nil + self.Data = {} + for _, ability in abilityList do + local wearingEquipment = ability:GetAttribute("wearing") + if wearingEquipment > 0 then + if table.find(wearingEquipmentList, wearingEquipment) then + table.insert(self.Data, ability) + end + end + end + + return true +end + +function RunePassiveAbilityAttackRate:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) + local banAbilityNumber = 0 + for _, ability in self.Data do + local abilityId = ability:GetAttribute("orgId") + local abilityData = Utils:GetIdDataFromJson(JsonAbility, abilityId) + if not abilityData.castType then + banAbilityNumber = banAbilityNumber + 1 + end + end + + local attackRate = math.floor((AttributesData.attackRate or 100) * banAbilityNumber * 50 / 100) + Utils:TableSafeAddValue(AttributesData, "attackRate", attackRate) + + return nil +end + + +return RunePassiveAbilityAttackRate \ No newline at end of file diff --git a/src/ServerStorage/Modules/Runes/RuneRightTrigger.luau b/src/ServerStorage/Modules/Runes/RuneRightTrigger.luau new file mode 100644 index 0000000..3742825 --- /dev/null +++ b/src/ServerStorage/Modules/Runes/RuneRightTrigger.luau @@ -0,0 +1,33 @@ +--> 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 RuneRightTrigger = {} +RuneRightTrigger.__index = RuneRightTrigger +setmetatable(RuneRightTrigger, {__index = Rune}) + +function RuneRightTrigger:Init(PlayerAI, Character: TypeList.Character) + local self = Rune:Init(PlayerAI, Character, script.Name) + setmetatable(self, RuneRightTrigger) + self.TriggerTime = 0 + + return self +end + +function RuneRightTrigger:Check(index: number, AttributesData: table, BehaviorNameList: table) + if self.TriggerSlot == #self.PlayerAI:GetRuneList() then return false end + if self.TriggerTime ~= 0 then return false end + return true +end + +function RuneRightTrigger:OnExecute(index: number, AttributesData: table, BehaviorNameList: table) + self.TriggerTime = self.TriggerTime + 1 + return self.TriggerSlot + 1 +end + +return RuneRightTrigger \ No newline at end of file diff --git a/src/ServerStorage/Proxy/DamageProxy.luau b/src/ServerStorage/Proxy/DamageProxy.luau index 318ad07..e286e3c 100644 --- a/src/ServerStorage/Proxy/DamageProxy.luau +++ b/src/ServerStorage/Proxy/DamageProxy.luau @@ -15,6 +15,11 @@ local Utils = require(ReplicatedStorage.Tools.Utils) --> Variables local TypeList = require(ServerStorage.Base.TypeList) +--> EventFilter +local EventFilter = require(ReplicatedStorage.Modules.EventFilter) +local EventFilterEnum = require(ReplicatedStorage.Data.EventFilterEnum) + + -- 伤害类型枚举 local DamageType = { NORMAL = "Normal", -- 普攻 @@ -307,6 +312,16 @@ function DamageProxy:Heal(Caster: TypeList.Character, Victim: TypeList.Character local actualHeal = math.min(Amount, MaxHealth - VictimHealth) local overheal = math.max(0, Amount - actualHeal) + + -- 发送攻击前事件 + EventFilter.FireGlobalWithFilter(EventFilterEnum.BEFORE_HEAL, { + caster = Caster, + victim = Victim, + amount = actualHeal, + }, function(processedData) + actualHeal = processedData.amount + end) + if actualHeal > 0 then Victim:ChangeAttributeValue("hp", VictimHealth + actualHeal) end diff --git a/src/ServerStorage/Proxy/EquipmentProxy.luau b/src/ServerStorage/Proxy/EquipmentProxy.luau index f60c482..c9656f7 100644 --- a/src/ServerStorage/Proxy/EquipmentProxy.luau +++ b/src/ServerStorage/Proxy/EquipmentProxy.luau @@ -341,9 +341,17 @@ function EquipmentProxy:RecycleEquipment(Player: Player, EquipmentId: number) -- GemProxy:RecycleGem(Player, EquipmentData.id) -- 回收装备返回金币 - -- TODO:处理关卡金币产出加成和词条加成 - local rewardData = {["1"] = EquipmentData.recycle} - PlayerInfoProxy:ChangeItemCount(Player, 1, EquipmentData.recycle) + + -- 处理关卡金币产出加成和词条加成 + local getNumber = EquipmentData.recycle + local coinBonus = Player.Character:FindFirstChild("Attributes"):GetAttribute("coinBonus") + if coinBonus then + getNumber = math.floor(getNumber * (1 + coinBonus / 100)) + end + + -- 返回金币 + local rewardData = {["1"] = getNumber} + PlayerInfoProxy:ChangeItemCount(Player, 1, getNumber) ArchiveProxy.pData[Player.UserId][STORE_NAME][EquipmentId] = nil diff --git a/src/ServerStorage/Proxy/LevelProxy.luau b/src/ServerStorage/Proxy/LevelProxy.luau index 9fa1d18..7f5d77a 100644 --- a/src/ServerStorage/Proxy/LevelProxy.luau +++ b/src/ServerStorage/Proxy/LevelProxy.luau @@ -117,6 +117,14 @@ local function OnMobDied(Player: Player, Mob: TypeList.Character) local mob_died_get = Utils:GetIdDataFromJson(JsonParam, 3) local PlayerInfoProxy = require(ServerStorage.Proxy.PlayerInfoProxy) local getNumber = math.floor(mob_died_get["intArray"][2] + LevelProxy:GetLevelGetBonus(Player) / 100) + + -- 铁矿加成,读取属性加成 + local ironBonus = Player.Character:FindFirstChild("Attributes"):GetAttribute("ironBonus") + if ironBonus then + if mob_died_get["intArray"][1] == 2 then + getNumber = math.floor(getNumber * (1 + ironBonus / 100)) + end + end PlayerInfoProxy:ChangeItemCount(Player, mob_died_get["intArray"][1], getNumber) for _, mob in LevelProxy.pData[Player.UserId].Mobs do