diff --git a/.luacheckrc b/.luacheckrc index 2e903fee..c19a0547 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -17,6 +17,7 @@ stds.ecs = { read_globals = {}, -- these globals can only be accessed. globals = { "----> GlobalAPI", + -- keep-sorted start case=no "AbandonQuest", "AbandonSkill", "AcceptAreaSpiritHeal", @@ -117,8 +118,8 @@ stds.ecs = { "C_ActionBar.IsEnabledAutoCastPetAction", "C_ActionBar.IsOnBarOrSpecialBar", "C_ActionBar.ToggleAutoCastPetAction", - "C_AddOns.GetAddOnInfo", "C_AddOns", + "C_AddOns.GetAddOnInfo", "C_AreaPoiInfo.GetAreaPOIForMap", "C_AreaPoiInfo.GetAreaPOIInfo", "C_AreaPoiInfo.IsAreaPOITimed", @@ -135,6 +136,7 @@ stds.ecs = { "C_CharacterServices.SetAutomaticBoostCharacter", "C_CharacterServicesPublic.ShouldSeeControlPopup", "C_ChatBubbles.GetAllChatBubbles", + "C_ChatInfo", "C_ChatInfo.GetChannelRosterInfo", "C_ChatInfo.GetNumActiveChannels", "C_ChatInfo.GetRegisteredAddonMessagePrefixes", @@ -145,7 +147,6 @@ stds.ecs = { "C_ChatInfo.ReportServerLag", "C_ChatInfo.SendAddonMessage", "C_ChatInfo.SendAddonMessageLogged", - "C_ChatInfo", "C_Club.AcceptInvitation", "C_Club.AddClubStreamChatChannel", "C_Club.AdvanceStreamViewMarker", @@ -389,6 +390,7 @@ stds.ecs = { "C_GuildInfo.RemoveFromGuild", "C_GuildInfo.SetGuildRankOrder", "C_GuildInfo.SetNote", + "C_Item", "C_Item.DoesItemExist", "C_Item.DoesItemExistByID", "C_Item.GetCurrentItemLevel", @@ -411,7 +413,6 @@ stds.ecs = { "C_Item.RequestLoadItemData", "C_Item.RequestLoadItemDataByID", "C_Item.UnlockItem", - "C_Item", "C_KeyBindings.GetCustomBindingType", "C_LootHistory.CanMasterLoot", "C_LootHistory.GetExpiration", @@ -424,6 +425,7 @@ stds.ecs = { "C_LossOfControl.GetNumEvents", "C_Mail.HasInboxMoney", "C_Mail.IsCommandPending", + "C_Map", "C_Map.GetAreaInfo", "C_Map.GetBestMapForUnit", "C_Map.GetBountySetIDForMap", @@ -449,10 +451,9 @@ stds.ecs = { "C_Map.GetWorldPosFromMapPos", "C_Map.MapHasArt", "C_Map.RequestPreloadMap", - "C_Map", + "C_MapExplorationInfo", "C_MapExplorationInfo.GetExploredAreaIDsAtPosition", "C_MapExplorationInfo.GetExploredMapTextures", - "C_MapExplorationInfo", "C_MerchantFrame.GetBuybackItemID", "C_ModelInfo.AddActiveModelScene", "C_ModelInfo.AddActiveModelSceneActor", @@ -462,6 +463,7 @@ stds.ecs = { "C_ModelInfo.GetModelSceneActorInfoByID", "C_ModelInfo.GetModelSceneCameraInfoByID", "C_ModelInfo.GetModelSceneInfoByID", + "C_NamePlate", "C_NamePlate.GetNamePlateEnemyClickThrough", "C_NamePlate.GetNamePlateEnemyPreferredClickInsets", "C_NamePlate.GetNamePlateEnemySize", @@ -485,16 +487,15 @@ stds.ecs = { "C_NamePlate.SetNamePlateSelfPreferredClickInsets", "C_NamePlate.SetNamePlateSelfSize", "C_NamePlate.SetTargetClampingInsets", - "C_NamePlate", "C_NewItems.ClearAll", "C_NewItems.IsNewItem", "C_NewItems.RemoveNewItem", + "C_PaperDollInfo", "C_PaperDollInfo.GetArmorEffectiveness", "C_PaperDollInfo.GetArmorEffectivenessAgainstTarget", "C_PaperDollInfo.GetMinItemLevel", "C_PaperDollInfo.OffhandHasShield", "C_PaperDollInfo.OffhandHasWeapon", - "C_PaperDollInfo", "C_PartyInfo.GetActiveCategories", "C_PartyInfo.GetInviteConfirmationInvalidQueues", "C_PlayerInfo.GetClass", @@ -507,13 +508,13 @@ stds.ecs = { "C_ProductChoice.GetProducts", "C_ProductChoice.MakeSelection", "C_PvP.IsPVPMap", + "C_QuestLog", "C_QuestLog.GetMaxNumQuests", "C_QuestLog.GetMaxNumQuestsCanAccept", "C_QuestLog.GetQuestInfo", "C_QuestLog.GetQuestObjectives", "C_QuestLog.IsOnQuest", "C_QuestLog.ShouldShowQuestRewards", - "C_QuestLog", "C_RecruitAFriend.CheckEmailEnabled", "C_RecruitAFriend.GetRecruitInfo", "C_RecruitAFriend.IsSendingEnabled", @@ -544,15 +545,15 @@ stds.ecs = { "C_Spell.DoesSpellExist", "C_Spell.IsSpellDataCached", "C_Spell.RequestLoadSpellData", - "C_SpellBook.IsSpellKnown", "C_SpellBook", + "C_SpellBook.IsSpellKnown", "C_StorePublic.DoesGroupHavePurchaseableProducts", "C_StorePublic.IsDisabledByParentalControls", "C_StorePublic.IsEnabled", "C_TaxiMap.GetAllTaxiNodes", "C_TaxiMap.GetTaxiNodesForMap", - "C_Timer.After", "C_Timer", + "C_Timer.After", "C_UI.Reload", "C_UIWidgetManager.GetAllWidgetsBySetID", "C_UIWidgetManager.GetBelowMinimapWidgetSetID", @@ -804,22 +805,6 @@ stds.ecs = { "ConvertToParty", "ConvertToRaid", "CopyToClipboard", - "CR_ARMOR_PENETRATION", - "CR_BLOCK", - "CR_CRIT_MELEE", - "CR_CRIT_RANGED", - "CR_CRIT_SPELL", - "CR_DEFENSE_SKILL", - "CR_DODGE", - "CR_EXPERTISE", - "CR_HASTE_MELEE", - "CR_HASTE_RANGED", - "CR_HASTE_SPELL", - "CR_HIT_MELEE", - "CR_HIT_RANGED", - "CR_HIT_SPELL", - "CR_PARRY", - "CR_WEAPON_SKILL", "CreateFont", "CreateFrame", "CreateMacro", @@ -2268,14 +2253,16 @@ stds.ecs = { "UseHearthstone", "UseInventoryItem", "UseItemByName", + -- keep-sorted end "----------------------------------------------------->LUA API", - "bit", + -- keep-sorted start case=no "abs", "acos", "asin", "assert", "atan", "atan2", + "bit", "bit.arshift", "bit.band", "bit.bnot", @@ -2415,7 +2402,9 @@ stds.ecs = { "unpack", "wipe", "xpcall", + -- keep-sorted end "------------------------------------------------------> FRAMES", + -- keep-sorted start case=no "ActionBarActionEventsFrame", "ActionBarButtonEventsFrame", "ActionBarController", @@ -2474,7 +2463,6 @@ stds.ecs = { "ChatConfigFrame", "ChatEdit_GetActiveWindow", "ChatEdit_InsertLink", - "ChatFrame_AddMessageEventFilter", "ChatFrame1", "ChatFrame10", "ChatFrame10EditBox", @@ -2503,6 +2491,7 @@ stds.ecs = { "ChatFrame9", "ChatFrame9EditBox", "ChatFrame9Tab", + "ChatFrame_AddMessageEventFilter", "ChatFrameChannelButton", "ChatFrameMenuButton", "ChatMenu", @@ -2537,6 +2526,22 @@ stds.ecs = { "ContainerFrame7", "ContainerFrame8", "ContainerFrame9", + "CR_ARMOR_PENETRATION", + "CR_BLOCK", + "CR_CRIT_MELEE", + "CR_CRIT_RANGED", + "CR_CRIT_SPELL", + "CR_DEFENSE_SKILL", + "CR_DODGE", + "CR_EXPERTISE", + "CR_HASTE_MELEE", + "CR_HASTE_RANGED", + "CR_HASTE_SPELL", + "CR_HIT_MELEE", + "CR_HIT_RANGED", + "CR_HIT_SPELL", + "CR_PARRY", + "CR_WEAPON_SKILL", "CraftFrame", "CreateChannelPopup", "DEFAULT_CHAT_FRAME", @@ -2620,6 +2625,7 @@ stds.ecs = { "MainMenuBar", "MapQuestInfoRewardsFrame", "MasterLooterFrame", + "MAX_SPELL_SCHOOLS", "MerchantFrame", "Minimap", "MinimapCluster", @@ -2696,11 +2702,11 @@ stds.ecs = { "SpellBookFrame", "StackSplitFrame", "STANDARD_TEXT_FONT", - "StaticPopup_Show", "StaticPopup1", "StaticPopup2", "StaticPopup3", "StaticPopup4", + "StaticPopup_Show", "StaticPopupDialogs", "StatsFrame", "StopwatchFrame", @@ -2752,7 +2758,9 @@ stds.ecs = { "WorldMapTooltip", "WorldStateScoreFrame", "ZoneTextFrame", + -- keep-sorted end "-----------------------------------------------------> Blizzard Data", + -- keep-sorted start case=no "CALENDAR_FULLDATE_MONTH_NAMES", "CALENDAR_WEEKDAY_NAMES", "QUEST_ITEMS_NEEDED", @@ -2765,19 +2773,27 @@ stds.ecs = { "WOW_PROJECT_ID", "WOW_PROJECT_MAINLINE", "WOW_PROJECT_WRATH_CLASSIC", + -- keep-sorted end "-----------------------------------------------------> Enums", + -- keep-sorted start case=no "LE_EXPANSION_BURNING_CRUSADE", + -- keep-sorted end "-----------------------------------------------------> GlobalStrings", + -- keep-sorted start case=no "CLOSE", "DEFENSE", + -- keep-sorted end "-----------------------------------------------------> External Addons", + -- keep-sorted start case=no "LeaPlusDB", "LibStub", "OutfitterButton", "OutfitterButtonFrame", "OutfitterFrame", "PawnInitialize", + -- keep-sorted end "-----------------------------------------------------> Project Specific", + -- keep-sorted start case=no "assert.are_same", "assert.is_nil", "assert.spy", @@ -2791,6 +2807,7 @@ stds.ecs = { "SLASH_ECS1", "SlashCmdList", "spy", + -- keep-sorted end } } std = "max+ecs" diff --git a/Modules/Data/Constants.lua b/Modules/Data/Constants.lua index 7f424a18..9991797a 100755 --- a/Modules/Data/Constants.lua +++ b/Modules/Data/Constants.lua @@ -1,3 +1,8 @@ +-- keep-sorted start case=no +local IsTBC = ECS.IsTBC +local IsWotlk = ECS.IsWotlk +-- keep-started end + ---@class Data local Data = ECSLoader:ImportModule("Data") @@ -21,6 +26,7 @@ Data.WARLOCK = 9 Data.DRUID = 11 Data.Aura = { + -- keep-sorted start block=yes case=no AllowCastingManaRegeneration = { [6117] = (ECS.IsWotlk and 0.5 or 0.3), -- Mage Armor rank 1 [12051] = 1, -- Evocation @@ -79,6 +85,85 @@ Data.Aura = { [17800] = (ECS.IsWotlk and -5 or nil), -- Shadow Mastery 5/5 [22959] = (ECS.IsWotlk and -5 or nil), -- Improved Scorch }, + ---@type table + HitReductionMelee = { + -- keep-sorted start block=yes numeric=yes + [0] = { + -- keep-sorted start numeric=yes + [2651] = (IsTBC and 20 or nil), -- Elune's Grace + [35346] = 50, -- Warp + [50240] = 200, -- Evasive Maneuvers + [54956] = 100, -- Impaling Charge + [59827] = 100, -- Impaling Charge + [445875] = -100, -- Gloom + [455868] = -1, -- Revealed Weakness + [460725] = -100, -- Gloom + -- keep-sorted end + }, + [14] = { + -- keep-sorted start numeric=yes + [46989] = (IsWotlk and 30 or 25), -- Improved Blink + [47000] = (IsWotlk and 15 or 13), -- Improved Blink + -- keep-sorted end + }, + [95] = { + -- keep-sorted start numeric=yes + [50280] = 20, -- Oily Coat + -- keep-sorted end + }, + [127] = { + -- keep-sorted start numeric=yes + [54603] = 25, -- Serpent's Agility + -- keep-sorted end + }, + -- keep-sorted end + }, + HitReductionRanged = { + -- keep-sorted start numeric=yes + [2651] = (IsTBC and 20 or nil), -- Elune's Grace + [26669] = 25, -- Evasion + [46989] = (IsWotlk and 30 or 25), -- Improved Blink + [47000] = (IsWotlk and 15 or 13), -- Improved Blink + [50280] = 20, -- Oily Coat + [54603] = 25, -- Serpent's Agility + [67801] = 100, -- Deterrence + [455868] = -1, -- Revealed Weakness + -- keep-sorted end + }, + ---@type table + HitReductionSpell = { + -- keep-sorted start block=yes numeric=yes + [0] = { + -- keep-sorted start numeric=yes + [50280] = 20, -- Oily Coat + [54603] = 25, -- Serpent's Agility + [56673] = -100, -- Fight Wyrm + [445875] = -100, -- Gloom + [460725] = -100, -- Gloom + -- keep-sorted end + }, + [126] = { + -- keep-sorted start numeric=yes + [31224] = 90, -- Cloak of Shadows + [31965] = -3, -- Spell Debuffs 2 (80) + [39666] = 90, -- Cloak of Shadows + [46989] = (IsWotlk and 30 or 25), -- Improved Blink + [47000] = (IsWotlk and 15 or 13), -- Improved Blink + [50240] = 200, -- Evasive Maneuvers + [65961] = 90, -- Cloak of Shadows + [455868] = -1, -- Revealed Weakness + [462873] = 90, -- Cloak of Shadows + -- keep-sorted end + }, + [127] = { + -- keep-sorted start numeric=yes + [33196] = (IsWotlk and -1 or nil), -- Misery + [33197] = (IsWotlk and -2 or nil), -- Misery + [33198] = (IsWotlk and -1 or nil), -- Misery + -- keep-sorted end + }, + -- keep-sorted end + }, IsFeralForm = { [768] = true, -- Cat Form [5487] = true, -- Bear Form @@ -422,6 +507,7 @@ Data.Aura = { [1227200] = 20, -- Wickedness [1236220] = -50, -- Slow }, + -- keep-sorted end } Data.Enchant = { BlockValue = { @@ -786,6 +872,46 @@ Data.Item = { [234032] = 2, }, } +Data.Talent = { + -- keep-sorted start block=yes + [Data.DEATHKNIGHT] = { + -- keep-sorted start + FRIGID_DREADPLATE = {49186,51108,51109}, + -- keep-sorted end + }, + [Data.HUNTER] = { + -- keep-sorted start + DISPLACEMENT = {34478,34479,34481}, + -- keep-sorted end + }, + [Data.MAGE] = { + -- keep-sorted start + ARCTIC_WINDS = {31674,31675,31676,31677,31678} + -- keep-sorted end + }, + [Data.PALADIN] = { + -- keep-sorted start + BALANCE_OF_POWER = {33592,33596}, + -- keep-sorted end + }, + [Data.PALADIN] = { + -- keep-sorted start + DIVINE_PURPOSE = {31871,31872}, + PURSUIT_OF_JUSTICE = {26022,26023,44414}, + -- keep-sorted end + }, + [Data.ROGUE] = { + -- keep-sorted start + HEIGHTENED_SENSES = {30894,30895}, + -- keep-sorted end + }, + [Data.WARRIOR] = { + -- keep-sorted start + IMPROVED_SPELL_REFLECTION = {59088,59089}, + -- keep-sorted end + }, + -- keep-sorted end +} Data.setNames = { AUGURS_REGALIA = "Augur's Regalia", BLOODSOUL_EMBRACE = "Bloodsoul Embrace", diff --git a/Modules/Data/Defense.lua b/Modules/Data/Defense.lua index f9511d57..54144e66 100755 --- a/Modules/Data/Defense.lua +++ b/Modules/Data/Defense.lua @@ -1,3 +1,14 @@ +-- keep-sorted start case=no +local band = bit.band +local GetBuffDataByIndex = C_UnitAuras.GetBuffDataByIndex +local GetDebuffDataByIndex = C_UnitAuras.GetDebuffDataByIndex +local IsSpellKnown = C_SpellBook.IsSpellKnown +local IsTBC = ECS.IsTBC +local IsWotlk = ECS.IsWotlk +local MAX_SPELL_SCHOOLS = MAX_SPELL_SCHOOLS +local pairs = pairs +-- keep-sorted end + ---@class Data local Data = ECSLoader:ImportModule("Data") ---@type DataUtils @@ -5,13 +16,25 @@ local DataUtils = ECSLoader:ImportModule("DataUtils") ---@type Utils local Utils = ECSLoader:ImportModule("Utils") -local _Defense = {} - +-- keep-sorted start case=no local _, _, classId = UnitClass("player") - -local MAX_SKILL = (UnitLevel("player")) * 5 +local _Defense = {} +local ARCANE = Data.ARCANE_SCHOOL +local DEATHKNIGHT = Data.DEATHKNIGHT -- Every 25 defense reduce the chance to be critically hit by 1 % local DEFENSE_FOR_CRIT_REDUCTION = 25 +local DRUID = Data.DRUID +local FROST = Data.FROST_SCHOOL +local HUNTER = Data.HUNTER +local MAGE = Data.MAGE +local MAX_SKILL = (UnitLevel("player")) * 5 +local NATURE = Data.NATURE_SCHOOL +local PALADIN = Data.PALADIN +local ROGUE = Data.ROGUE +local SHADOW = Data.SHADOW_SCHOOL +local Talent = Data.Talent +local WARRIOR = Data.WARRIOR +-- keep-sorted end ---@return number function Data:GetArmorValue() @@ -236,3 +259,120 @@ function _Defense:GetEnchantsBlockValue() end return mod end + +---@return table +function _Defense:GetHitReduction() + local hitReduction = { + spell = {0,0,0,0,0,0,0}, + melee= 0, + ranged = 0 + } + + local i = 1 + repeat + local aura = GetBuffDataByIndex("player", i) + i = i + 1 + if aura and aura.spellId then + hitReduction.melee = hitReduction.melee + (Data.Aura.HitReductionMelee[aura.spellId] or 0) + hitReduction.ranged = hitReduction.ranged + (Data.Aura.HitReductionRanged[aura.spellId] or 0) + + for k,v in pairs(Data.Aura.HitReductionSpell) do + for s=1,MAX_SPELL_SCHOOLS do + if ((k == 0) or band(k,s-1) ~= 0x0) then + hitReduction.spell[s] = hitReduction.spell[s] + (v[aura.spellId] or 0) + end + end + end + end + until (not aura) + i = 1 + repeat + local aura = GetDebuffDataByIndex("player", i) + i = i + 1 + if aura and aura.spellId then + hitReduction.melee = hitReduction.melee + (Data.Aura.HitReductionMelee[aura.spellId] or 0) + hitReduction.ranged = hitReduction.ranged + (Data.Aura.HitReductionRanged[aura.spellId] or 0) + + for k,v in pairs(Data.Aura.HitReductionSpell) do + for s=1,MAX_SPELL_SCHOOLS do + if ((k == 0) or band(k,s-1) ~= 0x0) then + hitReduction.spell[s] = hitReduction.spell[s] + (v[aura.spellId] or 0) + end + end + end + end + until (not aura) + + if IsWotlk then + if IsSpellKnown(20582) then -- Quickness + hitReduction.melee = hitReduction.melee + 2 + hitReduction.ranged = hitReduction.ranged + 2 + end + if IsSpellKnown(822) then -- Magic Resistance + for s=1,MAX_SPELL_SCHOOLS do + if band(126,s-1) ~= 0x0 then + hitReduction.spell[s] = hitReduction.spell[s] + 2 + end + end + end + if IsSpellKnown(20579) then -- Magic Resistance + for s=1,MAX_SPELL_SCHOOLS do + if band(126,s-1) ~= 0x0 then + hitReduction.spell[s] = hitReduction.spell[s] + 2 + end + end + end + hitReduction.spell[ARCANE] = hitReduction.spell[ARCANE] + (IsSpellKnown(20592) and 2 or 0) -- Arcane Resistance + hitReduction.spell[FROST] = hitReduction.spell[FROST] + (IsSpellKnown(20596) and 2 or 0) -- Frost Resistance + hitReduction.spell[NATURE] = hitReduction.spell[NATURE] + (IsSpellKnown(20583) and 2 or 0) -- Nature Resistance + hitReduction.spell[NATURE] = hitReduction.spell[NATURE] + (IsSpellKnown(20551) and 2 or 0) -- Nature Resistance + hitReduction.spell[SHADOW] = hitReduction.spell[SHADOW] + (IsSpellKnown(59535) and 2 or 0) -- Shadow Resistance + hitReduction.spell[SHADOW] = hitReduction.spell[SHADOW] + (IsSpellKnown(59540) and 2 or 0) -- Shadow Resistance + hitReduction.spell[SHADOW] = hitReduction.spell[SHADOW] + (IsSpellKnown(59538) and 2 or 0) -- Shadow Resistance + hitReduction.spell[SHADOW] = hitReduction.spell[SHADOW] + (IsSpellKnown(59221) and 2 or 0) -- Shadow Resistance + hitReduction.spell[SHADOW] = hitReduction.spell[SHADOW] + (IsSpellKnown(59541) and 2 or 0) -- Shadow Resistance + hitReduction.spell[SHADOW] = hitReduction.spell[SHADOW] + (IsSpellKnown(59536) and 2 or 0) -- Shadow Resistance + end + + local spellMod = 0 + if classId == DEATHKNIGHT then + hitReduction.melee = hitReduction.melee + 1 * DataUtils:GetActiveTalentSpell(Talent[DEATHKNIGHT].FRIGID_DREADPLATE) + elseif classId == DRUID then + spellMod = 3 * DataUtils:GetActiveTalentSpell(Talent[DRUID].BALANCE_OF_POWER) -- 126 + elseif classId == HUNTER then + if not ECS.IsClassic then + local mod = 1 * DataUtils:GetActiveTalentSpell(Talent[HUNTER].DISPLACEMENT) + spellMod = mod -- 126 + hitReduction.ranged = hitReduction.ranged + mod + hitReduction.melee = hitReduction.melee + mod + end + elseif classId == MAGE then + if not ECS.IsClassic then + local mod = 1 * DataUtils:GetActiveTalentSpell(Talent[MAGE].ARCTIC_WINDS) + hitReduction.ranged = hitReduction.ranged + mod + hitReduction.melee = hitReduction.melee + mod + end + elseif classId == PALADIN then + if IsTBC then + spellMod = 1 * DataUtils:GetActiveTalentSpell(Talent[PALADIN].PURSUIT_OF_JUSTICE) -- 126 + elseif IsWotlk then + local mod = 2 * DataUtils:GetActiveTalentSpell(Talent[PALADIN].DIVINE_PURPOSE) + spellMod = mod -- 126 + hitReduction.ranged = hitReduction.ranged + mod -- 127 + end + elseif classId == ROGUE then + local mod = 2 * DataUtils:GetActiveTalentSpell(Talent[ROGUE].HEIGHTENED_SENSES) + spellMod = mod -- 126 + hitReduction.ranged = hitReduction.ranged + mod + elseif classId == WARRIOR then + spellMod = 2 * DataUtils:GetActiveTalentSpell(Talent[WARRIOR].IMPROVED_SPELL_REFLECTION) -- 126 + end + + for s=1,MAX_SPELL_SCHOOLS do + if band(126,s-1) ~= 0x0 then + hitReduction.spell[s] = hitReduction.spell[s] + spellMod + end + end + + return hitReduction +end diff --git a/types/types.lua b/types/types.lua index 48e5fe55..d4c96a14 100644 --- a/types/types.lua +++ b/types/types.lua @@ -27,3 +27,4 @@ ---@alias EquipSlot string ---@alias ItemLink string ---@alias Color string +---@alias Bitmask number \ No newline at end of file