├── scripts
├── GenerateBaseArmor
│ ├── .nvmrc
│ ├── .gitignore
│ ├── package.json
│ ├── GenerateBaseArmor.mts
│ └── tsconfig.json
└── GenerateStatLocales
│ ├── .nvmrc
│ ├── .gitignore
│ ├── TestCases.lua
│ ├── package.json
│ ├── StatLocaleData.json
│ └── tsconfig.json
├── RB-Example.jpg
├── images
└── Sigma.blp
├── .gitignore
├── .github
├── ISSUE_TEMPLATE
│ ├── feature_request.md
│ └── bug_report.yml
└── workflows
│ └── release.yml
├── LanguageServerOverrides.lua
├── .editorconfig
├── locales
├── locales.xml
└── enUS.lua
├── libs
└── StatLogic
│ ├── locales
│ ├── locales.xml
│ └── GlobalPatterns.lua
│ ├── StatLogic_TBC.toc
│ ├── StatLogic_Vanilla.toc
│ ├── StatLogic.toc
│ ├── StatLogic_Mists.toc
│ ├── StatLogic_Wrath.toc
│ ├── Init.lua
│ ├── Global_Logic.lua
│ ├── Stats.lua
│ ├── libs
│ └── UTF8
│ │ └── utf8.lua
│ └── DiminishingReturns.lua
├── embeds.xml
├── RatingBuster_TBC.toc
├── RatingBuster_Vanilla.toc
├── RatingBuster.toc
├── RatingBuster_Mists.toc
├── RatingBuster_Wrath.toc
├── .pkgmeta
├── TipHooker.lua
├── .luarc.json
├── README.md
├── changelog_pre_git.txt
├── reference.txt
└── LICENSE.txt
/scripts/GenerateBaseArmor/.nvmrc:
--------------------------------------------------------------------------------
1 | lts/jod
2 |
--------------------------------------------------------------------------------
/scripts/GenerateStatLocales/.nvmrc:
--------------------------------------------------------------------------------
1 | lts/jod
2 |
--------------------------------------------------------------------------------
/scripts/GenerateBaseArmor/.gitignore:
--------------------------------------------------------------------------------
1 | *.csv
2 | *.lua
3 |
--------------------------------------------------------------------------------
/scripts/GenerateStatLocales/.gitignore:
--------------------------------------------------------------------------------
1 | DB2
2 | locales
3 |
--------------------------------------------------------------------------------
/RB-Example.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raethkcj/RatingBuster/HEAD/RB-Example.jpg
--------------------------------------------------------------------------------
/images/Sigma.blp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raethkcj/RatingBuster/HEAD/images/Sigma.blp
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | libs/*
2 | !libs/TipHooker-1.0
3 | !libs/StatLogic
4 | .release
5 | .vscode
6 | node_modules
7 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: "[Feature Request]"
5 | labels: enhancement
6 | assignees: ''
7 |
8 | ---
9 |
10 |
11 |
--------------------------------------------------------------------------------
/scripts/GenerateStatLocales/TestCases.lua:
--------------------------------------------------------------------------------
1 | local L, StatLogic = {}, {}
2 | L["mana regen %s per %s sec"] = {StatLogic.Stats.ManaRegen, false, }
3 | L["%s health and mana every %s sec"] = {{StatLogic.Stats.HealthRegen, StatLogic.Stats.ManaRegen, }, false, }
4 | L["alle %s sek. %s mana"] = {false, StatLogic.Stats.ManaRegen, }
5 |
--------------------------------------------------------------------------------
/LanguageServerOverrides.lua:
--------------------------------------------------------------------------------
1 | ---@meta
2 |
3 | ---@class ClassicGameTooltip : GameTooltip
4 | local ClassicGameTooltip = {}
5 |
6 | ---@return integer
7 | function ClassicGameTooltip:NumLines() end
8 |
9 | ---@return Frame?
10 | function ClassicGameTooltip:GetOwner() end
11 |
12 | ---@param school 1|2|3|4|5|6|7
13 | ---@return number
14 | function GetSpellCritChance(school) end
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: https://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | [*]
7 | indent_style = tab
8 | indent_size = 4
9 | end_of_line = lf
10 | charset = utf-8
11 | trim_trailing_whitespace = true
12 | insert_final_newline = true
13 |
14 | [*.{lua,toc,xml}]
15 | end_of_line = crlf
16 | insert_final_newline = false
17 |
18 | [*.lua]
19 | trailing_table_separator = smart
20 |
21 | [.pkgmeta]
22 | indent_style = space
23 |
--------------------------------------------------------------------------------
/scripts/GenerateBaseArmor/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "generatebasearmor",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "GenerateBaseArmor.mts",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "GPL-2.0",
11 | "engines": {
12 | "node": "~22"
13 | },
14 | "dependencies": {
15 | "@duckdb/node-api": "^1.3.1-alpha.22"
16 | },
17 | "devDependencies": {
18 | "@types/node": "^22.10.5",
19 | "tsx": "^4.19.2"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/scripts/GenerateStatLocales/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "generatestatlocales",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "GenerateStatLocales.mjs",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "GPL-2.0",
11 | "engines": {
12 | "node": "~22"
13 | },
14 | "dependencies": {
15 | "@duckdb/node-api": "^1.3.1-alpha.22",
16 | "typescript": "^5.8.2"
17 | },
18 | "devDependencies": {
19 | "@types/node": "^22.10.5",
20 | "tsx": "^4.19.2"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/locales/locales.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/libs/StatLogic/locales/locales.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/libs/StatLogic/StatLogic_TBC.toc:
--------------------------------------------------------------------------------
1 | ## Interface: 20505
2 | ## Title: StatLogic
3 | ## IconTexture: Interface\AddOns\RatingBuster\images\icon_64.png
4 | ## Author: Whitetooth, raethkcj
5 | ## X-License: GPL v2
6 | ## Group: RatingBuster
7 |
8 | #@non-debug@
9 | # libs\LibStub\LibStub.lua
10 | # libs\CallbackHandler-1.0\CallbackHandler-1.0.xml
11 | # libs\AceComm-3.0\AceComm-3.0.xml
12 | # libs\LibSerialize\lib.xml
13 | # libs\LibDeflate\lib.xml
14 | #@end-non-debug@
15 |
16 | libs\UTF8\utf8data.lua
17 | libs\UTF8\utf8.lua
18 |
19 | Init.lua
20 | Stats.lua
21 |
22 | locales\locales.xml
23 |
24 | StatLogic.lua
25 | TBC_Logic.lua
26 | Global_Logic.lua
--------------------------------------------------------------------------------
/libs/StatLogic/StatLogic_Vanilla.toc:
--------------------------------------------------------------------------------
1 | ## Interface: 11507, 11508
2 | ## Title: StatLogic
3 | ## IconTexture: Interface\AddOns\RatingBuster\images\icon_64.png
4 | ## Author: Whitetooth, raethkcj
5 | ## X-License: GPL v2
6 | ## Group: RatingBuster
7 |
8 | #@non-debug@
9 | # libs\LibStub\LibStub.lua
10 | # libs\CallbackHandler-1.0\CallbackHandler-1.0.xml
11 | # libs\AceComm-3.0\AceComm-3.0.xml
12 | # libs\LibSerialize\lib.xml
13 | # libs\LibDeflate\lib.xml
14 | #@end-non-debug@
15 |
16 | libs\UTF8\utf8data.lua
17 | libs\UTF8\utf8.lua
18 |
19 | Init.lua
20 | Stats.lua
21 |
22 | locales\locales.xml
23 |
24 | StatLogic.lua
25 | Vanilla_Logic.lua
26 | Global_Logic.lua
--------------------------------------------------------------------------------
/libs/StatLogic/StatLogic.toc:
--------------------------------------------------------------------------------
1 | ## Interface: 40401, 40402
2 | ## Title: StatLogic
3 | ## IconTexture: Interface\AddOns\RatingBuster\images\icon_64.png
4 | ## Author: Whitetooth, raethkcj
5 | ## X-License: GPL v2
6 | ## Group: RatingBuster
7 |
8 | #@non-debug@
9 | # libs\LibStub\LibStub.lua
10 | # libs\CallbackHandler-1.0\CallbackHandler-1.0.xml
11 | # libs\AceComm-3.0\AceComm-3.0.xml
12 | # libs\LibSerialize\lib.xml
13 | # libs\LibDeflate\lib.xml
14 | #@end-non-debug@
15 |
16 | libs\UTF8\utf8data.lua
17 | libs\UTF8\utf8.lua
18 |
19 | Init.lua
20 | Stats.lua
21 |
22 | locales\locales.xml
23 |
24 | StatLogic.lua
25 | DiminishingReturns.lua
26 | Cata_Logic.lua
27 | Global_Logic.lua
--------------------------------------------------------------------------------
/libs/StatLogic/StatLogic_Mists.toc:
--------------------------------------------------------------------------------
1 | ## Interface: 50502, 50503
2 | ## Title: StatLogic
3 | ## IconTexture: Interface\AddOns\RatingBuster\images\icon_64.png
4 | ## Author: Whitetooth, raethkcj
5 | ## X-License: GPL v2
6 | ## Group: RatingBuster
7 |
8 | #@non-debug@
9 | # libs\LibStub\LibStub.lua
10 | # libs\CallbackHandler-1.0\CallbackHandler-1.0.xml
11 | # libs\AceComm-3.0\AceComm-3.0.xml
12 | # libs\LibSerialize\lib.xml
13 | # libs\LibDeflate\lib.xml
14 | #@end-non-debug@
15 |
16 | libs\UTF8\utf8data.lua
17 | libs\UTF8\utf8.lua
18 |
19 | Init.lua
20 | Stats.lua
21 |
22 | locales\locales.xml
23 |
24 | StatLogic.lua
25 | DiminishingReturns.lua
26 | Mists_Logic.lua
27 | Global_Logic.lua
--------------------------------------------------------------------------------
/libs/StatLogic/StatLogic_Wrath.toc:
--------------------------------------------------------------------------------
1 | ## Interface: 30403, 30404
2 | ## Title: StatLogic
3 | ## IconTexture: Interface\AddOns\RatingBuster\images\icon_64.png
4 | ## Author: Whitetooth, raethkcj
5 | ## X-License: GPL v2
6 | ## Group: RatingBuster
7 |
8 | #@non-debug@
9 | # libs\LibStub\LibStub.lua
10 | # libs\CallbackHandler-1.0\CallbackHandler-1.0.xml
11 | # libs\AceComm-3.0\AceComm-3.0.xml
12 | # libs\LibSerialize\lib.xml
13 | # libs\LibDeflate\lib.xml
14 | #@end-non-debug@
15 |
16 | libs\UTF8\utf8data.lua
17 | libs\UTF8\utf8.lua
18 |
19 | Init.lua
20 | Stats.lua
21 |
22 | locales\locales.xml
23 |
24 | StatLogic.lua
25 | DiminishingReturns.lua
26 | Wrath_Logic.lua
27 | Global_Logic.lua
--------------------------------------------------------------------------------
/embeds.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/RatingBuster_TBC.toc:
--------------------------------------------------------------------------------
1 | ## Interface: 20505
2 | ## Title: RatingBuster
3 | ## IconTexture: Interface\AddOns\RatingBuster\images\icon_64.png
4 | ## Notes: Item stat breakdown, analysis and comparison
5 | ## Notes-zhTW: 裝備數值解析與比較
6 | ## Author: Whitetooth, raethkcj
7 | ## SavedVariables: RatingBusterDB
8 | ## Dependencies: StatLogic
9 | ## OptionalDeps: Ace3
10 | ## X-Category: Interface Enhancements
11 | ## X-License: GPL v2
12 | ## X-WoWI-ID: 26235
13 | ## X-Wago-ID: RaN0eM6j
14 | ## X-Curse-Project-ID: 837687
15 | ## Group: RatingBuster
16 | ## Category: Equipment
17 | ## Category-deDE: Ausrüstung
18 | ## Category-esES: Equipo
19 | ## Category-esMX: Equipo
20 | ## Category-frFR: Équipement
21 | ## Category-itIT: Equipaggiamento
22 | ## Category-koKR: 장비
23 | ## Category-ptBR: Equipamento
24 | ## Category-ruRU: Экипировка
25 | ## Category-zhCN: 装备
26 | ## Category-zhTW: 裝備
27 |
28 | # Libraries
29 | embeds.xml
30 |
31 | # Localization
32 | locales\locales.xml
33 |
34 | # Core
35 | TipHooker.lua
36 | RatingBuster.lua
37 |
--------------------------------------------------------------------------------
/RatingBuster_Vanilla.toc:
--------------------------------------------------------------------------------
1 | ## Interface: 11507, 11508
2 | ## Title: RatingBuster
3 | ## IconTexture: Interface\AddOns\RatingBuster\images\icon_64.png
4 | ## Notes: Item stat breakdown, analysis and comparing
5 | ## Notes-zhTW: 裝備數值解析與比較
6 | ## Author: Whitetooth, raethkcj
7 | ## SavedVariables: RatingBusterDB
8 | ## Dependencies: StatLogic
9 | ## OptionalDeps: Ace3
10 | ## X-Category: Interface Enhancements
11 | ## X-License: GPL v2
12 | ## X-WoWI-ID: 26235
13 | ## X-Wago-ID: RaN0eM6j
14 | ## X-Curse-Project-ID: 837687
15 | ## Group: RatingBuster
16 | ## Category: Equipment
17 | ## Category-deDE: Ausrüstung
18 | ## Category-esES: Equipo
19 | ## Category-esMX: Equipo
20 | ## Category-frFR: Équipement
21 | ## Category-itIT: Equipaggiamento
22 | ## Category-koKR: 장비
23 | ## Category-ptBR: Equipamento
24 | ## Category-ruRU: Экипировка
25 | ## Category-zhCN: 装备
26 | ## Category-zhTW: 裝備
27 |
28 | # Libraries
29 | embeds.xml
30 |
31 | # Localization
32 | locales\locales.xml
33 |
34 | # Core
35 | TipHooker.lua
36 | RatingBuster.lua
37 |
--------------------------------------------------------------------------------
/RatingBuster.toc:
--------------------------------------------------------------------------------
1 | ## Interface: 40401, 40402
2 | ## Title: RatingBuster
3 | ## IconTexture: Interface\AddOns\RatingBuster\images\icon_64.png
4 | ## Notes: Item stat breakdown, analysis and comparison
5 | ## Notes-zhTW: 裝備數值解析與比較
6 | ## Author: Whitetooth, raethkcj
7 | ## SavedVariables: RatingBusterDB
8 | ## Dependencies: StatLogic
9 | ## OptionalDeps: Ace3, LibDualSpec-1.0
10 | ## X-Category: Interface Enhancements
11 | ## X-License: GPL v2
12 | ## X-WoWI-ID: 26235
13 | ## X-Wago-ID: RaN0eM6j
14 | ## X-Curse-Project-ID: 837687
15 | ## Group: RatingBuster
16 | ## Category: Equipment
17 | ## Category-deDE: Ausrüstung
18 | ## Category-esES: Equipo
19 | ## Category-esMX: Equipo
20 | ## Category-frFR: Équipement
21 | ## Category-itIT: Equipaggiamento
22 | ## Category-koKR: 장비
23 | ## Category-ptBR: Equipamento
24 | ## Category-ruRU: Экипировка
25 | ## Category-zhCN: 装备
26 | ## Category-zhTW: 裝備
27 |
28 | # Libraries
29 | embeds.xml
30 |
31 | # Localization
32 | locales\locales.xml
33 |
34 | # Core
35 | TipHooker.lua
36 | RatingBuster.lua
37 |
--------------------------------------------------------------------------------
/RatingBuster_Mists.toc:
--------------------------------------------------------------------------------
1 | ## Interface: 50502, 50503
2 | ## Title: RatingBuster
3 | ## IconTexture: Interface\AddOns\RatingBuster\images\icon_64.png
4 | ## Notes: Item stat breakdown, analysis and comparison
5 | ## Notes-zhTW: 裝備數值解析與比較
6 | ## Author: Whitetooth, raethkcj
7 | ## SavedVariables: RatingBusterDB
8 | ## Dependencies: StatLogic
9 | ## OptionalDeps: Ace3, LibDualSpec-1.0
10 | ## X-Category: Interface Enhancements
11 | ## X-License: GPL v2
12 | ## X-WoWI-ID: 26235
13 | ## X-Wago-ID: RaN0eM6j
14 | ## X-Curse-Project-ID: 837687
15 | ## Group: RatingBuster
16 | ## Category: Equipment
17 | ## Category-deDE: Ausrüstung
18 | ## Category-esES: Equipo
19 | ## Category-esMX: Equipo
20 | ## Category-frFR: Équipement
21 | ## Category-itIT: Equipaggiamento
22 | ## Category-koKR: 장비
23 | ## Category-ptBR: Equipamento
24 | ## Category-ruRU: Экипировка
25 | ## Category-zhCN: 装备
26 | ## Category-zhTW: 裝備
27 |
28 | # Libraries
29 | embeds.xml
30 |
31 | # Localization
32 | locales\locales.xml
33 |
34 | # Core
35 | TipHooker.lua
36 | RatingBuster.lua
37 |
--------------------------------------------------------------------------------
/RatingBuster_Wrath.toc:
--------------------------------------------------------------------------------
1 | ## Interface: 30403, 30404
2 | ## Title: RatingBuster
3 | ## IconTexture: Interface\AddOns\RatingBuster\images\icon_64.png
4 | ## Notes: Item stat breakdown, analysis and comparison
5 | ## Notes-zhTW: 裝備數值解析與比較
6 | ## Author: Whitetooth, raethkcj
7 | ## SavedVariables: RatingBusterDB
8 | ## Dependencies: StatLogic
9 | ## OptionalDeps: Ace3, LibDualSpec-1.0
10 | ## X-Category: Interface Enhancements
11 | ## X-License: GPL v2
12 | ## X-WoWI-ID: 26235
13 | ## X-Wago-ID: RaN0eM6j
14 | ## X-Curse-Project-ID: 837687
15 | ## Group: RatingBuster
16 | ## Category: Equipment
17 | ## Category-deDE: Ausrüstung
18 | ## Category-esES: Equipo
19 | ## Category-esMX: Equipo
20 | ## Category-frFR: Équipement
21 | ## Category-itIT: Equipaggiamento
22 | ## Category-koKR: 장비
23 | ## Category-ptBR: Equipamento
24 | ## Category-ruRU: Экипировка
25 | ## Category-zhCN: 装备
26 | ## Category-zhTW: 裝備
27 |
28 | # Libraries
29 | embeds.xml
30 |
31 | # Localization
32 | locales\locales.xml
33 |
34 | # Core
35 | TipHooker.lua
36 | RatingBuster.lua
37 |
--------------------------------------------------------------------------------
/libs/StatLogic/Init.lua:
--------------------------------------------------------------------------------
1 | local addonName = ...
2 |
3 | --[[
4 | Name: StatLogic-1.0
5 | Description: A Library for stat conversion, calculation and summarization.
6 | Author: Whitetooth
7 | Email: hotdogee [at] gmail [dot] com
8 | Website:
9 | Documentation:
10 | License: LGPL v2.1
11 | Features:
12 | StatConversion -
13 | Ratings -> Effect
14 | Str -> AP, Block
15 | Agi -> Crit, Dodge, AP, RAP, Armor
16 | Sta -> Health, SpellDmg(Talant)
17 | Int -> Mana, SpellCrit
18 | Spi -> MP5, HP5
19 | and more!
20 | StatMods - Get stat mods from talants and buffs for every class
21 | BaseStats - for all classes and levels
22 | ItemStatParser - Fast multi level indexing algorithm instead of calling strfind for every stat
23 | ]]
24 |
25 | -- This library is still in early development, please consider not using this library until the documentation is writen on wowace.
26 | -- Unless you don't mind putting up with breaking changes that may or may not happen during early development.
27 |
28 | --[===[@non-debug@
29 | -- Add 80000 to always supercede Whitetooth's revisions
30 | local MINOR_VERSION = 80000 + @project-revision@
31 | --@end-non-debug@]===]
32 | --@debug@
33 | local MINOR_VERSION = 2 ^ 32 -- LibStub doesn't accept math.huge as a number
34 | --@end-debug@
35 |
36 | ---@class StatLogic
37 | local StatLogic = LibStub:NewLibrary(addonName, MINOR_VERSION)
--------------------------------------------------------------------------------
/.pkgmeta:
--------------------------------------------------------------------------------
1 | package-as: RatingBuster
2 |
3 | externals:
4 | libs/StatLogic/libs/LibSerialize:
5 | url: https://github.com/rossnichols/LibSerialize.git
6 | tag: v1.1.3
7 | libs/StatLogic/libs/LibDeflate:
8 | url: https://github.com/SafeteeWoW/LibDeflate.git
9 | tag: 1.0.2-release
10 | libs/LibDualSpec-1.0:
11 | url: git://git.wowace.com/wow/libdualspec-1-0/mainline.git
12 | ../Ace3:
13 | url: https://github.com/WoWUIDev/Ace3.git
14 |
15 | move-folders:
16 | RatingBuster/libs/StatLogic: StatLogic
17 | Ace3/LibStub: StatLogic/libs/LibStub
18 | Ace3/CallbackHandler-1.0: StatLogic/libs/CallbackHandler-1.0
19 | Ace3/AceComm-3.0: StatLogic/libs/AceComm-3.0
20 | Ace3/AceLocale-3.0: RatingBuster/libs/AceLocale-3.0
21 | Ace3/AceConsole-3.0: RatingBuster/libs/AceConsole-3.0
22 | Ace3/AceEvent-3.0: RatingBuster/libs/AceEvent-3.0
23 | Ace3/AceTimer-3.0: RatingBuster/libs/AceTimer-3.0
24 | Ace3/AceBucket-3.0: RatingBuster/libs/AceBucket-3.0
25 | Ace3/AceDB-3.0: RatingBuster/libs/AceDB-3.0
26 | Ace3/AceDBOptions-3.0: RatingBuster/libs/AceDBOptions-3.0
27 | Ace3/AceAddon-3.0: RatingBuster/libs/AceAddon-3.0
28 | Ace3/AceGUI-3.0: RatingBuster/libs/AceGUI-3.0
29 | Ace3/AceConfig-3.0: RatingBuster/libs/AceConfig-3.0
30 |
31 | embedded-libraries:
32 | - Ace3
33 | - libdeflate
34 |
35 | ignore:
36 | - ./*.txt
37 | - *.jpg
38 | - scripts
39 | - LanguageServerOverrides.lua
40 | - **/libs/**/*.rockspec
41 | - **/libs/**/changelog.*
42 | - **/libs/**/CHANGELOG.*
43 | - **/libs/**/docs
44 | - **/libs/**/examples
45 | - **/libs/**/tests
46 |
47 | plain-copy:
48 | - LICENSE.txt
49 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | # description of this workflow, can be anything you want
2 | name: Package and release
3 |
4 | # we need to let GitHub know _when_ we want to release, typically only when we create a new tag.
5 | # this will target only tags, and not all pushes to the master branch.
6 | # this part can be heavily customized to your liking, like targeting only tags that match a certain word,
7 | # other branches or even pullrequests.
8 | on:
9 | push:
10 | tags:
11 | - '**'
12 | workflow_dispatch:
13 |
14 | # a workflow is built up as jobs, and within these jobs are steps
15 | jobs:
16 |
17 | # "release" is a job, you can name it anything you want
18 | release:
19 |
20 | # we can run our steps on pretty much anything, but the "ubuntu-latest" image is a safe bet
21 | runs-on: ubuntu-latest
22 |
23 | # specify the environment variables used by the packager, matching the secrets from the project on GitHub
24 | env:
25 | CF_API_KEY: ${{ secrets.CF_API_KEY }}
26 | WOWI_API_TOKEN: ${{ secrets.WOWI_API_TOKEN }}
27 | WAGO_API_TOKEN: ${{ secrets.WAGO_API_TOKEN }}
28 | GITHUB_OAUTH: ${{ secrets.GITHUB_TOKEN }} # "GITHUB_TOKEN" is a secret always provided to the workflow
29 | # for your own token, the name cannot start with "GITHUB_"
30 |
31 | # "steps" holds a list of all the steps needed to package and release our AddOn
32 | steps:
33 |
34 | # we first have to clone the AddOn project, this is a required step
35 | - name: Clone project
36 | uses: actions/checkout@v1
37 | with:
38 | # you can specify how much of the commit history you want to fetch,
39 | # which is useful for controlling the length of the automated changelog
40 | fetch-depth: 50
41 |
42 | # once cloned, we just run the GitHub Action for the packager project
43 | - name: Package and release
44 | uses: BigWigsMods/packager@v2
45 |
--------------------------------------------------------------------------------
/scripts/GenerateStatLocales/StatLocaleData.json:
--------------------------------------------------------------------------------
1 | {
2 | "SpellItemEnchantment": {
3 | "1": {
4 | "2412": [ ["HealthRegen"] ],
5 | "2591": [ ["Intellect"], ["Stamina"], ["HealingPower"] ],
6 | "7615": [ ["Stamina"], ["Strength"], ["Agility"] ],
7 | "7635": [ ["Stamina"], ["Agility"], ["Strength"] ]
8 | },
9 | "2": {
10 | "2583": [ ["DefenseRating"], ["Stamina"], ["BlockValue"] ],
11 | "2584": [ ["Defense"], ["Stamina"], ["HealingPower"] ],
12 | "2586": [ ["RangedAttackPower"], ["Stamina"], ["HitRating"] ],
13 | "2591": [ ["Intellect"], ["Stamina"], ["HealingPower"] ],
14 | "2705": [ ["HealingPower"], ["SpellDamage"], ["Intellect"] ],
15 | "2752": [ ["MeleeCritRating", "RangedCritRating"], ["Strength"] ],
16 | "2756": [ ["MeleeHitRating", "RangedHitRating"], ["Agility"] ],
17 | "3000": [ ["Stamina"], ["DodgeRating"], ["ResilienceRating"] ],
18 | "3081": [ ["HealingPower"], ["SpellDamage"], ["SpellCritRating"] ],
19 | "3161": [ ["Stamina"], ["SpellCritRating"] ]
20 | },
21 | "3": {
22 | "2591": [ ["Intellect"], ["Stamina"], ["SpellPower"] ],
23 | "3754": [ ["GenericAttackPower"], ["Stamina"], ["HitRating"] ]
24 | },
25 | "4": {
26 | "2584": [ ["DodgeRating"], ["Stamina"], ["Intellect"] ],
27 | "2705": [ ["HasteRating"], ["Intellect"] ],
28 | "3113": [ ["CritRating"], ["Agility"] ],
29 | "3513": [ ["Spirit"], ["ResilienceRating"] ],
30 | "3885": [ ["MasteryRating"], ["Spirit"] ],
31 | "3886": [ ["MasteryRating"], ["HitRating"] ],
32 | "4280": [ ["HitRating"], ["MasteryRating"] ],
33 | "4282": [ ["Spirit"], ["MasteryRating"] ]
34 | },
35 | "5": {
36 | "2584": [ ["DodgeRating"], ["Stamina"], ["Intellect"] ],
37 | "2760": [ ["CritRating"], ["Intellect"] ],
38 | "3000": [ ["Stamina"], ["DodgeRating"], ["ResilienceRating"] ],
39 | "3113": [ ["CritRating"], ["Agility"] ],
40 | "3513": [ ["Spirit"], ["ResilienceRating"] ],
41 | "3754": [ ["GenericAttackPower"], ["Stamina"], ["HitRating"] ],
42 | "3885": [ ["MasteryRating"], ["Spirit"] ],
43 | "3886": [ ["MasteryRating"], ["HitRating"] ],
44 | "4280": [ ["HitRating"], ["MasteryRating"] ],
45 | "4282": [ ["Spirit"], ["MasteryRating"] ],
46 | "4671": [ ["Strength"], ["ParryRating"], ["CritRating"] ]
47 | }
48 | },
49 | "Spell": {
50 | "1": {
51 | "24694": [ ["FeralAttackPower"] ]
52 | },
53 | "2": {
54 | "24694": [ ["FeralAttackPower"] ]
55 | },
56 | "3": {},
57 | "4": {},
58 | "5": {}
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.yml:
--------------------------------------------------------------------------------
1 | name: Bug Report
2 | description: File a bug report
3 | title: "[Bug] "
4 | labels: ["bug"]
5 | body:
6 | - type: textarea
7 | id: description
8 | attributes:
9 | label: Describe the bug
10 | placeholder: A clear and concise description of what the bug is.
11 | validations:
12 | required: true
13 | - type: dropdown
14 | id: source
15 | attributes:
16 | label: Addon Source
17 | description: Where did you download the addon?
18 | options:
19 | - WoWInterface
20 | - Wago Addons
21 | - WowUp
22 | - GitHub Releases
23 | - CurseForge
24 | validations:
25 | required: true
26 | - type: input
27 | id: version
28 | attributes:
29 | label: Version
30 | description: What version of the addon do you have installed?
31 | placeholder: 1.0.0
32 | validations:
33 | required: true
34 | - type: dropdown
35 | id: locale
36 | attributes:
37 | label: Locale
38 | description: What locale (language) do you play WoW in?
39 | options:
40 | - English
41 | - Chinese (China)
42 | - Chinese (Taiwan)
43 | - French
44 | - German
45 | - Italian
46 | - Korean
47 | - Portuguese
48 | - Russian
49 | - Spanish (Mexico)
50 | - Spanish (Spain)
51 | - Other
52 | validations:
53 | required: true
54 | - type: dropdown
55 | id: specialization
56 | attributes:
57 | label: Talent Specialization
58 | description: What is your character's talent specialization?
59 | multiple: true
60 | options:
61 | - Blood Death Knight
62 | - Frost Death Knight
63 | - Unholy Death Knight
64 | - Balance Druid
65 | - Feral Druid
66 | - Guardian Druid
67 | - Restoration Druid
68 | - Beast Mastery Hunter
69 | - Marksmanship Hunter
70 | - Survival Hunter
71 | - Arcane Mage
72 | - Fire Mage
73 | - Frost Mage
74 | - Brewmaster Monk
75 | - Mistweaver Monk
76 | - Windwalker Monk
77 | - Holy Paladin
78 | - Protection Paladin
79 | - Retribution Paladin
80 | - Discipline Priest
81 | - Holy Priest
82 | - Shadow Priest
83 | - Assassination Rogue
84 | - Combat Rogue
85 | - Subtlety Rogue
86 | - Elemental Shaman
87 | - Enhancement Shaman
88 | - Restoration Shaman
89 | - Affliction Warlock
90 | - Demonology Warlock
91 | - Destruction Warlock
92 | - Arms Warrior
93 | - Fury Warrior
94 | - Protection Warrior
95 | validations:
96 | required: true
97 | - type: dropdown
98 | id: race
99 | attributes:
100 | label: Race
101 | description: What is your character's race?
102 | multiple: true
103 | options:
104 | - Blood Elf
105 | - Draenei
106 | - Dwarf
107 | - Gnome
108 | - Goblin
109 | - Human
110 | - Night Elf
111 | - Orc
112 | - Pandaren
113 | - Tauren
114 | - Troll
115 | - Undead
116 | - Worgen
117 | validations:
118 | required: true
119 |
--------------------------------------------------------------------------------
/TipHooker.lua:
--------------------------------------------------------------------------------
1 | local addonName, addon = ...
2 |
3 | local handler
4 | local enabled = false
5 |
6 | local RunHandler = function(tooltip)
7 | if enabled then
8 | handler(tooltip)
9 | end
10 | end
11 |
12 | local queuedTooltips = {}
13 |
14 | local function HandleUpdate(tooltip)
15 | if queuedTooltips[tooltip] then
16 | RunHandler(tooltip)
17 | queuedTooltips[tooltip] = nil
18 | end
19 | end
20 |
21 | local function QueueUpdate(tooltip)
22 | queuedTooltips[tooltip] = true
23 | end
24 |
25 | local directUpdateTypes = {
26 | ["GameTooltip"] = true,
27 | ["CheckButton"] = true,
28 | }
29 |
30 | local function HandleTooltipSetItem(tooltip)
31 | local owner = tooltip:GetOwner()
32 | -- Hacky workaround for ShoppingTooltip and InspectFrame,
33 | -- which fire OnUpdate before OnTooltipSetItem each frame
34 | if (owner and owner.GetObjectType and directUpdateTypes[owner:GetObjectType()]) or debugstack():find("OnUpdate") then
35 | RunHandler(tooltip)
36 | elseif owner then
37 | -- OnTooltipSetItem can be fired several times per frame,
38 | -- So we defer the actual update until OnUpdate
39 | QueueUpdate(tooltip)
40 | if not tooltip:GetScript("OnUpdate") then
41 | -- Workaround for ItemRefTooltip cannibalizing its OnUpdate handler
42 | tooltip:SetScript("OnUpdate", function(self)
43 | HandleUpdate(self)
44 | self:SetScript("OnUpdate", nil)
45 | end)
46 | end
47 | end
48 | end
49 |
50 | local tooltips = {
51 | ["GameTooltip"] = true,
52 | ["ShoppingTooltip1"] = true,
53 | ["ShoppingTooltip2"] = true,
54 | ["ItemRefTooltip"] = true,
55 | ["ItemRefShoppingTooltip1"] = true,
56 | ["ItemRefShoppingTooltip2"] = true,
57 | ["AtlasLootTooltip"] = true,
58 | }
59 |
60 | local staticItemSetters = {
61 | ["SetHyperlink"] = true,
62 | ["SetItemByID"] = true,
63 | }
64 |
65 | local tooltipNeedsRepaint = {}
66 |
67 | local initialized = false
68 | local function InitializeHook()
69 | for tooltipName in pairs(tooltips) do
70 | local tooltip = _G[tooltipName]
71 | if tooltip then
72 | tooltip:HookScript("OnTooltipSetItem", HandleTooltipSetItem)
73 | tooltip:HookScript("OnUpdate", HandleUpdate)
74 |
75 | -- Tooltips set by location (bag slot, inventory slot, etc.)
76 | -- are usually automatically redrawn every TOOLTIP_UPDATE_TIME.
77 | -- Tooltips set by link or ID are not, so we manually repaint them.
78 | for functionName in pairs(staticItemSetters) do
79 | hooksecurefunc(tooltip, functionName, function(self)
80 | tooltipNeedsRepaint[self] = true
81 | end)
82 | tooltip:HookScript("OnHide", function(self)
83 | tooltipNeedsRepaint[self] = nil
84 | end)
85 | end
86 | end
87 | end
88 | initialized = true
89 | end
90 |
91 | local variablesLoaded = false
92 | EventRegistry:RegisterFrameEventAndCallbackWithHandle("VARIABLES_LOADED", function()
93 | variablesLoaded = true
94 | if handler and not initialized then
95 | InitializeHook()
96 | end
97 | if LinkWrangler then
98 | LinkWrangler.RegisterCallback(addonName, RunHandler, "item", "refreshcomp");
99 | end
100 | end)
101 |
102 | function addon.RepaintStaticTooltips()
103 | ---@type GameTooltip?
104 | for tooltip in pairs(tooltipNeedsRepaint) do
105 | if tooltip and tooltip.GetItem then
106 | local _, itemLink = tooltip:GetItem()
107 | if itemLink then
108 | tooltip:ClearLines()
109 | tooltip:SetHyperlink(itemLink)
110 | end
111 | end
112 | end
113 | end
114 |
115 | function addon:EnableHook(h)
116 | handler = h
117 | if variablesLoaded and not initialized then
118 | InitializeHook()
119 | end
120 | enabled = true
121 | end
122 |
123 | function addon:DisableHook()
124 | enabled = false
125 | end
--------------------------------------------------------------------------------
/libs/StatLogic/Global_Logic.lua:
--------------------------------------------------------------------------------
1 | local addonName, addon = ...
2 | ---@class StatLogic
3 | local StatLogic = LibStub(addonName)
4 |
5 | local RatingScalars = {
6 | 0.03846150, 0.03846150, 0.03846150, 0.03846150, 0.03846150, 0.03846150, 0.03846150, 0.03846150, 0.03846150, 0.03846150,
7 | 0.05769232, 0.07692309, 0.09615381, 0.11538458, 0.13461540, 0.15384622, 0.17307690, 0.19230772, 0.21153854, 0.23076922,
8 | 0.24999999, 0.26923081, 0.28846148, 0.30769230, 0.32692312, 0.34615375, 0.36538462, 0.38461539, 0.40384621, 0.42307689,
9 | 0.44230761, 0.46153843, 0.48076930, 0.50000002, 0.51923075, 0.53846147, 0.55769229, 0.57692302, 0.59615379, 0.61538461,
10 | 0.63461533, 0.65384615, 0.67307692, 0.69230765, 0.71153847, 0.73076929, 0.74999996, 0.76923078, 0.78846160, 0.80769228,
11 | 0.82692315, 0.84615392, 0.86538460, 0.88461537, 0.90384624, 0.92307691, 0.94230768, 0.96153855, 0.98076923, 1.00000000,
12 | 1.03797464, 1.07894744, 1.12328768, 1.17142849, 1.22388062, 1.28125003, 1.34426230, 1.41379307, 1.49090911, 1.57692297,
13 | 1.69669417, 1.82556218, 1.96421831, 2.11340541, 2.27392361, 2.44663375, 2.63246166, 2.83240353, 3.04753145, 3.27899897,
14 | 4.30560143, 5.65397461, 7.42754553, 9.75272320, 12.80571629, 16.25000000, 20.78000000, 26.40000000, 33.69000000, 42.79000000,
15 | }
16 |
17 | local PvpScalars = {
18 | [81] = 4.09289612,
19 | [82] = 5.10881490,
20 | [83] = 6.37689952,
21 | [84] = 7.95974263,
22 | [85] = 9.93547022,
23 | [86] = 12.4800000,
24 | [87] = 16.2300000,
25 | [88] = 20.4500000,
26 | [89] = 26.2800000,
27 | [90] = 33.3500000,
28 | }
29 | setmetatable(PvpScalars, { __index = RatingScalars })
30 |
31 | ---@param stat Stat
32 | ---@param level number
33 | ---@return number
34 | function addon.GetRatingScalar(stat, level)
35 | if stat == StatLogic.Stats.ResilienceRating or stat == StatLogic.Stats.PvpPowerRating then
36 | return PvpScalars[level]
37 | else
38 | return RatingScalars[level]
39 | end
40 | end
41 |
42 | StatLogic.StatModTable["GLOBAL"] = {
43 | ["ADD_WEAPON_DAMAGE_AVERAGE_MOD_WEAPON_DAMAGE_MIN"] = {
44 | -- Base
45 | {
46 | ["value"] = 0.5,
47 | }
48 | },
49 | ["ADD_WEAPON_DAMAGE_AVERAGE_MOD_WEAPON_DAMAGE_MAX"] = {
50 | -- Base
51 | {
52 | ["value"] = 0.5,
53 | }
54 | },
55 | ["ADD_AP_MOD_GENERIC_ATTACK_POWER"] = {
56 | {
57 | value = 1,
58 | },
59 | },
60 | ["ADD_RANGED_AP_MOD_GENERIC_ATTACK_POWER"] = {
61 | {
62 | value = 1,
63 | },
64 | },
65 | ["ADD_MELEE_CRIT_MOD_AGI"] = {
66 | {
67 | ["level"] = addon.conversionFallback(addon.CritPerAgi[addon.class], StatLogic.GetCritPerAgi),
68 | }
69 | },
70 | ["ADD_RANGED_CRIT_MOD_AGI"] = {
71 | {
72 | ["level"] = addon.CritPerAgi[addon.class]
73 | }
74 | },
75 | ["ADD_MANA_REGEN_MOD_GENERIC_MANA_REGEN"] = {
76 | {
77 | ["value"] = 1,
78 | }
79 | },
80 | ["ADD_SPELL_CRIT_MOD_INT"] = {
81 | {
82 | ["level"] = addon.conversionFallback(addon.SpellCritPerInt[addon.class], StatLogic.GetSpellCritPerInt),
83 | }
84 | },
85 | ["ADD_DODGE_MOD_AGI"] = {
86 | {
87 | ["level"] = addon.conversionFallback(addon.DodgePerAgi[addon.class], StatLogic.GetDodgePerAgi)
88 | }
89 | },
90 | ["ADD_SPELL_DMG_MOD_SPELL_POWER"] = {
91 | {
92 | ["value"] = 1,
93 | },
94 | },
95 | ["ADD_HEALING_MOD_SPELL_POWER"] = {
96 | {
97 | ["value"] = 1,
98 | },
99 | },
100 | }
101 |
102 | addon.GenerateWeaponSubclassStats()
103 |
104 | for stat in pairs(StatLogic.RatingBase) do
105 | local rating_name = stat.name:gsub("(%l)(%u)", "%1_%2"):upper()
106 | local add = rating_name:gsub("_RATING$", "")
107 | local mod = rating_name
108 | local stat_mod = {
109 | add = add,
110 | mod = mod,
111 | initialValue = 0,
112 | finalAdjust = 0,
113 | }
114 | local name = ("ADD_%s_MOD_%s"):format(stat_mod.add, stat_mod.mod)
115 | StatLogic.StatModInfo[name] = stat_mod
116 | StatLogic.StatModTable["GLOBAL"][name] = {
117 | {
118 | ["level"] = setmetatable({}, {
119 | __index = function(t, level)
120 | t[level] = StatLogic:GetEffectFromRating(1, stat, level)
121 | return t[level]
122 | end
123 | }),
124 | }
125 | }
126 | end
--------------------------------------------------------------------------------
/scripts/GenerateBaseArmor/GenerateBaseArmor.mts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env -S node --import=tsx
2 |
3 | import { writeFileSync } from 'node:fs'
4 | import { DuckDBInstance } from '@duckdb/node-api'
5 |
6 | // Subset of InventoryTypes that can contain a mix of Armor and Bonus Armor
7 | // https://warcraft.wiki.gg/wiki/Enum.InventoryType
8 | enum InventoryType {
9 | Head = 1,
10 | Shoulder = 3,
11 | Chest = 5,
12 | Waist = 6,
13 | Legs = 7,
14 | Feet = 8,
15 | Wrist = 9,
16 | Hands = 10,
17 | Shield = 14,
18 | Cloak = 16,
19 | Robe = 20,
20 | }
21 | const inventoryTypes = Object.values(InventoryType).filter(v => Number.isInteger(v))
22 |
23 | // https://warcraft.wiki.gg/wiki/InventorySlotID
24 | enum InventorySlot {
25 | None = 0,
26 | HEADSLOT = 1,
27 | SHOULDERSLOT = 3,
28 | CHESTSLOT = 5,
29 | WAISTSLOT = 6,
30 | LEGSSLOT = 7,
31 | FEETSLOT = 8,
32 | WRISTSLOT = 9,
33 | HANDSSLOT = 10,
34 | SECONDARYHANDSLOT = 17,
35 | BACKSLOT = 15,
36 | }
37 |
38 | const InventoryTypeSlots: Record = {
39 | [InventoryType.Head]: InventorySlot.HEADSLOT,
40 | [InventoryType.Shoulder]: InventorySlot.SHOULDERSLOT,
41 | [InventoryType.Chest]: InventorySlot.CHESTSLOT,
42 | [InventoryType.Waist]: InventorySlot.WAISTSLOT,
43 | [InventoryType.Legs]: InventorySlot.LEGSSLOT,
44 | [InventoryType.Feet]: InventorySlot.FEETSLOT,
45 | [InventoryType.Wrist]: InventorySlot.WRISTSLOT,
46 | [InventoryType.Hands]: InventorySlot.HANDSSLOT,
47 | [InventoryType.Shield]: InventorySlot.SECONDARYHANDSLOT,
48 | [InventoryType.Cloak]: InventorySlot.BACKSLOT,
49 | [InventoryType.Robe]: InventorySlot.CHESTSLOT,
50 | }
51 |
52 | // https://warcraft.wiki.gg/wiki/Enum.ItemQuality
53 | enum ItemQuality {
54 | "Enum.ItemQuality.Poor" = 0,
55 | "Enum.ItemQuality.Standard or Enum.ItemQuality.Common" = 1, // in-game doesn't match wiki
56 | "Enum.ItemQuality.Good or Enum.ItemQuality.Uncommon" = 2, // in-game doesn't match wiki
57 | "Enum.ItemQuality.Rare" = 3,
58 | "Enum.ItemQuality.Epic" = 4,
59 | "Enum.ItemQuality.Legendary" = 5,
60 | "Enum.ItemQuality.Artifact" = 6,
61 | "Enum.ItemQuality.Heirloom" = 7,
62 | "Enum.ItemQuality.WoWToken" = 8,
63 | }
64 |
65 | // https://warcraft.wiki.gg/wiki/ItemType#4:_Armor
66 | enum ItemArmorSubclass {
67 | "Enum.ItemArmorSubclass.Cloth" = 1,
68 | "Enum.ItemArmorSubclass.Leather" = 2,
69 | "Enum.ItemArmorSubclass.Mail" = 3,
70 | "Enum.ItemArmorSubclass.Plate" = 4,
71 | "Enum.ItemArmorSubclass.Shield" = 6,
72 | }
73 |
74 | type Item = {
75 | ID: number
76 | OverallQualityID: ItemQuality
77 | InventoryType: InventoryType
78 | Resistances_0: number
79 | ItemLevel: number
80 | SubclassID: ItemArmorSubclass
81 | ShieldArmor: number
82 | SubclassArmorTotal: number
83 | ArmorLocationModifier: number
84 | ArmorQualityModifier: number
85 |
86 | ComputedArmor: number
87 | }
88 |
89 | const ItemStatBonusArmor = 50
90 |
91 | // Expects the DB2 tables in FROM and JOIN clauses to be in CSV format in the same directory.
92 | // Fetch from Wago or use a DB2 to CSV tool.
93 | // For older versions of the game, ItemArmor* and ArmorLocation can be ignored and ItemSparse.Resistances_0 can be used directly.
94 | const query = `
95 | SET VARIABLE types = ['INTEGER', 'DOUBLE', 'VARCHAR'];
96 | SELECT
97 | ItemSparse.ID, ItemSparse.OverallQualityID, ItemSparse.InventoryType, ItemSparse.Resistances_0, ItemSparse.ItemLevel,
98 | Item.SubclassID,
99 | [
100 | ItemArmorTotal.Cloth,
101 | ItemArmorTotal.Leather,
102 | ItemArmorTotal.Mail,
103 | ItemArmorTotal.Plate
104 | ][Item.SubclassID] AS SubclassArmorTotal,
105 | [
106 | ArmorLocation.Clothmodifier,
107 | ArmorLocation.Leathermodifier,
108 | ArmorLocation.Chainmodifier,
109 | ArmorLocation.Platemodifier
110 | ][Item.SubclassID] AS ArmorLocationModifier,
111 | [
112 | ItemArmorQuality.Qualitymod_0,
113 | ItemArmorQuality.Qualitymod_1,
114 | ItemArmorQuality.Qualitymod_2,
115 | ItemArmorQuality.Qualitymod_3,
116 | ItemArmorQuality.Qualitymod_4,
117 | ItemArmorQuality.Qualitymod_5,
118 | ItemArmorQuality.Qualitymod_6
119 | ][ItemSparse.OverallQualityID + 1] AS ArmorQualityModifier,
120 | [
121 | ItemArmorShield.Quality_0,
122 | ItemArmorShield.Quality_1,
123 | ItemArmorShield.Quality_2,
124 | ItemArmorShield.Quality_3,
125 | ItemArmorShield.Quality_4,
126 | ItemArmorShield.Quality_5,
127 | ItemArmorShield.Quality_6
128 | ][ItemSparse.OverallQualityID + 1] AS ShieldArmor
129 | FROM read_csv('ItemSparse.csv', auto_type_candidates = getvariable(types)) ItemSparse
130 | JOIN read_csv('Item.csv', auto_type_candidates = getvariable(types)) Item on Item.ID = ItemSparse.ID
131 | JOIN read_csv('ItemArmorTotal.csv', auto_type_candidates = getvariable(types)) ItemArmorTotal on ItemArmorTotal.ID = ItemSparse.ItemLevel
132 | JOIN read_csv('ArmorLocation.csv', auto_type_candidates = getvariable(types)) ArmorLocation on ArmorLocation.ID = ItemSparse.InventoryType
133 | JOIN read_csv('ItemArmorQuality.csv', auto_type_candidates = getvariable(types)) ItemArmorQuality on ItemArmorQuality.ID = ItemSparse.ItemLevel
134 | JOIN read_csv('ItemArmorShield.csv', auto_type_candidates = getvariable(types)) ItemArmorShield on ItemArmorShield.ID = ItemSparse.ItemLevel
135 | WHERE ItemSparse.InventoryType IN [${inventoryTypes}]
136 | AND (
137 | ItemSparse.QualityModifier > 0
138 | OR ${ItemStatBonusArmor} IN [
139 | ItemSparse.StatModifier_bonusStat_0,
140 | ItemSparse.StatModifier_bonusStat_1,
141 | ItemSparse.StatModifier_bonusStat_2,
142 | ItemSparse.StatModifier_bonusStat_3,
143 | ItemSparse.StatModifier_bonusStat_4,
144 | ItemSparse.StatModifier_bonusStat_5,
145 | ItemSparse.StatModifier_bonusStat_6,
146 | ItemSparse.StatModifier_bonusStat_7,
147 | ItemSparse.StatModifier_bonusStat_8,
148 | ItemSparse.StatModifier_bonusStat_9,
149 | ]
150 | )
151 | `
152 |
153 | const instance = await DuckDBInstance.create()
154 | const connection = await instance.connect()
155 | const reader = await connection.runAndReadAll(query)
156 | const items = reader.getRowObjects() as Item[]
157 |
158 | const baseArmor = {}
159 | for(const item of Object.values(items)) {
160 | const quality = ItemQuality[item.OverallQualityID]
161 | const slot = InventorySlot[InventoryTypeSlots[item.InventoryType]]
162 | const subclass = ItemArmorSubclass[item.SubclassID]
163 | const armor = item.InventoryType === InventoryType.Shield
164 | ? item.ShieldArmor
165 | : Math.round(item.SubclassArmorTotal * item.ArmorLocationModifier * item.ArmorQualityModifier)
166 |
167 | if (armor !== 0) {
168 | const slots = baseArmor[quality] ||= {}
169 | const subclasses = slots[slot] ||= {}
170 | const itemLevels = subclasses[subclass] ||= {}
171 | itemLevels[item.ItemLevel] = armor
172 | if (item.InventoryType > 10) {
173 | item.ComputedArmor = armor
174 | console.dir(item)
175 | }
176 | }
177 | }
178 |
179 | let data = "addon.baseArmorTable = {\n"
180 | const indent = "\t"
181 | const generateLua = function(obj, level) {
182 | level ||= 1
183 | for(const [key, value] of Object.entries(obj)) {
184 | if(typeof(value) === "object") {
185 | data = data.concat(indent.repeat(level), "[", key, "] = {\n")
186 | generateLua(value, level + 1)
187 | data = data.concat(indent.repeat(level), "},\n")
188 | } else {
189 | data = data.concat(indent.repeat(level), "[", key, "] = ", value, ",\n")
190 | }
191 | }
192 | }
193 | generateLua(baseArmor)
194 | data = data + "}\n"
195 |
196 | const filename = `BaseArmor.lua`
197 | writeFileSync(filename, data)
198 | console.log(`Wrote ${filename}`)
199 |
--------------------------------------------------------------------------------
/libs/StatLogic/Stats.lua:
--------------------------------------------------------------------------------
1 | local addonName = ...
2 |
3 | ---@class StatLogic
4 | local StatLogic = LibStub(addonName)
5 |
6 | ---@class Stat
7 | ---@field name string
8 | ---@field dependents? table This Stat's dependent Stats mapped to the rate at which they are inherited
9 | ---@field modifier? number The total multiplicative modifers on this stat
10 | ---@field value? number The total flat amount of this stat
11 | ---@field show boolean -- Should the stat be shown in summaries, or when broken down from a parent Stat
12 | ---@field isPercent boolean -- Whether values of the stat represent a percentage
13 | local Stat = {
14 | show = true,
15 | isPercent = false,
16 | }
17 |
18 | ---@param stat table?
19 | ---@return Stat
20 | function Stat:new(stat)
21 | stat = stat or {}
22 | stat = setmetatable(stat, self)
23 | self.__index = self
24 |
25 | return stat
26 | end
27 |
28 | function Stat:__tostring()
29 | return self.name
30 | end
31 |
32 | function Stat:AddDependent(stat, value)
33 | self.dependents = self.dependents or {}
34 | self.dependents[stat] = (self.dependents[stat] or 0) + value
35 | end
36 |
37 | function Stat:RemoveDependent(stat, value)
38 | if self.dependents and self.dependents[stat] then
39 | self.dependents[stat] = (self.dependents[stat] or 0) - value
40 | end
41 | end
42 |
43 | function Stat:ApplyModifier(value)
44 | self.modifier = (self.modifier or 1) * (1 + value)
45 | end
46 |
47 | function Stat:RemoveModifier(value)
48 | self.modifier = (self.modifier or 1) / (1 + value)
49 | end
50 |
51 | function Stat:AddValue(value)
52 | self.value = (self.value or 0) + value
53 | end
54 |
55 | function Stat:RemoveValue(value)
56 | self.value = (self.value or 0) - value
57 | end
58 |
59 | StatLogic.Stats = setmetatable({}, {
60 | __newindex = function(t, name, stat)
61 | stat.name = name
62 | rawset(t, name, stat)
63 | end
64 | })
65 |
66 | -- Basic Attributes
67 | StatLogic.Stats.Strength = Stat:new()
68 | StatLogic.Stats.Agility = Stat:new()
69 | StatLogic.Stats.Stamina = Stat:new()
70 | StatLogic.Stats.Intellect = Stat:new()
71 | StatLogic.Stats.Spirit = Stat:new()
72 | StatLogic.Stats.Mastery = Stat:new()
73 | StatLogic.Stats.MasteryEffect = Stat:new({ isPercent = true })
74 | StatLogic.Stats.MasteryRating = Stat:new()
75 |
76 | -- Resources
77 | StatLogic.Stats.Health = Stat:new()
78 | StatLogic.Stats.Mana = Stat:new()
79 | StatLogic.Stats.NormalManaRegen = Stat:new({ show = false })
80 | StatLogic.Stats.GenericManaRegen = Stat:new({ show = false })
81 | StatLogic.Stats.ManaRegen = Stat:new()
82 | StatLogic.Stats.HealthRegen = Stat:new()
83 | StatLogic.Stats.ManaRegenNotCasting = Stat:new()
84 | StatLogic.Stats.ManaRegenOutOfCombat = Stat:new()
85 | StatLogic.Stats.HealthRegenOutOfCombat = Stat:new()
86 |
87 | -- Generic Stats
88 | StatLogic.Stats.AllStats = Stat:new({ show = false })
89 | StatLogic.Stats.Hit = Stat:new({ show = false })
90 | StatLogic.Stats.HitRating = Stat:new({ show = false })
91 | StatLogic.Stats.Crit = Stat:new({ show = false })
92 | StatLogic.Stats.CritRating = Stat:new({ show = false })
93 | StatLogic.Stats.Haste = Stat:new({ show = false })
94 | StatLogic.Stats.HasteRating = Stat:new({ show = false })
95 | StatLogic.Stats.GenericAttackPower = Stat:new({ show = false })
96 | StatLogic.Stats.FeralAttackPower = Stat:new({ show = false })
97 |
98 | -- Physical Stats
99 | StatLogic.Stats.AttackPower = Stat:new()
100 | StatLogic.Stats.IgnoreArmor = Stat:new()
101 | StatLogic.Stats.ArmorPenetration = Stat:new({ isPercent = true })
102 | StatLogic.Stats.ArmorPenetrationRating = Stat:new()
103 |
104 | -- Weapon Stats
105 | StatLogic.Stats.MinWeaponDamage = Stat:new()
106 | StatLogic.Stats.MaxWeaponDamage = Stat:new()
107 | StatLogic.Stats.AverageWeaponDamage = Stat:new()
108 | StatLogic.Stats.WeaponDPS = Stat:new()
109 |
110 | -- Melee Stats
111 | StatLogic.Stats.MeleeHit = Stat:new({ isPercent = true })
112 | StatLogic.Stats.MeleeHitRating = Stat:new()
113 | StatLogic.Stats.MeleeCrit = Stat:new({ isPercent = true })
114 | StatLogic.Stats.MeleeCritRating = Stat:new()
115 | StatLogic.Stats.MeleeHaste = Stat:new({ isPercent = true })
116 | StatLogic.Stats.MeleeHasteRating = Stat:new()
117 |
118 | StatLogic.Stats.WeaponSkill = Stat:new()
119 | StatLogic.Stats.Expertise = Stat:new()
120 | StatLogic.Stats.ExpertiseRating = Stat:new()
121 | StatLogic.Stats.DodgeReduction = Stat:new({ isPercent = true })
122 | StatLogic.Stats.ParryReduction = Stat:new({ isPercent = true })
123 |
124 | -- Ranged Stats
125 | StatLogic.Stats.RangedAttackPower = Stat:new()
126 | StatLogic.Stats.RangedHit = Stat:new({ isPercent = true })
127 | StatLogic.Stats.RangedHitRating = Stat:new()
128 | StatLogic.Stats.RangedCrit = Stat:new({ isPercent = true })
129 | StatLogic.Stats.RangedCritRating = Stat:new()
130 | StatLogic.Stats.RangedHaste = Stat:new({ isPercent = true })
131 | StatLogic.Stats.RangedHasteRating = Stat:new()
132 |
133 | -- Spell Stats
134 | StatLogic.Stats.SpellPower = Stat:new()
135 | StatLogic.Stats.SpellDamage = Stat:new()
136 | StatLogic.Stats.HealingPower = Stat:new()
137 | StatLogic.Stats.SpellPenetration = Stat:new()
138 |
139 | StatLogic.Stats.HolyDamage = Stat:new()
140 | StatLogic.Stats.FireDamage = Stat:new()
141 | StatLogic.Stats.NatureDamage = Stat:new()
142 | StatLogic.Stats.FrostDamage = Stat:new()
143 | StatLogic.Stats.ShadowDamage = Stat:new()
144 | StatLogic.Stats.ArcaneDamage = Stat:new()
145 |
146 | StatLogic.Stats.SpellHit = Stat:new({ isPercent = true })
147 | StatLogic.Stats.SpellHitRating = Stat:new()
148 | StatLogic.Stats.SpellCrit = Stat:new({ isPercent = true })
149 | StatLogic.Stats.SpellCritRating = Stat:new()
150 | StatLogic.Stats.SpellHaste = Stat:new({ isPercent = true })
151 | StatLogic.Stats.SpellHasteRating = Stat:new()
152 |
153 | -- Tank Stats
154 | StatLogic.Stats.Armor = Stat:new()
155 | StatLogic.Stats.BonusArmor = Stat:new({ show = false })
156 |
157 | StatLogic.Stats.Avoidance = Stat:new({ isPercent = true })
158 | StatLogic.Stats.Dodge = Stat:new({ isPercent = true })
159 | StatLogic.Stats.DodgeBeforeDR = Stat:new({ show = false, isPercent = true })
160 | StatLogic.Stats.DodgeRating = Stat:new()
161 | StatLogic.Stats.Parry = Stat:new({ isPercent = true })
162 | StatLogic.Stats.ParryBeforeDR = Stat:new({ show = false, isPercent = true })
163 | StatLogic.Stats.ParryRating = Stat:new()
164 | StatLogic.Stats.BlockChance = Stat:new({ isPercent = true })
165 | StatLogic.Stats.BlockChanceBeforeDR = Stat:new({ show = false, isPercent = true })
166 | StatLogic.Stats.BlockRating = Stat:new()
167 | StatLogic.Stats.BlockValue = Stat:new()
168 | StatLogic.Stats.Miss = Stat:new({ isPercent = true })
169 | StatLogic.Stats.MissBeforeDR = Stat:new({ isPercent = true })
170 |
171 | StatLogic.Stats.Defense = Stat:new()
172 | StatLogic.Stats.DefenseRating = Stat:new()
173 | StatLogic.Stats.CritAvoidance = Stat:new({ isPercent = true })
174 |
175 | StatLogic.Stats.Resilience = Stat:new({ isPercent = true })
176 | StatLogic.Stats.ResilienceBeforeDR = Stat:new({ isPercent = true })
177 | StatLogic.Stats.ResilienceRating = Stat:new()
178 | StatLogic.Stats.CritDamageReduction = Stat:new({ isPercent = true })
179 | StatLogic.Stats.PvPDamageReduction = Stat:new({ isPercent = true })
180 | StatLogic.Stats.PvpPower = Stat:new({ isPercent = true })
181 | StatLogic.Stats.PvpPowerRating = Stat:new()
182 |
183 | StatLogic.Stats.HolyResistance = Stat:new()
184 | StatLogic.Stats.FireResistance = Stat:new()
185 | StatLogic.Stats.NatureResistance = Stat:new()
186 | StatLogic.Stats.FrostResistance = Stat:new()
187 | StatLogic.Stats.ShadowResistance = Stat:new()
188 | StatLogic.Stats.ArcaneResistance = Stat:new()
--------------------------------------------------------------------------------
/libs/StatLogic/libs/UTF8/utf8.lua:
--------------------------------------------------------------------------------
1 | -- $Id: utf8.lua 147 2007-01-04 00:57:00Z pasta $
2 | --
3 | -- Provides UTF-8 aware string functions implemented in pure lua:
4 | -- * string.utf8len(s)
5 | -- * string.utf8sub(s, i, j)
6 | -- * string.utf8reverse(s)
7 | --
8 | -- If utf8data.lua (containing the lower<->upper case mappings) is loaded, these
9 | -- additional functions are available:
10 | -- * string.utf8upper(s)
11 | -- * string.utf8lower(s)
12 | --
13 | -- All functions behave as their non UTF-8 aware counterparts with the exception
14 | -- that UTF-8 characters are used instead of bytes for all units.
15 |
16 | --[[
17 | Copyright (c) 2006-2007, Kyle Smith
18 | All rights reserved.
19 |
20 | Redistribution and use in source and binary forms, with or without
21 | modification, are permitted provided that the following conditions are met:
22 |
23 | * Redistributions of source code must retain the above copyright notice,
24 | this list of conditions and the following disclaimer.
25 | * Redistributions in binary form must reproduce the above copyright
26 | notice, this list of conditions and the following disclaimer in the
27 | documentation and/or other materials provided with the distribution.
28 | * Neither the name of the author nor the names of its contributors may be
29 | used to endorse or promote products derived from this software without
30 | specific prior written permission.
31 |
32 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
36 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
38 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
39 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
40 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
41 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 | --]]
43 |
44 | -- ABNF from RFC 3629
45 | --
46 | -- UTF8-octets = *( UTF8-char )
47 | -- UTF8-char = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4
48 | -- UTF8-1 = %x00-7F
49 | -- UTF8-2 = %xC2-DF UTF8-tail
50 | -- UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
51 | -- %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
52 | -- UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
53 | -- %xF4 %x80-8F 2( UTF8-tail )
54 | -- UTF8-tail = %x80-BF
55 | --
56 |
57 | -- returns the number of bytes used by the UTF-8 character at byte i in s
58 | -- also doubles as a UTF-8 character validator
59 | local function utf8charbytes (s, i)
60 | -- argument defaults
61 | i = i or 1
62 |
63 | -- argument checking
64 | if type(s) ~= "string" then
65 | error("bad argument #1 to 'utf8charbytes' (string expected, got ".. type(s).. ")")
66 | end
67 | if type(i) ~= "number" then
68 | error("bad argument #2 to 'utf8charbytes' (number expected, got ".. type(i).. ")")
69 | end
70 |
71 | local c = s:byte(i)
72 |
73 | -- determine bytes needed for character, based on RFC 3629
74 | -- validate byte 1
75 | if c > 0 and c <= 127 then
76 | -- UTF8-1
77 | return 1
78 |
79 | elseif c >= 194 and c <= 223 then
80 | -- UTF8-2
81 | local c2 = s:byte(i + 1)
82 |
83 | if not c2 then
84 | error("UTF-8 string terminated early")
85 | end
86 |
87 | -- validate byte 2
88 | if c2 < 128 or c2 > 191 then
89 | error("Invalid UTF-8 character")
90 | end
91 |
92 | return 2
93 |
94 | elseif c >= 224 and c <= 239 then
95 | -- UTF8-3
96 | local c2 = s:byte(i + 1)
97 | local c3 = s:byte(i + 2)
98 |
99 | if not c2 or not c3 then
100 | error("UTF-8 string terminated early")
101 | end
102 |
103 | -- validate byte 2
104 | if c == 224 and (c2 < 160 or c2 > 191) then
105 | error("Invalid UTF-8 character")
106 | elseif c == 237 and (c2 < 128 or c2 > 159) then
107 | error("Invalid UTF-8 character")
108 | elseif c2 < 128 or c2 > 191 then
109 | error("Invalid UTF-8 character")
110 | end
111 |
112 | -- validate byte 3
113 | if c3 < 128 or c3 > 191 then
114 | error("Invalid UTF-8 character")
115 | end
116 |
117 | return 3
118 |
119 | elseif c >= 240 and c <= 244 then
120 | -- UTF8-4
121 | local c2 = s:byte(i + 1)
122 | local c3 = s:byte(i + 2)
123 | local c4 = s:byte(i + 3)
124 |
125 | if not c2 or not c3 or not c4 then
126 | error("UTF-8 string terminated early")
127 | end
128 |
129 | -- validate byte 2
130 | if c == 240 and (c2 < 144 or c2 > 191) then
131 | error("Invalid UTF-8 character")
132 | elseif c == 244 and (c2 < 128 or c2 > 143) then
133 | error("Invalid UTF-8 character")
134 | elseif c2 < 128 or c2 > 191 then
135 | error("Invalid UTF-8 character")
136 | end
137 |
138 | -- validate byte 3
139 | if c3 < 128 or c3 > 191 then
140 | error("Invalid UTF-8 character")
141 | end
142 |
143 | -- validate byte 4
144 | if c4 < 128 or c4 > 191 then
145 | error("Invalid UTF-8 character")
146 | end
147 |
148 | return 4
149 |
150 | else
151 | error("Invalid UTF-8 character")
152 | end
153 | end
154 |
155 |
156 | -- returns the number of characters in a UTF-8 string
157 | local function utf8len (s)
158 | -- argument checking
159 | if type(s) ~= "string" then
160 | error("bad argument #1 to 'utf8len' (string expected, got ".. type(s).. ")")
161 | end
162 |
163 | local pos = 1
164 | local bytes = s:len()
165 | local len = 0
166 |
167 | while pos <= bytes do
168 | len = len + 1
169 | pos = pos + utf8charbytes(s, pos)
170 | end
171 |
172 | return len
173 | end
174 |
175 | -- install in the string library
176 | if not string.utf8len then
177 | string.utf8len = utf8len
178 | end
179 |
180 |
181 | -- functions identically to string.sub except that i and j are UTF-8 characters
182 | -- instead of bytes
183 | local function utf8sub (s, i, j)
184 | -- argument defaults
185 | j = j or -1
186 |
187 | -- argument checking
188 | if type(s) ~= "string" then
189 | error("bad argument #1 to 'utf8sub' (string expected, got ".. type(s).. ")")
190 | end
191 | if type(i) ~= "number" then
192 | error("bad argument #2 to 'utf8sub' (number expected, got ".. type(i).. ")")
193 | end
194 | if type(j) ~= "number" then
195 | error("bad argument #3 to 'utf8sub' (number expected, got ".. type(j).. ")")
196 | end
197 |
198 | local pos = 1
199 | local bytes = s:len()
200 | local len = 0
201 |
202 | -- only set l if i or j is negative
203 | local l = (i >= 0 and j >= 0) or s:utf8len()
204 | local startChar = (i >= 0) and i or l + i + 1
205 | local endChar = (j >= 0) and j or l + j + 1
206 |
207 | -- can't have start before end!
208 | if startChar > endChar then
209 | return ""
210 | end
211 |
212 | -- byte offsets to pass to string.sub
213 | local startByte, endByte = 1, bytes
214 |
215 | while pos <= bytes do
216 | len = len + 1
217 |
218 | if len == startChar then
219 | startByte = pos
220 | end
221 |
222 | pos = pos + utf8charbytes(s, pos)
223 |
224 | if len == endChar then
225 | endByte = pos - 1
226 | break
227 | end
228 | end
229 |
230 | return s:sub(startByte, endByte)
231 | end
232 |
233 | -- install in the string library
234 | if not string.utf8sub then
235 | string.utf8sub = utf8sub
236 | end
237 |
238 |
239 | -- replace UTF-8 characters based on a mapping table
240 | local function utf8replace (s, mapping)
241 | -- argument checking
242 | if type(s) ~= "string" then
243 | error("bad argument #1 to 'utf8replace' (string expected, got ".. type(s).. ")")
244 | end
245 | if type(mapping) ~= "table" then
246 | error("bad argument #2 to 'utf8replace' (table expected, got ".. type(mapping).. ")")
247 | end
248 |
249 | local pos = 1
250 | local bytes = s:len()
251 | local charbytes
252 | local newstr = ""
253 |
254 | while pos <= bytes do
255 | charbytes = utf8charbytes(s, pos)
256 | local c = s:sub(pos, pos + charbytes - 1)
257 |
258 | newstr = newstr .. (mapping[c] or c)
259 |
260 | pos = pos + charbytes
261 | end
262 |
263 | return newstr
264 | end
265 |
266 |
267 | -- identical to string.upper except it knows about unicode simple case conversions
268 | local function utf8upper (s)
269 | return utf8replace(s, utf8_lc_uc)
270 | end
271 |
272 | -- install in the string library
273 | if not string.utf8upper and utf8_lc_uc then
274 | string.utf8upper = utf8upper
275 | end
276 |
277 |
278 | -- identical to string.lower except it knows about unicode simple case conversions
279 | local function utf8lower (s)
280 | return utf8replace(s, utf8_uc_lc)
281 | end
282 |
283 | -- install in the string library
284 | if not string.utf8lower and utf8_uc_lc then
285 | string.utf8lower = utf8lower
286 | end
287 |
288 |
289 | -- identical to string.reverse except that it supports UTF-8
290 | local function utf8reverse (s)
291 | -- argument checking
292 | if type(s) ~= "string" then
293 | error("bad argument #1 to 'utf8reverse' (string expected, got ".. type(s).. ")")
294 | end
295 |
296 | local bytes = s:len()
297 | local pos = bytes
298 | local charbytes
299 | local newstr = ""
300 |
301 | while pos > 0 do
302 | local c = s:byte(pos)
303 | while c >= 128 and c <= 191 do
304 | pos = pos - 1
305 | c = s:byte(pos)
306 | end
307 |
308 | charbytes = utf8charbytes(s, pos)
309 |
310 | newstr = newstr .. s:sub(pos, pos + charbytes - 1)
311 |
312 | pos = pos - 1
313 | end
314 |
315 | return newstr
316 | end
317 |
318 | -- install in the string library
319 | if not string.utf8reverse then
320 | string.utf8reverse = utf8reverse
321 | end
322 |
--------------------------------------------------------------------------------
/.luarc.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json",
3 | "runtime.version": "Lua 5.1",
4 | "workspace.ignoreDir": [
5 | ".vscode",
6 | "libs/StatLogic/locales",
7 | "scripts"
8 | ],
9 | "diagnostics.groupSeverity": {
10 | "unused": "Warning"
11 | },
12 | "diagnostics.globals": [
13 | "SlashCmdList",
14 | "GREEN_FONT_COLOR_CODE",
15 | "HIGHLIGHT_FONT_COLOR_CODE",
16 | "RED_FONT_COLOR_CODE",
17 | "FONT_COLOR_CODE_CLOSE",
18 | "ColorPickerFrame",
19 | "EventUtil",
20 | "EMPTY_SOCKET_RED",
21 | "EMPTY_SOCKET_YELLOW",
22 | "EMPTY_SOCKET_BLUE",
23 | "EMPTY_SOCKET_META",
24 | "EMPTY_SOCKET_PRISMATIC",
25 | "ITEM_DELTA_DESCRIPTION",
26 | "ITEM_DELTA_MULTIPLE_COMPARISON_DESCRIPTION",
27 | "LARGE_NUMBER_SEPERATOR",
28 | "LE_EXPANSION_LEVEL_CURRENT",
29 | "SECONDARYHANDSLOT",
30 | "CHESTSLOT",
31 | "FEETSLOT",
32 | "HANDSSLOT",
33 | "HEADSLOT",
34 | "LEGSSLOT",
35 | "SHOULDERSLOT",
36 | "WRISTSLOT",
37 | "BACKSLOT",
38 | "WAISTSLOT",
39 | "LE_UNIT_STAT_INTELLECT",
40 | "LE_UNIT_STAT_AGILITY",
41 | "CR_PARRY",
42 | "COMBAT_RATING_RESILIENCE_PLAYER_DAMAGE_TAKEN",
43 | "CR_DEFENSE_SKILL",
44 | "WorldFrame",
45 | "ItemRefTooltip",
46 | "DECIMAL_SEPERATOR",
47 | "ChatFrame_AddMessageEventFilter",
48 | "ERR_CHAT_PLAYER_NOT_FOUND_S",
49 | "ITEM_SPELL_TRIGGER_ONEQUIP",
50 | "ITEM_SOCKET_BONUS",
51 | "BLOCK_PER_STRENGTH",
52 | "ITEM_BIND_ON_EQUIP",
53 | "ITEM_BIND_ON_PICKUP",
54 | "ITEM_BIND_ON_USE",
55 | "ITEM_BIND_QUEST",
56 | "ITEM_SOULBOUND",
57 | "ITEM_BIND_TO_ACCOUNT",
58 | "ITEM_BIND_TO_BNETACCOUNT",
59 | "ITEM_STARTS_QUEST",
60 | "ITEM_CANT_BE_DESTROYED",
61 | "ITEM_CONJURED",
62 | "ITEM_DISENCHANT_NOT_DISENCHANTABLE",
63 | "ITEM_REQ_HORDE",
64 | "ITEM_REQ_ALLIANCE",
65 | "INVTYPE_AMMO",
66 | "INVTYPE_HEAD",
67 | "INVTYPE_NECK",
68 | "INVTYPE_SHOULDER",
69 | "INVTYPE_BODY",
70 | "INVTYPE_CHEST",
71 | "INVTYPE_ROBE",
72 | "INVTYPE_WAIST",
73 | "INVTYPE_LEGS",
74 | "INVTYPE_FEET",
75 | "INVTYPE_WRIST",
76 | "INVTYPE_HAND",
77 | "INVTYPE_FINGER",
78 | "INVTYPE_TRINKET",
79 | "INVTYPE_CLOAK",
80 | "INVTYPE_WEAPON",
81 | "INVTYPE_SHIELD",
82 | "INVTYPE_2HWEAPON",
83 | "INVTYPE_WEAPONMAINHAND",
84 | "INVTYPE_WEAPONOFFHAND",
85 | "INVTYPE_HOLDABLE",
86 | "INVTYPE_RANGED",
87 | "INVTYPE_RELIC",
88 | "INVTYPE_TABARD",
89 | "INVTYPE_BAG",
90 | "ITEM_HEROIC",
91 | "ITEM_HEROIC_EPIC",
92 | "ITEM_HEROIC_QUALITY0_DESC",
93 | "ITEM_HEROIC_QUALITY1_DESC",
94 | "ITEM_HEROIC_QUALITY2_DESC",
95 | "ITEM_HEROIC_QUALITY3_DESC",
96 | "ITEM_HEROIC_QUALITY4_DESC",
97 | "ITEM_HEROIC_QUALITY5_DESC",
98 | "ITEM_HEROIC_QUALITY6_DESC",
99 | "ITEM_HEROIC_QUALITY7_DESC",
100 | "ITEM_QUALITY0_DESC",
101 | "ITEM_QUALITY1_DESC",
102 | "ITEM_QUALITY2_DESC",
103 | "ITEM_QUALITY3_DESC",
104 | "ITEM_QUALITY4_DESC",
105 | "ITEM_QUALITY5_DESC",
106 | "ITEM_QUALITY6_DESC",
107 | "ITEM_QUALITY7_DESC",
108 | "HP",
109 | "MP",
110 | "ITEM_MOD_AGILITY_SHORT",
111 | "ITEM_MOD_ARMOR_PENETRATION_RATING_SHORT",
112 | "ITEM_MOD_ATTACK_POWER_SHORT",
113 | "ITEM_MOD_BLOCK_RATING_SHORT",
114 | "ITEM_MOD_BLOCK_VALUE_SHORT",
115 | "ITEM_MOD_CRIT_MELEE_RATING_SHORT",
116 | "ITEM_MOD_CRIT_RANGED_RATING_SHORT",
117 | "ITEM_MOD_CRIT_RATING_SHORT",
118 | "ITEM_MOD_CRIT_SPELL_RATING_SHORT",
119 | "ITEM_MOD_DEFENSE_SKILL_RATING_SHORT",
120 | "ITEM_MOD_DODGE_RATING_SHORT",
121 | "ITEM_MOD_EXPERTISE_RATING_SHORT",
122 | "ITEM_MOD_EXTRA_ARMOR_SHORT",
123 | "ITEM_MOD_FERAL_ATTACK_POWER_SHORT",
124 | "ITEM_MOD_HASTE_RATING_SHORT",
125 | "ITEM_MOD_HEALTH_REGEN_SHORT",
126 | "ITEM_MOD_HEALTH_REGENERATION_SHORT",
127 | "ITEM_MOD_HEALTH_SHORT",
128 | "ITEM_MOD_HIT_MELEE_RATING_SHORT",
129 | "ITEM_MOD_HIT_RANGED_RATING_SHORT",
130 | "ITEM_MOD_HIT_RATING_SHORT",
131 | "ITEM_MOD_HIT_SPELL_RATING_SHORT",
132 | "ITEM_MOD_INTELLECT_SHORT",
133 | "ITEM_MOD_MANA_REGENERATION_SHORT",
134 | "ITEM_MOD_MANA_SHORT",
135 | "ITEM_MOD_MASTERY_RATING_SHORT",
136 | "ITEM_MOD_MELEE_ATTACK_POWER_SHORT",
137 | "ITEM_MOD_PARRY_RATING_SHORT",
138 | "ITEM_MOD_POWER_REGEN0_SHORT",
139 | "ITEM_MOD_RANGED_ATTACK_POWER_SHORT",
140 | "ITEM_MOD_RESILIENCE_RATING_SHORT",
141 | "RESILIENCE",
142 | "ITEM_MOD_SPELL_DAMAGE_DONE_SHORT",
143 | "ITEM_MOD_SPELL_HEALING_DONE_SHORT",
144 | "ITEM_MOD_SPELL_PENETRATION_SHORT",
145 | "ITEM_MOD_SPELL_POWER_SHORT",
146 | "ITEM_MOD_SPIRIT_SHORT",
147 | "ITEM_MOD_STAMINA_SHORT",
148 | "ITEM_MOD_STRENGTH_SHORT",
149 | "SPELL_STATALL",
150 | "STAT_ATTACK_POWER",
151 | "COMBAT_RATING_NAME9",
152 | "ITEM_MOD_AGILITY",
153 | "ITEM_MOD_ARMOR_PENETRATION_RATING",
154 | "ITEM_MOD_ATTACK_POWER",
155 | "ITEM_MOD_BLOCK_RATING",
156 | "ITEM_MOD_BLOCK_VALUE",
157 | "ITEM_MOD_CRIT_MELEE_RATING",
158 | "ITEM_MOD_CRIT_RANGED_RATING",
159 | "ITEM_MOD_CRIT_RATING",
160 | "ITEM_MOD_CRIT_SPELL_RATING",
161 | "ITEM_MOD_DEFENSE_SKILL_RATING",
162 | "ITEM_MOD_DODGE_RATING",
163 | "ITEM_MOD_EXPERTISE_RATING",
164 | "ITEM_MOD_EXTRA_ARMOR",
165 | "ITEM_MOD_FERAL_ATTACK_POWER",
166 | "ITEM_MOD_HASTE_RATING",
167 | "ITEM_MOD_HEALTH",
168 | "ITEM_MOD_HIT_MELEE_RATING",
169 | "ITEM_MOD_HIT_RANGED_RATING",
170 | "ITEM_MOD_HIT_RATING",
171 | "ITEM_MOD_HIT_SPELL_RATING",
172 | "ITEM_MOD_INTELLECT",
173 | "ITEM_MOD_MANA",
174 | "ITEM_MOD_MASTERY_RATING",
175 | "ITEM_MOD_PARRY_RATING",
176 | "ITEM_MOD_RANGED_ATTACK_POWER",
177 | "ITEM_MOD_RESILIENCE_RATING",
178 | "ITEM_MOD_SPELL_DAMAGE_DONE",
179 | "ITEM_MOD_SPELL_HEALING_DONE",
180 | "ITEM_MOD_SPELL_PENETRATION",
181 | "ITEM_MOD_SPELL_POWER",
182 | "ITEM_MOD_SPIRIT",
183 | "ITEM_MOD_STAMINA",
184 | "ITEM_MOD_STRENGTH",
185 | "DPS_TEMPLATE",
186 | "ARMOR_TEMPLATE",
187 | "SHIELD_BLOCK_TEMPLATE",
188 | "PLUS_DAMAGE_TEMPLATE",
189 | "DAMAGE_TEMPLATE",
190 | "AMMO_DAMAGE_TEMPLATE",
191 | "ITEM_MOD_HEALTH_REGEN",
192 | "ITEM_MOD_HEALTH_REGENERATION",
193 | "ITEM_MOD_MANA_REGENERATION",
194 | "SPEED",
195 | "ITEM_DISENCHANT_ANY_SKILL",
196 | "ITEM_DISENCHANT_MIN_SKILL",
197 | "ITEM_DURATION_DAYS",
198 | "ITEM_CREATED_BY",
199 | "ITEM_COOLDOWN_TIME_DAYS",
200 | "ITEM_UNIQUE",
201 | "ITEM_MIN_LEVEL",
202 | "ITEM_MIN_SKILL",
203 | "ITEM_CLASSES_ALLOWED",
204 | "ITEM_RACES_ALLOWED",
205 | "ITEM_SPELL_TRIGGER_ONUSE",
206 | "ITEM_SPELL_TRIGGER_ONPROC",
207 | "ITEM_SET_BONUS",
208 | "DAMAGE_TEMPLATE_WITH_SCHOOL",
209 | "PLUS_DAMAGE_TEMPLATE_WITH_SCHOOL",
210 | "ITEM_RESIST_SINGLE",
211 | "ITEM_SET_NAME",
212 | "STAT_SPELLPOWER",
213 | "COMBAT_RATING_NAME15",
214 | "SHOW",
215 | "ATTACK_POWER_TOOLTIP",
216 | "RATING",
217 | "SPELL_LASTING_EFFECT",
218 | "SPELL_STAT1_NAME",
219 | "SPELL_STAT2_NAME",
220 | "SPELL_STAT3_NAME",
221 | "SPELL_STAT4_NAME",
222 | "SPELL_STAT5_NAME",
223 | "DEFENSE",
224 | "ARMOR",
225 | "STAT_MASTERY",
226 | "HEALTH",
227 | "MANA",
228 | "STAT_HIT_CHANCE",
229 | "COMBAT_RATING_NAME6",
230 | "MELEE_CRIT_CHANCE",
231 | "STAT_HASTE",
232 | "STAT_EXPERTISE",
233 | "RANGED_ATTACK_POWER",
234 | "STAT_SPELLDAMAGE",
235 | "STAT_AVOIDANCE",
236 | "DODGE",
237 | "COMBAT_RATING_NAME3",
238 | "PARRY",
239 | "COMBAT_RATING_NAME4",
240 | "BLOCK_CHANCE",
241 | "COMBAT_RATING_NAME5",
242 | "MISS",
243 | "RESISTANCE2_NAME",
244 | "RESISTANCE3_NAME",
245 | "RESISTANCE4_NAME",
246 | "RESISTANCE5_NAME",
247 | "RESISTANCE6_NAME",
248 | "SKILL",
249 | "PLAYERSTAT_RANGED_COMBAT",
250 | "PLAYERSTAT_SPELL_COMBAT",
251 | "SPELL_SCHOOL1_CAP",
252 | "SPELL_SCHOOL2_CAP",
253 | "SPELL_SCHOOL3_CAP",
254 | "SPELL_SCHOOL4_CAP",
255 | "SPELL_SCHOOL5_CAP",
256 | "SPELL_SCHOOL6_CAP",
257 | "CRIT_ABBR",
258 | "SPELL_PENETRATION",
259 | "DAMAGE",
260 | "Add",
261 | "CR_DODGE",
262 | "ARMOR_PER_AGILITY",
263 | "ReforgingFrame",
264 | "NUM_GLYPH_SLOTS",
265 | "GetGlyphSocketInfo",
266 | "GetSpellSubtext",
267 | "GetPrimaryTalentTree",
268 | "C_Engraving",
269 | "LE_UNIT_STAT_SPIRIT",
270 | "UnitDefense",
271 | "REFORGED",
272 | "GetNumTalentTabs",
273 | "GetNumTalents",
274 | "UnitAttackBothHands",
275 | "GetActiveTalentGroup",
276 | "StatLogicTooltipTextLeft4",
277 | "RESILIENCE_CRIT_CHANCE_TO_DAMAGE_REDUCTION_MULTIPLIER",
278 | "RESILIENCE_CRIT_CHANCE_TO_CONSTANT_DAMAGE_REDUCTION_MULTIPLIER",
279 | "NATURE_RES",
280 | "SPELL_DMG",
281 | "ColorPickerFrameHeader",
282 | "C_Seasons",
283 | "ReforgingFrame_Update",
284 | "GetFunctionCPUUsage",
285 | "LinkWrangler"
286 | ]
287 | }
288 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # RatingBuster
2 |
3 | 
4 |
5 | RatingBuster converts combat ratings in your tooltips into percentages, so that you have more meaningful information when comparing different items.
6 |
7 | The design aim of RatingBuster is to provide detailed, meaningful and customizable information about items so you can easily decide for yourself which item is better.
8 |
9 | 
10 |
11 | Originally written by Whitetooth (https://github.com/hotdogee)
12 |
13 | ## Installation:
14 | Available for download at:
15 |
16 | [CurseForge](https://www.curseforge.com/wow/addons/ratingbuster-classic) | [WoWInterface](https://www.wowinterface.com/downloads/info26235-RatingBusterClassic.html#info) | [Wago Addons](https://addons.wago.io/addons/ratingbuster) | [WowUp](https://wowup.io/addons/54151) | [GitHub Releases](https://github.com/raethkcj/RatingBuster/releases/latest)
17 |
18 | ## Features
19 |
20 | Rating Conversion:
21 | * Converts combat ratings into percentages.
22 |
23 | Stat Breakdown:
24 | * Breakdown Strength, Agility, Stamina, Intellect and Spirit into base stats.
25 | * Supports talents, buffs and racials that give you extra bonuses.
26 | * Ex talent: Lunar Guidance - "Increases your spell damage and healing by 8%/16%/25% of your total Intellect."
27 | * Ex talent: Heart of the Wild - "Increases your Intellect by 4%/8%/12%/16%/20%. In addition, ......etc"
28 | * Ex: +13 Intellect (+234 Mana, +0.18% Spell Crit, +3.9 Dmg)
29 |
30 | Stat Summary:
31 | * Summarizes all the stats from the item itself, enchants and gems, converts them to base stats and displays the total value and/or difference from your current equipped item.
32 | * Ex: Crit Chance - Adds up agility and crit rating from the item, enchant and gem. Converts agility and crit rating to crit chance, and displays the total in a single value.
33 |
34 | Item Level and Item ID:
35 | * Item Level is obtained from the WoW API, not a calculated value.
36 | * Item ID is useful for advanced users.
37 |
38 | Supports talents, buffs and racials that modify your stats for all classes.
39 |
40 | Fully customizable, decide what you need to see and what you don't want.
41 |
42 |
43 | ## Auto fill gems in empty sockets
44 | 1. You can set the default gems for each type of empty socket using "/rb sum gem " or using the options window.
45 | 2. To specify the gem of your choice, you will need to give RatingBuster the ItemLink or the ItemID of the gem.
46 | 3. ItemLink example: type "/rb sum gem blue " (last char is a space) and link the gem (from your bags, AH, ItemSync or whatever), then press .
47 | 4. What if you can't link the gem? Well thats what ItemID is for. Find your gem on http://www.wowhead.com/ and look at the URL,
48 | for example "http://www.wowhead.com/?item=32193", 32193 is the ItemID for that gem.
49 | Go back in wow, type "/rb sum gem red 32193" and press .
50 |
51 | Note1: If you have "/rb sum ignore gem" on, the auto fill gems won't work.
52 | Note2: Meta gem conditions and SetBonuses work, so if you don't meet the conditions, StatSummary won't count them.
53 | Note3: RatingBuster will only auto fill empty sockets, if the item already has some gems on it, it will remain.
54 | Note4: Empty sockets filled by RatingBuster will keep the "Empty Socket Icon" so you can still easily tell what color socket it is.
55 | Note5: Gem text filled by RatingBuster will be shown in gray color to differentiate from real gems.
56 |
57 |
58 | ## Supported Addons
59 |
60 | EquipCompare, EQCompare, tekKompare.
61 | LinkWrangler, MultiTips, Links.
62 | AtlasLoot, ItemMagic, Sniff.
63 |
64 | will work with all bag mods too!
65 |
66 |
67 | ## Options
68 |
69 | Type `/rb` or `/ratingbuster` to open the options menu GUI, or add a slash command:
70 |
71 | - `help` - Show help message
72 | - `showItemID` - Show the ItemID in tooltips
73 | - `showItemLevel` - Show the ItemLevel in tooltips
74 | - `rating` - Options for Rating display
75 | - `showRatings` - Show Rating conversions in tooltips
76 | - `detailedConversionText` - Show detailed text for Resilience and Expertise conversions
77 | - `defBreakDown` - Convert Defense into Crit Avoidance, Hit Avoidance, Dodge, Parry and Block
78 | - `wpnBreakDown` - Convert Weapon Skill into Crit, Hit, Dodge Neglect, Parry Neglect and Block Neglect
79 | - `expBreakDown` - Convert Expertise into Dodge Neglect and Parry Neglect
80 | - `color` - Changes the color of added text
81 | - `pick` - Pick a color
82 | - `enableTextColor` - Enable colored text
83 | - `stat` - Changes the display of base stats
84 | - `showStats` - Show base stat conversions in tooltips
85 | - `str` - Changes the display of Strength
86 | - `showAPFromStr` - Show Attack Power from Strength
87 | - `showBlockValueFromStr` - Show Block Value from Strength
88 | - `agi` - Changes the display of Agility
89 | - `showCritFromAgi` - Show Crit chance from Agility
90 | - `showDodgeFromAgi` - Show Dodge chance from Agility
91 | - `showAPFromAgi` - Show Attack Power from Agility
92 | - `showRAPFromAgi` - Show Ranged Attack Power from Agility
93 | - `showArmorFromAgi` - Show Armor from Agility
94 | - `sta` - Changes the display of Stamina
95 | - `showHealthFromSta` - Show Health from Stamina
96 | - `int` - Changes the display of Intellect
97 | - `showSpellCritFromInt` - Show Spell Crit chance from Intellect
98 | - `showManaFromInt` - Show Mana from Intellect
99 | - `showManaRegenFromInt` - Show Mana Regen Intellect
100 | - `spi` - Changes the display of Spirit
101 | - `showManaRegenFromSpi` - Show Mana Regen from Spirit
102 | - `showHP5FromSpi` - Show Health Regen from Spirit
103 | - `sum` - Options for stat summary
104 | - `showSum` - Show stat summary in tooltips
105 | - `ignore` - Ignore stuff when calculating the stat summary
106 | - `sumIgnoreUnused` - Show stat summary only for highest level armor type and items you can use with uncommon quality and up
107 | - `sumIgnoreEquipped` - Hide stat summary for equipped items
108 | - `sumIgnoreEnchant` - Ignore enchants on items when calculating the stat summary
109 | - `sumIgnoreGems` - Ignore gems on items when calculating the stat summary
110 | - `sumDiffStyle` - Display diff values in the main tooltip or only in compare tooltips
111 | values"comp", "main"}
112 | - `space` - Add a empty line before or after stat summary
113 | - `sumBlankLine` - Add a empty line before stat summary
114 | - `sumBlankLineAfter` - Add a empty line after stat summary
115 | - `sumShowIcon` - Show the sigma icon before stat summary
116 | - `sumShowTitle` - Show the title text before stat summary
117 | - `showZeroValueStat` - Show zero value stats in summary for consistancy
118 | - `calcSum` - Calculate the total stats for the item
119 | - `calcDiff` - Calculate the stat difference for the item and equipped items
120 | - `sumSortAlpha` - Enable to sort StatSummary alphabetically, disable to sort according to stat type(basic, physical, spell, tank)
121 | - `sumAvoidWithBlock` - Enable to include block chance in Avoidance summary, Disable for only dodge, parry, miss
122 | - `basic` - Choose basic stats for summary
123 | - `sumHP` - Health <- Health, Stamina
124 | - `sumMP` - Mana <- Mana, Intellect
125 | - `sumManaRegen` - Mana Regen
126 | - `sumManaRegenNotCasting` - Mana Regen while not casting
127 | - `sumManaRegenOutOfCombat` - Mana Regen while out of combat
128 | - `sumHP5` - Health Regen <- Health Regen
129 | - `sumHP5OC` - Health Regen when out of combat <- Spirit
130 | - `sumStr` - Strength Summary
131 | - `sumAgi` - Agility Summary
132 | - `sumSta` - Stamina Summary
133 | - `sumInt` - Intellect Summary
134 | - `sumSpi` - Spirit Summary
135 | - `physical` - Choose physical damage stats for summary
136 | - `sumAP` - Attack Power <- Attack Power, Strength, Agility
137 | - `sumRAP` - Ranged Attack Power <- Ranged Attack Power, Intellect, Attack Power, Strength, Agility
138 | - `sumFAP` - Feral Attack Power <- Feral Attack Power, Attack Power, Strength, Agility
139 | - `sumHit` - Hit Chance <- Hit Rating, Weapon Skill Rating
140 | - `sumHitRating` - Hit Rating Summary
141 | - `sumCrit` - Crit Chance <- Crit Rating, Agility, Weapon Skill Rating
142 | - `sumCritRating` - Crit Rating Summary
143 | - `sumHaste` - Haste <- Haste Rating
144 | - `sumHasteRating` - Haste Rating Summary
145 | - `sumDodgeNeglect` - Dodge Neglect <- Expertise, Weapon Skill Rating
146 | - `sumParryNeglect` - Parry Neglect <- Expertise, Weapon Skill Rating
147 | - `sumBlockNeglect` - Block Neglect <- Weapon Skill Rating
148 | - `sumWeaponSkill` - Weapon Skill <- Weapon Skill Rating
149 | - `sumExpertise` - Expertise <- Expertise Rating
150 | - `sumWeaponMaxDamage` - Weapon Max Damage Summary
151 | - `weapondps` - Weapon DPS Summary
152 | - `sumIgnoreArmor` - Ignore Armor Summary
153 | - `spell` - Choose spell damage and healing stats for summary
154 | - `sumSpellDmg` - Spell Damage <- Spell Damage, Intellect, Spirit, Stamina
155 | - `sumHolyDmg` - Holy Spell Damage <- Holy Spell Damage, Spell Damage, Intellect, Spirit
156 | - `sumArcaneDmg` - Arcane Spell Damage <- Arcane Spell Damage, Spell Damage, Intellect
157 | - `sumFireDmg` - Fire Spell Damage <- Fire Spell Damage, Spell Damage, Intellect, Stamina
158 | - `sumNatureDmg` - Nature Spell Damage <- Nature Spell Damage, Spell Damage, Intellect
159 | - `sumFrostDmg` - Frost Spell Damage <- Frost Spell Damage, Spell Damage, Intellect
160 | - `sumShadowDmg` - Shadow Spell Damage <- Shadow Spell Damage, Spell Damage, Intellect, Spirit, Stamina
161 | - `sumHealing` - Healing <- Healing, Intellect, Spirit, Agility, Strength
162 | - `sumSpellHit` - Spell Hit Chance <- Spell Hit Rating
163 | - `sumSpellHitRating` - Spell Hit Rating Summary
164 | - `sumSpellCrit` - Spell Crit Chance <- Spell Crit Rating, Intellect
165 | - `sumSpellCritRating` - Spell Crit Rating Summary
166 | - `sumSpellHaste` - Spell Haste <- Spell Haste Rating
167 | - `sumSpellHasteRating` - Spell Haste Rating Summary
168 | - `sumPenetration` - Spell Penetration Summary
169 | - `tank` - Choose tank stats for summary
170 | - `sumArmor` - Armor <- Armor from items, Armor from bonuses, Agility, Intellect
171 | - `sumDefense` - Defense <- Defense Rating
172 | - `sumDodge` - Dodge Chance <- Dodge Rating, Agility, Defense Rating
173 | - `sumDodgeRating` - Dodge Rating Summary
174 | - `sumParry` - Parry Chance <- Parry Rating, Defense Rating
175 | - `sumParryRating` - Parry Rating Summary
176 | - `sumBlock` - Block Chance <- Block Rating, Defense Rating
177 | - `sumBlockRating` - Block Rating Summary
178 | - `sumBlockValue` - Block Value <- Block Value, Strength
179 | - `sumHitAvoid` - Hit Avoidance <- Defense Rating
180 | - `sumCritAvoid` - Crit Avoidance <- Defense Rating, Resilience
181 | - `sumResilience` - Resilience Summary
182 | - `sumArcaneResist` - Arcane Resistance Summary
183 | - `sumFireResist` - Fire Resistance Summary
184 | - `sumNatureResist` - Nature Resistance Summary
185 | - `sumFrostResist` - Frost Resistance Summary
186 | - `sumShadowResist` - Shadow Resistance Summary
187 | - `sumAvoidance` - Avoidance <- Dodge, Parry, MobMiss, Block(Optional)
188 | - `gem` - Auto fill empty gem slots
189 | - `sumGemRed` - ItemID or Link of the gem you would like to auto fill
190 | - `sumGemYellow` - ItemID or Link of the gem you would like to auto fill
191 | - `sumGemBlue` - ItemID or Link of the gem you would like to auto fill
192 | - `sumGemMeta` - ItemID or Link of the gem you would like to auto fill
193 |
--------------------------------------------------------------------------------
/scripts/GenerateBaseArmor/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* Visit https://aka.ms/tsconfig to read more about this file */
4 |
5 | /* Projects */
6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
12 |
13 | /* Language and Environment */
14 | "target": "ES2024", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
15 | "lib": ["ESNext"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
16 | // "jsx": "preserve", /* Specify what JSX code is generated. */
17 | // "libReplacement": true, /* Enable lib replacement. */
18 | // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
19 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
20 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
21 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
22 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
23 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
24 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
25 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
26 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
27 |
28 | /* Modules */
29 | "module": "NodeNext", /* Specify what module code is generated. */
30 | // "rootDir": "./", /* Specify the root folder within your source files. */
31 | "moduleResolution": "nodenext", /* Specify how TypeScript looks up a file from a given module specifier. */
32 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
33 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
34 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
35 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
36 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */
37 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
38 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
39 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
40 | // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */
41 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
42 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
43 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
44 | // "noUncheckedSideEffectImports": true, /* Check side effect imports. */
45 | "resolveJsonModule": true, /* Enable importing .json files. */
46 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
47 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */
48 |
49 | /* JavaScript Support */
50 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
51 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
52 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
53 |
54 | /* Emit */
55 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
56 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */
57 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
58 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
59 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
60 | // "noEmit": true, /* Disable emitting files from a compilation. */
61 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
62 | // "outDir": "./", /* Specify an output folder for all emitted files. */
63 | // "removeComments": true, /* Disable emitting comments. */
64 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
65 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
66 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
67 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
68 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
69 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
70 | // "newLine": "crlf", /* Set the newline character for emitting files. */
71 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
72 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
73 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
74 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
75 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
76 |
77 | /* Interop Constraints */
78 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
79 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
80 | // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
81 | // "erasableSyntaxOnly": true, /* Do not allow runtime constructs that are not part of ECMAScript. */
82 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
83 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
84 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
85 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
86 |
87 | /* Type Checking */
88 | "strict": true, /* Enable all strict type-checking options. */
89 | "noImplicitAny": false, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
90 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
91 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
92 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
93 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
94 | // "strictBuiltinIteratorReturn": true, /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */
95 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
96 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
97 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
98 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
99 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
100 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
101 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
102 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
103 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
104 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
105 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
106 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
107 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
108 |
109 | /* Completeness */
110 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
111 | "skipLibCheck": true /* Skip type checking all .d.ts files. */
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/scripts/GenerateStatLocales/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* Visit https://aka.ms/tsconfig to read more about this file */
4 |
5 | /* Projects */
6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
12 |
13 | /* Language and Environment */
14 | "target": "ES2024", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
15 | "lib": ["ESNext"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
16 | // "jsx": "preserve", /* Specify what JSX code is generated. */
17 | // "libReplacement": true, /* Enable lib replacement. */
18 | // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
19 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
20 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
21 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
22 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
23 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
24 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
25 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
26 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
27 |
28 | /* Modules */
29 | "module": "NodeNext", /* Specify what module code is generated. */
30 | // "rootDir": "./", /* Specify the root folder within your source files. */
31 | "moduleResolution": "nodenext", /* Specify how TypeScript looks up a file from a given module specifier. */
32 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
33 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
34 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
35 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
36 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */
37 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
38 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
39 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
40 | // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */
41 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
42 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
43 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
44 | // "noUncheckedSideEffectImports": true, /* Check side effect imports. */
45 | "resolveJsonModule": true, /* Enable importing .json files. */
46 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
47 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */
48 |
49 | /* JavaScript Support */
50 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
51 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
52 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
53 |
54 | /* Emit */
55 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
56 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */
57 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
58 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
59 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
60 | // "noEmit": true, /* Disable emitting files from a compilation. */
61 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
62 | // "outDir": "./", /* Specify an output folder for all emitted files. */
63 | // "removeComments": true, /* Disable emitting comments. */
64 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
65 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
66 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
67 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
68 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
69 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
70 | // "newLine": "crlf", /* Set the newline character for emitting files. */
71 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
72 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
73 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
74 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
75 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
76 |
77 | /* Interop Constraints */
78 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
79 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
80 | // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
81 | // "erasableSyntaxOnly": true, /* Do not allow runtime constructs that are not part of ECMAScript. */
82 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
83 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
84 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
85 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
86 |
87 | /* Type Checking */
88 | "strict": true, /* Enable all strict type-checking options. */
89 | "noImplicitAny": false, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
90 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
91 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
92 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
93 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
94 | // "strictBuiltinIteratorReturn": true, /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */
95 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
96 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
97 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
98 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
99 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
100 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
101 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
102 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
103 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
104 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
105 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
106 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
107 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
108 |
109 | /* Completeness */
110 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
111 | "skipLibCheck": true /* Skip type checking all .d.ts files. */
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/libs/StatLogic/DiminishingReturns.lua:
--------------------------------------------------------------------------------
1 | local addonName, addon = ...
2 | ---@class StatLogic
3 | local StatLogic = LibStub:GetLibrary(addonName)
4 |
5 | -----------------------------------
6 | -- Avoidance diminishing returns --
7 | -----------------------------------
8 | -- Formula reverse engineered by Whitetooth (hotdogee [at] gmail [dot] com)
9 | --[[-------------------------------
10 | This includes
11 | 1. Dodge from Dodge Rating, Defense, Agility.
12 | 2. Parry from Parry Rating, Defense.
13 | 3. Chance to be missed from Defense.
14 |
15 | The following is the result of hours of work gathering data from beta servers and then spending even more time running multiple regression analysis on the data.
16 |
17 | 1. DR for Dodge, Parry, Miss are calculated separately.
18 | 2. Base avoidances are not affected by DR, (ex: Dodge from base Agility)
19 | 3. Death Knight's Parry from base Strength is affected by DR, base for parry is 5%.
20 | 4. Direct avoidance gains from talents and spells(ex: Evasion) are not affected by DR.
21 | 5. Indirect avoidance gains from talents and spells(ex: +Agility from Kings) are affected by DR
22 | 6. c and k values depend on class but does not change with level.
23 |
24 | 7. The DR formula:
25 |
26 | 1/x' = 1/c+k/x
27 |
28 | x' is the diminished stat before converting to IEEE754.
29 | x is the stat before diminishing returns.
30 | c is the cap of the stat, and changes with class.
31 | k is is a value that changes with class.
32 | -----------------------------------]]
33 |
34 | function StatLogic:GetMissChanceBeforeDR()
35 | local baseDefense, additionalDefense = UnitDefense("player")
36 | local defenseFromDefenseRating = floor(GetCombatRatingBonus(CR_DEFENSE_SKILL))
37 | local modMiss = defenseFromDefenseRating * 0.04
38 | local drFreeMiss = 5 + (baseDefense + additionalDefense - defenseFromDefenseRating) * 0.04
39 | return modMiss, drFreeMiss
40 | end
41 |
42 | --[[
43 | Formula by Whitetooth (hotdogee [at] gmail [dot] com)
44 | Calculates the dodge percentage per agility for your current class and level.
45 | Only works for your currect class and current level, does not support class and level args.
46 | Calculations got a bit more complicated with the introduction of the avoidance DR in WotLK, these are the values we know or can be calculated easily:
47 | D'=Total Dodge% after DR
48 | D_r=Dodge from Defense and Dodge Rating before DR
49 | D_b=Dodge unaffected by DR (BaseDodge + Dodge from talent/buffs + penalty from uncapped Defense skill)
50 | A=Total Agility
51 | A_b=Base Agility (This is what you have with no gear on)
52 | A_g=Total Agility - Base Agility
53 | Let d be the Dodge/Agi value we are going to calculate.
54 |
55 | 1 1 k
56 | --- = --- + ---
57 | x' c x
58 |
59 | x'=D'-D_b-A_b*d
60 | x=A_g*d+D_r
61 |
62 | 1/(D'-D_b-A_b*d)=1/C_d+k/(A_g*d+D_r)=(A_g*d+D_r+C_d*k)/(C_d*A_g*d+C_d*D_r)
63 |
64 | C_d*A_g*d+C_d*D_r=[(D'-D_b)-A_b*d]*[Ag*d+(D_r+C_d*k)]
65 |
66 | After rearranging the terms, we get an equation of type a*d^2+b*d+c where
67 | a=-A_g*A_b
68 | b=A_g(D'-D_b)-A_b(D_r+C_d*k)-C_dA_g
69 | c=(D'-D_b)(D_r+C_d*k)-C_d*D_r
70 | Dodge/Agi=(-b-(b^2-4ac)^0.5)/(2a)
71 | ]]
72 | ---@return number dodge Dodge percentage per agility
73 | function StatLogic:GetDodgePerAgi()
74 | -- Collect data
75 | local D_dr = GetDodgeChance()
76 | if D_dr == 0 then
77 | return 0
78 | end
79 | local dodgeFromDodgeRating = GetCombatRatingBonus(CR_DODGE)
80 | local D_r = dodgeFromDodgeRating
81 | local D_b = self:GetStatMod("ADD_DODGE")
82 | if addon.tocversion < 40000 then
83 | local baseDefense, modDefense = UnitDefense("player")
84 | local dodgeFromModDefense = modDefense * 0.04
85 | D_r = D_r + dodgeFromModDefense
86 | D_b = D_b + (baseDefense - UnitLevel("player") * 5) * 0.04
87 | end
88 | local stat, effectiveStat, posBuff, negBuff = UnitStat("player", LE_UNIT_STAT_AGILITY)
89 | local modAgi = 1
90 | if addon.ModAgiClasses and addon.ModAgiClasses[addon.class] then
91 | modAgi = self:GetStatMod("MOD_AGI")
92 | -- Talents that modify Agi will not add to posBuff, so we need to calculate baseAgi
93 | -- But Agi from Kings etc. will add to posBuff, so we subtract those if present
94 | for _, case in ipairs(StatLogic.StatModTable["ALL"]["MOD_AGI"]) do
95 | if case.group == addon.ExclusiveGroup.AllStats then
96 | if StatLogic:GetAuraInfo(case.aura, true) then
97 | modAgi = modAgi - case.value
98 | end
99 | end
100 | end
101 | end
102 | local A = effectiveStat
103 | local A_b = ceil((stat - posBuff - negBuff) / modAgi)
104 | local A_g = A - A_b
105 | local C = addon.C_d[addon.class]
106 | local k = addon.K[addon.class]
107 | -- Solve a*x^2+b*x+c
108 | local a = -A_g*A_b
109 | local b = A_g*(D_dr-D_b)-A_b*(D_r+C*k)-C*A_g
110 | local c = (D_dr-D_b)*(D_r+C*k)-C*D_r
111 |
112 | local dodgePerAgi
113 | if a == 0 then
114 | dodgePerAgi = -c / b
115 | else
116 | dodgePerAgi = (-b-(b^2-4*a*c)^0.5)/(2*a)
117 | end
118 |
119 | return dodgePerAgi
120 | end
121 |
122 | --[[
123 | Calculates your current Dodge% before diminishing returns.
124 | Dodge% = diminishableDodge + drFreeDodge
125 |
126 | drFreeDodge includes:
127 | * Base dodge
128 | * Dodge from base agility
129 | * Dodge modifier from base defense
130 | * Dodge modifers from talents or spells
131 |
132 | diminishableDodge includes
133 | * Dodge from dodge rating
134 | * Dodge from additional defense
135 | * Dodge from non-base agility
136 | ]]
137 | ---@return number diminishableDodge The part that is affected by diminishing returns.
138 | ---@return number drFreeDodge The part that isn't affected by diminishing returns.
139 | function StatLogic:GetDodgeChanceBeforeDR()
140 | local agility, _, posBuff, negBuff = UnitStat("player", LE_UNIT_STAT_AGILITY)
141 | local baseAgi = agility - posBuff - negBuff
142 |
143 | local diminishableDodge = GetCombatRatingBonus(CR_DODGE)
144 | + floor(GetCombatRatingBonus(CR_DEFENSE_SKILL) or 0) * 0.04
145 | + (agility - baseAgi) * self:GetStatMod("ADD_DODGE_MOD_AGI")
146 |
147 | local drFreeDodge = GetDodgeChance() - self:GetAvoidanceAfterDR(StatLogic.Stats.Dodge, diminishableDodge)
148 |
149 | return diminishableDodge, drFreeDodge
150 | end
151 |
152 | ---@return number parry Parry percentage per strength
153 | function StatLogic:GetParryPerStr()
154 | -- Collect data
155 | local P_dr = GetParryChance()
156 | if P_dr == 0 then
157 | return 0
158 | end
159 | local parryFromParryRating = GetCombatRatingBonus(CR_PARRY)
160 | local P_r = parryFromParryRating
161 | local P_b = self:GetStatMod("ADD_PARRY")
162 | local stat, effectiveStat, posBuff, negBuff = UnitStat("player", LE_UNIT_STAT_STRENGTH)
163 | local modStr = 1
164 | -- if addon.ModStrClasses[addon.class] then
165 | -- modStr = self:GetStatMod("MOD_STR")
166 | -- -- Talents that modify Str will not add to posBuff, so we need to calculate baseStr
167 | -- -- But Str from Kings etc. will add to posBuff, so we subtract those if present
168 | -- for _, case in ipairs(StatLogic.StatModTable["ALL"]["MOD_STR"]) do
169 | -- if case.group == addon.ExclusiveGroup.AllStats then
170 | -- if StatLogic:GetAuraInfo(case.aura, true) then
171 | -- modStr = modStr - case.value
172 | -- end
173 | -- end
174 | -- end
175 | -- end
176 | local A = effectiveStat
177 | local A_b = ceil((stat - posBuff - negBuff) / modStr)
178 | local A_g = A - A_b
179 | local C = addon.C_p[addon.class]
180 | local k = addon.K[addon.class]
181 | -- Solve a*x^2+b*x+c
182 | local a = -A_g*A_b
183 | local b = A_g*(P_dr-P_b)-A_b*(P_r+C*k)-C*A_g
184 | local c = (P_dr-P_b)*(P_r+C*k)-C*P_r
185 |
186 | local parryPerStr
187 | if a == 0 then
188 | parryPerStr = -c / b
189 | else
190 | parryPerStr = (-b-(b^2-4*a*c)^0.5)/(2*a)
191 | end
192 |
193 | return parryPerStr
194 | end
195 |
196 | --[[
197 | Calculates your current Parry% before diminishing returns.
198 | Parry% = diminishableParry + drFreeParry
199 |
200 | drFreeParry includes:
201 | * Base parry
202 | * Parry from base strength
203 | * Parry modifier from base defense
204 | * Parry modifers from talents or spells
205 |
206 | diminishableParry includes
207 | * Parry from parry rating
208 | * Parry from additional defense
209 | * Parry from non-base strength
210 | ]]
211 | ---@return number diminishableParry The part that is affected by diminishing returns.
212 | ---@return number drFreeParry The part that isn't affected by diminishing returns.
213 | function StatLogic:GetParryChanceBeforeDR()
214 | local strength, _, posBuff, negBuff = UnitStat("player", LE_UNIT_STAT_STRENGTH)
215 | local baseStr = strength - posBuff - negBuff
216 |
217 | local diminishableParry = GetCombatRatingBonus(CR_PARRY)
218 | + floor(GetCombatRatingBonus(CR_DEFENSE_SKILL) or 0) * 0.04
219 | + (strength - baseStr) * self:GetStatMod("ADD_PARRY_MOD_STR")
220 |
221 | local drFreeParry = GetParryChance() - self:GetAvoidanceAfterDR(StatLogic.Stats.Parry, diminishableParry)
222 |
223 | return diminishableParry, drFreeParry
224 | end
225 |
226 | ---@return number diminishableBlockChance The part that is affected by diminishing returns.
227 | ---@return number drFreeBlockChance The part that isn't affected by diminishing returns.
228 | function StatLogic:GetBlockChanceBeforeDR()
229 | local diminishableBlockChance = GetMastery() * self:GetStatMod("ADD_BLOCK_CHANCE_MOD_MASTERY_EFFECT")
230 | + floor(GetCombatRatingBonus(CR_DEFENSE_SKILL) or 0) * 0.04
231 |
232 | local drFreeBlockChance = GetBlockChance() - self:GetAvoidanceAfterDR(StatLogic.Stats.BlockChance, diminishableBlockChance)
233 |
234 | return diminishableBlockChance, drFreeBlockChance
235 | end
236 |
237 | --[[
238 | Avoidance DR formula and k, C_p, C_d constants derived by Whitetooth (hotdogee [at] gmail [dot] com)
239 | avoidanceBeforeDR is the part that is affected by diminishing returns.
240 | See :GetClassIdOrName(class) for valid class values.
241 |
242 | Calculates the avoidance after diminishing returns, this includes:
243 | * Dodge from Dodge Rating, Defense, Agility.
244 | * Parry from Parry Rating, Defense.
245 | * Chance to be missed from Defense.
246 |
247 | The DR formula: 1/x' = 1/c+k/x
248 | * x' is the diminished stat before converting to IEEE754.
249 | * x is the stat before diminishing returns.
250 | * c is the cap of the stat, and changes with class.
251 | * k is is a value that changes with class.
252 |
253 | Formula details:
254 | * DR for Dodge, Parry, Miss are calculated separately.
255 | * Base avoidances are not affected by DR, (ex: Dodge from base Agility)
256 | * Death Knight's Parry from base Strength is affected by DR, base for parry is 5%.
257 | * Direct avoidance gains from talents and spells(ex: Evasion) are not affected by DR.
258 | * Indirect avoidance gains from talents and spells(ex: +Agility from Kings) are affected by DR
259 | * c and k values depend on class but does not change with level.
260 | ]]
261 | ---@param stat `StatLogic.Stats.Dodge`|`StatLogic.Stats.Parry`|`StatLogic.Stats.Miss|`StatLogic.Stats.BlockChance`
262 | ---@param avoidanceBeforeDR number Amount of avoidance before diminishing returns in percentages.
263 | ---@return number avoidanceAfterDR Avoidance after diminishing returns in percentages.
264 | function StatLogic:GetAvoidanceAfterDR(stat, avoidanceBeforeDR)
265 | local C = addon.C_d
266 | if stat == StatLogic.Stats.Parry then
267 | C = addon.C_p
268 | elseif stat == StatLogic.Stats.Miss then
269 | C = addon.C_m
270 | elseif stat == StatLogic.Stats.BlockChance then
271 | C = addon.C_b
272 | -- See https://sacreddutydotnet.wordpress.com/2012/09/14/avoidance-diminishing-returns-in-mop-followup-2/
273 | avoidanceBeforeDR = math.floor(128 * avoidanceBeforeDR + 0.5) / 128
274 | end
275 |
276 | local cap = C and C[addon.class] or 0
277 | if cap > 0 and avoidanceBeforeDR > 0 then
278 | return 1 / (1 / cap + addon.K[addon.class] / avoidanceBeforeDR)
279 | elseif avoidanceBeforeDR > 0 then
280 | return avoidanceBeforeDR
281 | else
282 | return 0
283 | end
284 | end
285 |
286 | -- Calculates the avoidance gain after diminishing returns with player's current stats.
287 | ---@param stat `StatLogic.Stats.Dodge`|`StatLogic.Stats.Parry`|`StatLogic.Stats.Miss`|`StatLogic.Stats.BlockChance`
288 | ---@param gainBeforeDR number Avoidance gain before diminishing returns in percentages.
289 | ---@return number gainAfterDR Avoidance gain after diminishing returns in percentages.
290 | function StatLogic:GetAvoidanceGainAfterDR(stat, gainBeforeDR)
291 | if stat == StatLogic.Stats.Parry then
292 | local modAvoidance, drFreeAvoidance = self:GetParryChanceBeforeDR()
293 | local newAvoidanceChance = self:GetAvoidanceAfterDR(stat, modAvoidance + gainBeforeDR) + drFreeAvoidance
294 | if newAvoidanceChance < 0 then newAvoidanceChance = 0 end
295 | return newAvoidanceChance - GetParryChance()
296 | elseif stat == StatLogic.Stats.Dodge then
297 | local modAvoidance, drFreeAvoidance = self:GetDodgeChanceBeforeDR()
298 | local newAvoidanceChance = self:GetAvoidanceAfterDR(stat, modAvoidance + gainBeforeDR) + drFreeAvoidance
299 | if newAvoidanceChance < 0 then newAvoidanceChance = 0 end -- because GetDodgeChance() is 0 when negative
300 | return newAvoidanceChance - GetDodgeChance()
301 | elseif stat == StatLogic.Stats.Miss then
302 | local modAvoidance = self:GetMissChanceBeforeDR()
303 | return self:GetAvoidanceAfterDR(stat, modAvoidance + gainBeforeDR) - self:GetAvoidanceAfterDR(stat, modAvoidance)
304 | elseif stat == StatLogic.Stats.BlockChance then
305 | local modAvoidance, drFreeAvoidance = self:GetBlockChanceBeforeDR()
306 | local newAvoidanceChance = self:GetAvoidanceAfterDR(stat, modAvoidance + gainBeforeDR) + drFreeAvoidance
307 | if newAvoidanceChance < 0 then newAvoidanceChance = 0 end
308 | return newAvoidanceChance - GetBlockChance()
309 | else
310 | return gainBeforeDR
311 | end
312 | end
313 |
314 | function StatLogic:GetResilienceEffectGainAfterDR(gainBeforeDR)
315 | local currentResilienceBeforeDR = self:GetEffectFromRating(GetCombatRating(COMBAT_RATING_RESILIENCE_PLAYER_DAMAGE_TAKEN), StatLogic.Stats.ResilienceRating)
316 | local currentResilienceAfterDR = GetCombatRatingBonus(COMBAT_RATING_RESILIENCE_PLAYER_DAMAGE_TAKEN)
317 | return self:GetResilienceEffectAfterDR(currentResilienceBeforeDR + gainBeforeDR) - currentResilienceAfterDR
318 | end
--------------------------------------------------------------------------------
/libs/StatLogic/locales/GlobalPatterns.lua:
--------------------------------------------------------------------------------
1 | local addonName, addon = ...
2 | local StatLogic = LibStub(addonName)
3 | local locale = GetLocale()
4 |
5 | -- Metatable that forces keys to be UTF8-lowercase
6 | local lowerMT = {
7 | __newindex = function(t, k, v)
8 | if k then
9 | rawset(t, k:utf8lower(), v)
10 | end
11 | end
12 | }
13 |
14 | -----------------------
15 | -- Whole Text Lookup --
16 | -----------------------
17 | -- Strings without numbers; mainly used for enchants or easy exclusions
18 | ---@alias WholeTextEntry { [Stat]: number } | false
19 | ---@type { [string]: WholeTextEntry }
20 | addon.WholeTextLookup = setmetatable({}, lowerMT)
21 | local W = addon.WholeTextLookup
22 |
23 | local exclusions = {
24 | "",
25 | " \n",
26 | EMPTY_SOCKET_RED,
27 | EMPTY_SOCKET_YELLOW,
28 | EMPTY_SOCKET_BLUE,
29 | EMPTY_SOCKET_META,
30 | EMPTY_SOCKET_PRISMATIC,
31 | ITEM_BIND_ON_EQUIP,
32 | ITEM_BIND_ON_PICKUP,
33 | ITEM_BIND_ON_USE,
34 | ITEM_BIND_QUEST,
35 | ITEM_SOULBOUND,
36 | ITEM_BIND_TO_ACCOUNT,
37 | ITEM_BIND_TO_BNETACCOUNT,
38 | ITEM_STARTS_QUEST,
39 | ITEM_CANT_BE_DESTROYED,
40 | ITEM_CONJURED,
41 | ITEM_DISENCHANT_NOT_DISENCHANTABLE,
42 | ITEM_REQ_HORDE,
43 | ITEM_REQ_ALLIANCE,
44 | C_Item.GetItemClassInfo(Enum.ItemClass.Projectile),
45 | INVTYPE_AMMO,
46 | INVTYPE_HEAD,
47 | INVTYPE_NECK,
48 | INVTYPE_SHOULDER,
49 | INVTYPE_BODY,
50 | INVTYPE_CHEST,
51 | INVTYPE_ROBE,
52 | INVTYPE_WAIST,
53 | INVTYPE_LEGS,
54 | INVTYPE_FEET,
55 | INVTYPE_WRIST,
56 | INVTYPE_HAND,
57 | INVTYPE_FINGER,
58 | INVTYPE_TRINKET,
59 | INVTYPE_CLOAK,
60 | INVTYPE_WEAPON,
61 | INVTYPE_SHIELD,
62 | INVTYPE_2HWEAPON,
63 | INVTYPE_WEAPONMAINHAND,
64 | INVTYPE_WEAPONOFFHAND,
65 | INVTYPE_HOLDABLE,
66 | INVTYPE_RANGED,
67 | INVTYPE_RELIC,
68 | INVTYPE_TABARD,
69 | INVTYPE_BAG,
70 | REFORGED,
71 | ITEM_HEROIC,
72 | ITEM_HEROIC_EPIC,
73 | ITEM_HEROIC_QUALITY0_DESC,
74 | ITEM_HEROIC_QUALITY1_DESC,
75 | ITEM_HEROIC_QUALITY2_DESC,
76 | ITEM_HEROIC_QUALITY3_DESC,
77 | ITEM_HEROIC_QUALITY4_DESC,
78 | ITEM_HEROIC_QUALITY5_DESC,
79 | ITEM_HEROIC_QUALITY6_DESC,
80 | ITEM_HEROIC_QUALITY7_DESC,
81 | ITEM_QUALITY0_DESC,
82 | ITEM_QUALITY1_DESC,
83 | ITEM_QUALITY2_DESC,
84 | ITEM_QUALITY3_DESC,
85 | ITEM_QUALITY4_DESC,
86 | ITEM_QUALITY5_DESC,
87 | ITEM_QUALITY6_DESC,
88 | ITEM_QUALITY7_DESC,
89 | C_Item.GetItemSubClassInfo(Enum.ItemClass.Weapon, Enum.ItemWeaponSubclass.Thrown),
90 | C_Item.GetItemSubClassInfo(Enum.ItemClass.Miscellaneous, Enum.ItemMiscellaneousSubclass.Mount)
91 | }
92 |
93 | for _, exclusion in pairs(exclusions) do
94 | W[exclusion] = false
95 | end
96 |
97 | for _, subclass in pairs(Enum.ItemArmorSubclass) do
98 | local subclassName = C_Item.GetItemSubClassInfo(Enum.ItemClass.Armor, subclass)
99 | if subclassName then
100 | W[subclassName] = false
101 | end
102 | end
103 |
104 | local function unescape(pattern)
105 | return (pattern:gsub("%%%d?%$?c", ""):gsub("%%%d?%$?[sd]", "%%s"):gsub("%.$", ""))
106 | end
107 |
108 | local function setPrefixPatterns(input, output)
109 | for _, pattern in ipairs(input) do
110 | output["^" .. pattern .. " *"] = true
111 | end
112 | end
113 |
114 | ---@type table
115 | addon.TrimmedPrefixes = {}
116 |
117 | local trimmedPrefixes = {
118 | ITEM_SPELL_TRIGGER_ONEQUIP,
119 | ITEM_SOCKET_BONUS:format("")
120 | }
121 |
122 | setPrefixPatterns(trimmedPrefixes, addon.TrimmedPrefixes)
123 |
124 | -- Patterns that should be matched for breakdowns, but ignord for summaries
125 | ---@type table
126 | addon.IgnoreSum = setmetatable({}, lowerMT)
127 |
128 | local ignoreSumPrefixes = {
129 | ITEM_SPELL_TRIGGER_ONUSE, -- "Use:"
130 | ITEM_SPELL_TRIGGER_ONPROC, -- "Chance on hit:"
131 | ITEM_SET_BONUS_GRAY:gsub("[()]", "%%%1"):gsub("%%d", "%%d+"):gsub("%%s", ""), -- "(%d) Set: %s"
132 | ITEM_SET_BONUS:format(""), -- "Set: %s"
133 | }
134 |
135 | setPrefixPatterns(ignoreSumPrefixes, addon.IgnoreSum)
136 |
137 | addon.OnUseCooldown = ITEM_COOLDOWN_TOTAL:utf8lower():format("[^(]+"):gsub("[()]", "%%%1") .. "$"
138 |
139 | addon.ReforgeSuffix = "%s*" .. REFORGE_TOOLTIP_LINE:format(0, "", "", ".*"):utf8lower():trim():gsub("[()]", "%%%1")
140 |
141 | -------------------------
142 | -- Substitution Lookup --
143 | -------------------------
144 | ---@class SubstitutionEntry
145 | ---@field ignoreSum boolean?
146 | ---@field reduction boolean?
147 | ---@field [number] Stat[] | false
148 | ---@type { [string]: SubstitutionEntry }
149 | addon.StatIDLookup = setmetatable({}, lowerMT)
150 | local L = addon.StatIDLookup
151 |
152 | local short = {
153 | [HP] = { {StatLogic.Stats.Health} },
154 | [MP] = { {StatLogic.Stats.Mana} },
155 | [ITEM_MOD_AGILITY_SHORT] = { {StatLogic.Stats.Agility} },
156 | [ITEM_MOD_ARMOR_PENETRATION_RATING_SHORT] = { {StatLogic.Stats.ArmorPenetrationRating} },
157 | [ITEM_MOD_ATTACK_POWER_SHORT] = { {StatLogic.Stats.GenericAttackPower} },
158 | [ITEM_MOD_BLOCK_RATING_SHORT] = { {StatLogic.Stats.BlockRating} },
159 | [ITEM_MOD_BLOCK_VALUE_SHORT] = { {StatLogic.Stats.BlockValue} },
160 | [ITEM_MOD_CRIT_MELEE_RATING_SHORT] = { {StatLogic.Stats.MeleeCritRating} },
161 | [ITEM_MOD_CRIT_RANGED_RATING_SHORT] = { {StatLogic.Stats.RangedCritRating} },
162 | [ITEM_MOD_CRIT_RATING_SHORT] = { {StatLogic.Stats.CritRating} },
163 | [ITEM_MOD_CRIT_SPELL_RATING_SHORT] = { {StatLogic.Stats.SpellCritRating} },
164 | [ITEM_MOD_DEFENSE_SKILL_RATING_SHORT] = { {StatLogic.Stats.DefenseRating} },
165 | [ITEM_MOD_DODGE_RATING_SHORT] = { {StatLogic.Stats.DodgeRating} },
166 | [ITEM_MOD_EXPERTISE_RATING_SHORT] = { {StatLogic.Stats.ExpertiseRating} },
167 | [ITEM_MOD_EXTRA_ARMOR_SHORT] = { {StatLogic.Stats.BonusArmor} },
168 | [ITEM_MOD_FERAL_ATTACK_POWER_SHORT] = { {StatLogic.Stats.FeralAttackPower} },
169 | [ITEM_MOD_HASTE_RATING_SHORT] = { {StatLogic.Stats.HasteRating} },
170 | [ITEM_MOD_HEALTH_REGEN_SHORT] = { {StatLogic.Stats.HealthRegen} },
171 | [ITEM_MOD_HEALTH_REGENERATION_SHORT] = { {StatLogic.Stats.HealthRegen} },
172 | [ITEM_MOD_HEALTH_SHORT] = { {StatLogic.Stats.Health} },
173 | [ITEM_MOD_HIT_MELEE_RATING_SHORT] = { {StatLogic.Stats.MeleeHitRating} },
174 | [ITEM_MOD_HIT_RANGED_RATING_SHORT] = { {StatLogic.Stats.RangedHitRating} },
175 | [ITEM_MOD_HIT_RATING_SHORT] = { {StatLogic.Stats.HitRating} },
176 | [ITEM_MOD_HIT_SPELL_RATING_SHORT] = { {StatLogic.Stats.SpellHitRating} },
177 | [ITEM_MOD_INTELLECT_SHORT] = { {StatLogic.Stats.Intellect} },
178 | [ITEM_MOD_MANA_REGENERATION_SHORT] = { {StatLogic.Stats.GenericManaRegen} },
179 | [ITEM_MOD_MANA_SHORT] = { {StatLogic.Stats.Mana} },
180 | [ITEM_MOD_MASTERY_RATING_SHORT] = { {StatLogic.Stats.MasteryRating} },
181 | [ITEM_MOD_MELEE_ATTACK_POWER_SHORT] = { {StatLogic.Stats.AttackPower} },
182 | [ITEM_MOD_PARRY_RATING_SHORT] = { {StatLogic.Stats.ParryRating} },
183 | [ITEM_MOD_POWER_REGEN0_SHORT] = { {StatLogic.Stats.GenericManaRegen} },
184 | [ITEM_MOD_RANGED_ATTACK_POWER_SHORT] = { {StatLogic.Stats.RangedAttackPower} },
185 | [ITEM_MOD_RESILIENCE_RATING_SHORT] = { {StatLogic.Stats.ResilienceRating} },
186 | [RESILIENCE] = { {StatLogic.Stats.ResilienceRating} },
187 | [ITEM_MOD_PVP_POWER_SHORT] = { {StatLogic.Stats.PvpPowerRating} },
188 | [STAT_PVP_POWER] = { {StatLogic.Stats.PvpPowerRating} },
189 | [ITEM_MOD_SPELL_DAMAGE_DONE_SHORT] = { {StatLogic.Stats.SpellDamage} },
190 | [ITEM_MOD_SPELL_HEALING_DONE_SHORT] = { {StatLogic.Stats.HealingPower} },
191 | [ITEM_MOD_SPELL_PENETRATION_SHORT] = { {StatLogic.Stats.SpellPenetration} },
192 | [ITEM_MOD_SPELL_POWER_SHORT] = { {StatLogic.Stats.SpellPower} },
193 | [ITEM_MOD_SPIRIT_SHORT] = { {StatLogic.Stats.Spirit} },
194 | [ITEM_MOD_STAMINA_SHORT] = { {StatLogic.Stats.Stamina} },
195 | [ITEM_MOD_STRENGTH_SHORT] = { {StatLogic.Stats.Strength} },
196 | [SPELL_STATALL] = { {StatLogic.Stats.AllStats} },
197 | [STAT_ATTACK_POWER] = { {StatLogic.Stats.GenericAttackPower} },
198 | [COMBAT_RATING_NAME9] = { {StatLogic.Stats.CritRating} },
199 | }
200 |
201 | for pattern, stat in pairs(short) do
202 | L["%s " .. pattern] = stat
203 | L[pattern .. " %s"] = stat
204 | end
205 |
206 | local long = {
207 | [ITEM_MOD_AGILITY] = { {StatLogic.Stats.Agility} },
208 | [ITEM_MOD_ARMOR_PENETRATION_RATING] = { {StatLogic.Stats.ArmorPenetrationRating} },
209 | [ITEM_MOD_ATTACK_POWER] = { {StatLogic.Stats.GenericAttackPower} },
210 | [ITEM_MOD_BLOCK_RATING] = { {StatLogic.Stats.BlockRating} },
211 | [ITEM_MOD_BLOCK_VALUE] = { {StatLogic.Stats.BlockValue} },
212 | [ITEM_MOD_CRIT_MELEE_RATING] = { {StatLogic.Stats.MeleeCritRating} },
213 | [ITEM_MOD_CRIT_RANGED_RATING] = { {StatLogic.Stats.RangedCritRating} },
214 | [ITEM_MOD_CRIT_RATING] = { {StatLogic.Stats.CritRating} },
215 | [ITEM_MOD_CRIT_SPELL_RATING] = { {StatLogic.Stats.SpellCritRating} },
216 | [ITEM_MOD_DEFENSE_SKILL_RATING] = { {StatLogic.Stats.DefenseRating} },
217 | [ITEM_MOD_DODGE_RATING] = { {StatLogic.Stats.DodgeRating} },
218 | [ITEM_MOD_EXPERTISE_RATING] = { {StatLogic.Stats.ExpertiseRating} },
219 | [ITEM_MOD_EXTRA_ARMOR] = { {StatLogic.Stats.BonusArmor} },
220 | [ITEM_MOD_FERAL_ATTACK_POWER] = { {StatLogic.Stats.FeralAttackPower} },
221 | [ITEM_MOD_HASTE_RATING] = { {StatLogic.Stats.HasteRating} },
222 | [ITEM_MOD_HEALTH] = { {StatLogic.Stats.Health} },
223 | [ITEM_MOD_HIT_MELEE_RATING] = { {StatLogic.Stats.MeleeHitRating} },
224 | [ITEM_MOD_HIT_RANGED_RATING] = { {StatLogic.Stats.RangedHitRating} },
225 | [ITEM_MOD_HIT_RATING] = { {StatLogic.Stats.HitRating} },
226 | [ITEM_MOD_HIT_SPELL_RATING] = { {StatLogic.Stats.SpellHitRating} },
227 | [ITEM_MOD_INTELLECT] = { {StatLogic.Stats.Intellect} },
228 | [ITEM_MOD_MANA] = { {StatLogic.Stats.Mana} },
229 | [ITEM_MOD_MASTERY_RATING] = { {StatLogic.Stats.MasteryRating} },
230 | [ITEM_MOD_PARRY_RATING] = { {StatLogic.Stats.ParryRating} },
231 | [ITEM_MOD_RANGED_ATTACK_POWER] = { {StatLogic.Stats.RangedAttackPower} },
232 | [ITEM_MOD_RESILIENCE_RATING] = { {StatLogic.Stats.ResilienceRating} },
233 | [ITEM_MOD_PVP_POWER] = { {StatLogic.Stats.PvpPowerRating} },
234 | [ITEM_MOD_SPELL_DAMAGE_DONE] = { {StatLogic.Stats.SpellDamage} },
235 | [ITEM_MOD_SPELL_HEALING_DONE] = { {StatLogic.Stats.HealingPower} },
236 | [ITEM_MOD_SPELL_PENETRATION] = { {StatLogic.Stats.SpellPenetration} },
237 | [ITEM_MOD_SPELL_POWER] = { {StatLogic.Stats.SpellPower} },
238 | [ITEM_MOD_SPIRIT] = { {StatLogic.Stats.Spirit} },
239 | [ITEM_MOD_STAMINA] = { {StatLogic.Stats.Stamina} },
240 | [ITEM_MOD_STRENGTH] = { {StatLogic.Stats.Strength} },
241 |
242 | [DPS_TEMPLATE] = { {StatLogic.Stats.WeaponDPS} },
243 | [ARMOR_TEMPLATE] = { {StatLogic.Stats.Armor} },
244 | [SHIELD_BLOCK_TEMPLATE] = { {StatLogic.Stats.BlockValue} },
245 | [PLUS_DAMAGE_TEMPLATE] = { {StatLogic.Stats.MinWeaponDamage}, {StatLogic.Stats.MaxWeaponDamage} },
246 | [DAMAGE_TEMPLATE] = { {StatLogic.Stats.MinWeaponDamage}, {StatLogic.Stats.MaxWeaponDamage} },
247 | [PLUS_DAMAGE_TEMPLATE_WITH_SCHOOL:format("%s", "%s", "")] = { {StatLogic.Stats.MinWeaponDamage}, {StatLogic.Stats.MaxWeaponDamage} },
248 | [AMMO_DAMAGE_TEMPLATE] = { {StatLogic.Stats.WeaponDPS} },
249 | }
250 |
251 | for pattern, stats in pairs(long) do
252 | L[unescape(pattern)] = stats
253 | end
254 |
255 | local regen = {
256 | [ITEM_MOD_HEALTH_REGEN] = { {StatLogic.Stats.HealthRegen} },
257 | [ITEM_MOD_HEALTH_REGENERATION] = { {StatLogic.Stats.HealthRegen} },
258 | [ITEM_MOD_MANA_REGENERATION] = { {StatLogic.Stats.GenericManaRegen} },
259 | }
260 |
261 | for pattern, stats in pairs(regen) do
262 | local stat = pattern:find("%%s")
263 | local five = pattern:find("5")
264 | pattern = pattern:gsub("5", "%%s")
265 | local i = stat > five and 1 or 2
266 | table.insert(stats, i, false)
267 | L[unescape(pattern)] = stats
268 | end
269 |
270 | local resistances = {
271 | [3] = StatLogic.Stats.FireResistance,
272 | [4] = StatLogic.Stats.NatureResistance,
273 | [5] = StatLogic.Stats.FrostResistance,
274 | [6] = StatLogic.Stats.ShadowResistance,
275 | [7] = StatLogic.Stats.ArcaneResistance,
276 | }
277 |
278 | if not MAX_SPELL_SCHOOLS then MAX_SPELL_SCHOOLS = 7 end
279 | for i = 2, MAX_SPELL_SCHOOLS do
280 | local school = _G["DAMAGE_SCHOOL" .. i]
281 | L[DAMAGE_TEMPLATE_WITH_SCHOOL:format("%s", "%s", school)] = { {StatLogic.Stats.MinWeaponDamage}, {StatLogic.Stats.MaxWeaponDamage} }
282 | L[PLUS_DAMAGE_TEMPLATE_WITH_SCHOOL:format("%s", "%s", school)] = { {StatLogic.Stats.MinWeaponDamage}, {StatLogic.Stats.MaxWeaponDamage} }
283 | if resistances[i] then
284 | L[unescape(ITEM_RESIST_SINGLE):format("%s", school)] = { {resistances[i]} }
285 | end
286 | end
287 |
288 | --------------------
289 | -- Prefix Exclude --
290 | --------------------
291 | -- Exclude strings by 3-5 character prefixes
292 | -- Used to reduce noise while debugging missing patterns
293 | local prefixExclusions = {
294 | SPEED,
295 | ITEM_DISENCHANT_ANY_SKILL, -- "Disenchantable"
296 | ITEM_DISENCHANT_MIN_SKILL, -- "Disenchanting requires %s (%d)"
297 | ITEM_DURATION_DAYS, -- "Duration: %d days"
298 | ITEM_CREATED_BY, -- "|cff00ff00|r"
299 | ITEM_COOLDOWN_TIME_DAYS, -- "Cooldown remaining: %d day"
300 | ITEM_UNIQUE, -- "Unique"
301 | ITEM_MIN_LEVEL, -- "Requires Level %d"
302 | ITEM_MIN_SKILL, -- "Requires %s (%d)"
303 | ITEM_CLASSES_ALLOWED, -- "Classes: %s"
304 | ITEM_RACES_ALLOWED, -- "Races: %s"
305 | }
306 |
307 | addon.PrefixExclude = {}
308 | local excludeLen = 5
309 | if locale == "koKR" or locale == "zhCN" or locale == "zhTW" then
310 | excludeLen = 3
311 | end
312 | addon.PrefixExcludeLength = excludeLen
313 |
314 | for _, exclusion in pairs(prefixExclusions) do
315 | -- Set the string to exactly excludeLen characters, right-padded.
316 | local len = string.utf8len(exclusion)
317 | if len > excludeLen then
318 | exclusion = string.utf8sub(exclusion, 1, excludeLen)
319 | elseif len < excludeLen then
320 | exclusion = exclusion .. (" "):rep(excludeLen - len)
321 | end
322 | addon.PrefixExclude[exclusion] = true
323 | end
324 |
325 | ---------------------
326 | -- PreScan Exclude --
327 | ---------------------
328 | -- Iterates all patterns, matching the whole string. Expensive so try not to use.
329 | -- Used to reduce noise while debugging missing patterns
330 | addon.PreScanPatterns = setmetatable({}, lowerMT)
331 | local itemSetNamePattern = ITEM_SET_NAME:gsub("%%%d?%$?s", ".+"):gsub("%%%d?%$?d", "%%d+"):gsub("[()]", "%%%1")
332 | addon.PreScanPatterns[itemSetNamePattern] = false
--------------------------------------------------------------------------------
/changelog_pre_git.txt:
--------------------------------------------------------------------------------
1 | ------------------------------------------------------------------------
2 | r355 | mikk | 2012-04-25 19:24:09 +0000 (Wed, 25 Apr 2012) | 1 line
3 | Changed paths:
4 | A /tags/1.6.7 (from /trunk:354)
5 |
6 | Tagging as 1.6.7 to pull in new LibStatLogic with fixed gem scanner (would error on settings gems if an equipment slot was empty)
7 | ------------------------------------------------------------------------
8 | r354 | mikk | 2012-04-23 21:23:47 +0000 (Mon, 23 Apr 2012) | 1 line
9 | Changed paths:
10 | M /trunk/RatingBuster.lua
11 |
12 | - Figure out max level automagically so it doesn't get forgotten again (using MAX_PLAYER_LEVEL_TABLE)
13 | ------------------------------------------------------------------------
14 | r353 | mikk | 2012-04-23 01:10:36 +0000 (Mon, 23 Apr 2012) | 1 line
15 | Changed paths:
16 | M /trunk/RatingBuster.lua
17 |
18 | - max level is 85, not 80
19 | ------------------------------------------------------------------------
20 | r351 | mikk | 2012-04-22 22:10:39 +0000 (Sun, 22 Apr 2012) | 4 lines
21 | Changed paths:
22 | M /trunk/RatingBuster.toc
23 |
24 | - TOC 40300
25 | Also pulling in new LibStatLogic-1.2:
26 | - Will now pick up new gems in 4.3 (belatedly)
27 | - Added code to always understand gems that already exist in your gear regardless of addon updated-ness
28 | ------------------------------------------------------------------------
29 | r350 | lightsfuryuther | 2012-01-10 00:39:00 +0000 (Tue, 10 Jan 2012) | 2 lines
30 | Changed paths:
31 | M /trunk/RatingBuster-Locale-enUS.lua
32 | M /trunk/RatingBuster.lua
33 |
34 | - Added an option to disable integration with the Reforging UI
35 | - Added English localization strings for the new configuration entries. Other locales will need to be updated.
36 | ------------------------------------------------------------------------
37 | 1.3.8
38 | - NEW: Support for negative stats
39 | - Update for 2.4.3: Parry Rating, Defense Rating, and Block Rating: Low-level players will now convert these ratings into their corresponding defensive stats at the same rate as level 34 players
40 | - Fixed: Better JewelTips support
41 | - Fixed: Druid - Nurturing Instinct (Str->Agi)
42 | - Fixed: Mage - Arcane Fortitude (50% -> 100% Armor from Int)
43 | - Optimized library usage
44 | - Updated localizations
45 | 1.3.7a
46 | - Fixed: Loading error
47 | 1.3.7
48 | - Changed: Will only show stat breakdown options your class can use
49 | - Changed: Class specific stat breakdown options will show the talents required
50 | - Added: Stat breakdown support for Mental Quickness (Shaman)
51 | - Fixed: Support for new Demonic Knowledge(Warlock) and Nurturing Instinct(Druid)
52 | - Fixed: Library errors
53 | 1.3.6
54 | - Updated toc to 20400
55 | - Fixed: Able to clear default gem settings
56 | - Fixed: Deadly Fire Opal now shows rating conversion
57 | 1.3.5
58 | - NEW: Default gems for empty sockets! Set the gems to use for each socket using /rb sum gem
59 | - In 2.4.0: Spirit-Based Mana Regeneration: This system has been adjusted so that as your intellect rises, you will regenerate more mana per point of spirit.
60 | - Fixed: Will now work with [Insightful Earthstorm Diamond]
61 | - Fixed: Profiles should now work
62 | - Changed: Use "/rb win" to open the options window instead of "/rb optionswin"
63 | 1.3.1
64 | - Fixed: Spell Haste summary works now
65 | - Fixed: Doesn't match percentages anymore (ex: Increases healing by up to 10% of your total Intellect)
66 | - Fixed: Error when sorting StatSummary alphabetically
67 | - Updated localizations: Taiwan, French, China, German, Spanish
68 | 1.3.0
69 | - Updated: TOC to 20300
70 | - Updated localizations: Taiwan, Korean, China, German
71 | - Fixed: Socketed gem stat text color after percentage conversion is no longer yellow
72 | - Fixed: "+X healing and +X spell damage" type gems and enchants now gives correct healing summary
73 | - NEW: Categorized StatSummery Options in to Basic, Physical damage, Spell damage and healing, Tank
74 | - NEW: StatSummary is sorted(basic, physical damage, spell damage and healing, tank in that order)
75 | - NEW: Option to sort StatSummary alphabetically instead of the above
76 | - NEW: Option to include block chance in Avoidance summary
77 | - StatSummary Added:
78 | Resilience
79 | Haste
80 | Haste Rating
81 | Spell Haste
82 | Spell Haste Rating
83 | Penetration
84 | IgnoreArmor
85 | HitRating
86 | CritRating
87 | SpellHitRating
88 | SpellCritRating
89 | DodgeRating
90 | ParryRating
91 | BlockRating
92 | 1.2.8
93 | - Fixed: +X Spell Power gives healing too
94 | - In 2.3.0: Support for Spell Damage bonus in +Healing stats
95 | 1.2.7
96 | - NEW: Option to Show detail text for Resilience and Expertise conversions
97 | - NEW: Option to Show Avoidance Summary <- Dodge, Parry, MobMiss
98 | - NEW: TankPoints support, if you have TankPoints loaded you get 2 new summary options: TankPoints and Total Reduction
99 | - In 2.3.0: Added Expertise stat support
100 | - In 2.3.0: Heart of the Wild (Druid Feral Combat talent) provides 2/4/6/8/10% bonus attack power in Cat form instead
101 | - In 2.3.0: Intensity (Druid Restoration talent) increased to 10/20/30% mana regeneration
102 | - In 2.3.0: Arcane Meditation (Mage Arcane talent) increased to 10/20/30% mana regeneration
103 | - In 2.3.0: Meditation (Priest Discipline talent) increased to 10/20/30% mana regeneration
104 | - In 2.3.0: Weapon Expertise (Paladin Protection talent) renamed Combat Expertise, now increases expertise by 1/2/3/4/5 and total Stamina by 2/4/6/8/10%
105 | - In 2.3.0: Mental Quickness (Shaman Enhancement talent) now also increases spell damage and healing equal to 10/20/30% of your attack power
106 | - All 2.3.0 Changes will only take affect when using a 2.3.0 client.
107 | - Updated: German localization
108 | 1.2.6
109 | - Fixed: Ranged AP Calculations
110 | 1.2.5
111 | - Updated: toc to 20200
112 | - Fixed: Haste rating change in 2.2.0
113 | - Fixed: Hunter Survival Instincts talent support
114 | - Fixed: Armor multiplier no longer apply to Armor from enchants
115 | - NEW: Added China localization by iceburn(candykiss)
116 | - Updated: Taiwan localization
117 | - Updated: Korean localization by fenlis
118 | - Updated: German localization by Dleh
119 | - Code optimizations
120 | - Updated: Libs
121 | 1.2.4
122 | - Fixed: Error when difftype is set to comp
123 | - Made Waterfall-1.0 optional
124 | 1.2.3
125 | - NEW: You can now open the options window using /rb optionswin
126 | - Updated Taiwan localization
127 | - Updated Korean localizations by fenlis
128 | 1.2.2
129 | - New option to hide the StatSummary title
130 | - New option to hide the sigma icon in the StatSummary title
131 | - New option to add a empty line after the StatSummary
132 | - Updated Taiwan localization
133 | - Other localizations needs to be updated
134 | 1.2.1
135 | - Updated Taiwan localization
136 | - Improved stat scanning
137 | - Updated German localization
138 | 1.2.0
139 | - Updated French localization by Tixu and Silaor, now supports StatSummary
140 | - Fixed a bug causing StatSummary not showing correctly for languages other then English
141 | - Fixed Parry/SpellHaste rating conversions
142 | - Updated libs
143 | 1.1.9
144 | - Pre updated the TOC to 2.1.0
145 | - Improved the Sigma icon
146 | - Updated readme file
147 | 1.1.8
148 | - StatSummary: "Mana Regen while Not casting" now shows the correct value
149 | - StatSummary: "Health Regen while Out of Combat" now shows the correct value
150 | - StatSummary: fixed lines with "and" counting stats twice
151 | - Added support for Gnome +5% Intellect Racial
152 | - Added support for Human +10% Spirit Racial
153 | - Fixed StatLogic line 6285 strfind error (thanks to everyone that helped)
154 | - Updated Korean localizations by fenlis
155 | 1.1.7
156 | - Minor bug fixes
157 | - Updated Taiwan localizations by mcc
158 | - Updated Korean localizations by fenlis
159 | - Updated French localizations by renchap
160 | 1.1.6
161 | - Stat Summary now has the option to show resistances
162 | - Fixed Feral Attack Power name
163 | - /rb sum ignore unused now shows leather for hunters
164 | - Fixed an error when mousing over items that goes into a slot you currently have no equipment in when you have the ignore enchant or gem option on
165 | 1.1.5
166 | - Fixed MP5NC, HP5OC summary
167 | - Changed default diff style from comp to main, since not everyone uses a compare addon
168 | - Attempt to fix some more funny bugs
169 | 1.1.4
170 | - Option to display Weapon Max Damage in summary
171 | - Improved option for ignoring enchants and gems, they are now 2 different options
172 | - Fixed some classes not showing summary for cloaks
173 | - Fixed incorrect shield diffs
174 | - Improved diff style code should fix funny errors
175 | 1.1.3
176 | - Fixed EQCompare, tekKompare support
177 | - Updated Taiwan localizations
178 | 1.1.2
179 | - Option to Display diff values in the main tooltip or only in compare tooltips for readability
180 | - Option to Ignore enchants and gems on items when calculating the stat summary
181 | - /rb sum ignore unused now shows all armor types they are use for druids, paladins and shamans
182 | - Updated Taiwan localizations
183 | - Code clean up
184 | 1.1.1
185 | - Option to Show stat summary only for highest level armor type and items you can use with uncommon quality and up
186 | - Option to Hide stat summary for equipped items
187 | - Option to Add a blank line before stat summary for readability
188 | - Mage, Warlock, Shaman now shows spellcrit as default summary instead of crit
189 | - Updated Taiwan localizations
190 | - Minor bug fixes
191 | 1.1.0
192 | - NEW: Stat Summary - Display the sum of stats of the item and/or the stat difference of the item and your equipped items
193 | - Choose the stats you really care about to be show in the summary
194 | - Composite stats are broken down and added into base stats, and supports talent/buff mods, Ex: "Spell Crit Chance" is calculated from "Spell Crit Rating" and "Intellect"
195 | - Option descriptions now show class names for class specific stat conversions
196 | - Added support for Aspect of the Viper
197 | - Option to hide rating conversions
198 | - Option to hide all base stat conversions
199 | - Option to further breakdown Defense into Crit Avoidance, Hit Avoidance, Dodge, Parry and Block
200 | - Option to further breakdown Weapon Skills into Crit, Hit, Dodge Neglect, Parry Neglect, Block Neglect
201 | - Fixed Taiwan and French localization errors
202 | - Fixed locale registering twice error
203 | - Fixed mp5 and hp5 calculations for Shaman, Druid, Mage, Warlock
204 | - Agi -> Dodge only works for your current level, for best results turn off /rb usereqlv, and set /rb level 0
205 | 1.0.0
206 | - Support for talents and buffs that modify your stats
207 | - Supports the following stat conversions
208 | - Str -> AP, Block, Healing(Talent)
209 | - Agi -> Crit, Dodge, AP, RAP, Armor
210 | - Sta -> Health, SpellDmg(Talent)
211 | - Int -> Mana, SpellCrit, SpellDmg(Talent), Healing(Talent), MP5(Talent), RAP(Talent), Armor(Talent)
212 | - Spi -> MP5(Talent), MP5NC, HP5, SpellDmg(Talent), Healing(Talent)
213 | - If you need a GUI config window for RatingBuster, use Niagara (Download at: http://files.wowace.com/)
214 | 0.9.5
215 | - Fixed library error
216 | 0.9.4
217 | - Added Taiwan localizations by CuteMiyu
218 | 0.9.3
219 | - Updated Korean localization by kcgcom
220 | 0.9.2
221 | - Code clean up
222 | - Finally removed Compost
223 | 0.9.1a
224 | - Really fixed locales
225 | 0.9.1
226 | - Fixed locales
227 | - Added Korean localization by kcgcom
228 | 0.9.0
229 | - Optimized parsing algorithm to use fewer resources
230 | - showCritFromAgi and showSpellCritFromInt will now correctly save as per class data
231 | - /rb level will now save
232 | - No longer scans buffs
233 | - Code clean up
234 | 0.8.6
235 | - tekKompare support
236 | - Sniff support
237 | 0.8.5
238 | - AtlasLoot support
239 | - ItemMagic support
240 | - Fixed line 785 error
241 | 0.8.4
242 | - Spell Crit from Intellect defaults off for Hunters too
243 | 0.8.3
244 | - Fixed color picker bug
245 | - Updated French localization (Tixu)
246 | 0.8.2
247 | - Fixed % signs showing before some periods bug
248 | 0.8.1
249 | - Option to enable colored text (/rb color)
250 | - Fixed Defense showing the % sign bug
251 | - Fixed Haste Rating conversion
252 | - Updated French localization (Tixu)
253 | 0.8.0
254 | - Option to show Crit from Agility, Ex: "+15 Agility (+0.72% Crit)"
255 | - Option to show Spell Crit from Intellect, Ex: "+23 Intellect (+0.35% Spell Crit)"
256 | - Support for "grant you xx stat" type pattern, ex: Quel'Serrar, Assassination Armor set
257 | - "+14 (1.21%) Rating" type strings changed to "+14 Rating (+1.21%)"
258 | - Recoded tooltip scanner is now more easily extendable and has support for multiple separators for better accuracy.
259 | 0.7.6
260 | - The amount of haste granted by a point of haste rating has been increased by 50% (Patch 2.0.7)
261 | - Fixed Mutltitips support
262 | - Minor code tweaks
263 | 0.7.5
264 | - Fixed double conversion bug
265 | - Fixed GetItem error
266 | - Support for Hit Avoidance Rating (assuming its the same as melee Hit Rating)
267 | 0.7.1
268 | - Fixed a hooking bug
269 | 0.7.0
270 | - Now uses the OnTooltipSetItem script handler instead of hooking all the SetX methods,
271 | this combined with the new Tooltip:GetItem() method should also fix problems where
272 | RatingBuster doesn't always work, like at the mailbox.
273 | 0.6.6
274 | - MultiTips support
275 | 0.6.5
276 | - LinkWrangler support
277 | 0.6.4
278 | - Updated Libs
279 | 0.6.3
280 | - Use required level defaults to true
281 | - Support for EQCompare
282 | - Changed toc to 20003 for TBC (It will show up as out-of-date until TBC goes live, enable loading out-of-date to load it)
283 | 0.6.2
284 | - Added German localization by Runenstetter@Nathrezim.EU
285 | - Fixed French localization
286 | 0.6.1
287 | - Added French localization by Tixu
288 | 0.6
289 | - Added option to calculate using the required level if you are below the required level
290 | - Redesigned the tooltip scanner to be more locale friendly, should be easier to do translations now.
291 | 0.5.1
292 | - Fixed line 457 error
293 | 0.5
294 | - Improved ItemLevel and ItemID algorithm, will now work on most tooltips
295 | - Updated Libs
296 | 0.4.3
297 | - Fixed line 499 error
298 | - Temporarily removed ItemLevel and ID support for Bagnon, working on a better implementation
299 | 0.4.2
300 | - Fixed a rare error in line 487
301 | - Updated Libs
302 | 0.4.1
303 | - Inspect frame support for ItemLevel and ItemID
304 | - Two-Handed skill ratings now works
305 | 0.4
306 | - Bagnon support for ItemLevel and ItemID
307 | - Fixed some errors
308 | - Updated libs
309 | 0.3.2
310 | - Fixed auction house bug
311 | 0.3.1
312 | - Fixed keyring bug
313 | 0.3
314 | - Works with enchant links
315 | - Works with keyring items
316 | 0.2.1
317 | - Fixed AceConsole error
318 | 0.2
319 | - Simplified the localization file for easier localization
320 | - Added keyword "spell crit"
321 | - Added Item Level, Item ID support for profession trainer items
322 | - Set Debugging to false
323 | 0.1.1
324 | - Removed AceHook2.1 cause it was causing problems with other Ace2 addons
325 | 0.1
326 | - Initial release
327 |
--------------------------------------------------------------------------------
/reference.txt:
--------------------------------------------------------------------------------
1 | **************************************
2 | ** How I derived the Rating Formula **
3 | **************************************
4 |
5 | As soon as I saw the blue post on combat ratings system, I began to think about coding this addon.
6 | But Blizzard only gave us level 60 and 70 data about this system, and for an addon like this to work you need exact formula that will work for all levels.
7 | So I need to reverse engineer the Combat Rating formula, and the process of obtaining this formula can be broken up into two simple steps.
8 |
9 | 1. Get more data
10 | In order to obtain the exact formula, I will need more data points then just level 60 and 70. So I logged on and started asking random people about their crit% and crit ratings show in the Character frame, the problem was the crit% shown only has 2 two decimal places, which turned out to be insufficient for this matter.
11 |
12 | So I started to dig in the DefaultUI lua files in search for a new API that will give a more precise crit% and I came up with this script /script DEFAULT_CHAT_FRAME:AddMessage(GetCombatRatingBonus(9)).
13 |
14 | Now I need to log on again and ask random people to type that script and tell me that 13 decimal place crit% that it shows. This was not an easy task, as most people are unfamiliar with lua script, there are even people that immediately put me on ignore after I sent him this script lol.
15 |
16 | After hours of work, this is what I got:
17 | A B C D E F G H
18 | Lv Type Rating Percentage =C/D 60base =E/F =1/G
19 | 19 crit 2 0.6753247631 2.9615380764 14 0.211538434 4.727273342
20 | 21 crit 2 0.5714285714 3.5000000000 14 0.25 4
21 | 22 crit 2 0.5306122010 3.7692310810 14 0.269230792 3.714285407
22 | 28 crit 2 0.3714286018 5.3846149445 14 0.384615353 2.6
23 | 29 crit 2 0.3537415195 5.6538457870 14 0.403846128 2.476190637
24 | 36 crit 14 1.8557142035 7.5442651532 14 0.538876082 1.855714204
25 | 48 crit 14 1.2999998760 10.7692317963 14 0.769230843 1.3
26 | 50 crit 14 1.2380952140 11.3076925278 14 0.807692323 1.238095214
27 | 60 crit 112 8.0000000000 14.0000000000 14 1 1
28 | 61 crit 56 3.8536582293 14.5316467285 14 1.037974766 0.963414557
29 | 62 hit 50 4.6341464061 10.7894735336 10 1.078947353 0.926829281
30 | 62 crit 56 3.7073167036 15.1052646637 14 1.078947476 0.926829176
31 | 63 crit 31 1.9712541049 15.7260293961 14 1.123287814 0.890243789
32 | 64 crit 17 1.0365853900 16.3999996185 14 1.171428544 0.853658556
33 | 65 crit 56 3.2682925906 17.1343288422 14 1.223880632 0.817073148
34 | 66 crit 168 9.3658536585 17.9375000000 14 1.28125 0.780487805
35 | 66 sp_hit 48 4.6829268293 10.2500000000 8 1.28125 0.780487805
36 | 67 crit 78 4.1445989933 18.8196735382 14 1.344262396 0.743902383
37 | 67 crit 76 4.0383272242 18.8196735382 14 1.344262396 0.743902383
38 |
39 | 2. Think very hard
40 | After some creative thinking, this is what I got:
41 |
42 | Percentage = Rating / F * H
43 | Lv 8 to 60: 1/H = 1/52 * Level - 8/52
44 | Lv 60 to 70: H = - 3/82 * Level + 131/41
45 |
46 | F=
47 | Weapon Skill 2.5
48 | Expertise 2.5
49 | Defense 1.5
50 | Dodge 12.0
51 | Parry 15.0
52 | Block 5.0
53 | Hit 10.0
54 | Crit 14.0
55 | Haste 10.0
56 | Spell Hit 8.0
57 | Spell Crit 14.0
58 | Spell Haste 10.0
59 | Resilience 25.0
60 |
61 | This formula is correct to the 13th decimal place, so I'm 100% sure this is what blizzard uses.
62 |
63 |
64 | ****************************************
65 | ** Stat Conversion Data for Reference **
66 | ****************************************
67 |
68 | Combat rating needed for 1 point of stat
69 | WepS Defe Dodge Parry Bloc M-Hit M-Crit M-Hst S-Hit S-Crit S-Hst Resil
70 | 70 3.94 2.37 18.92 31.54 7.88 15.77 22.08 15.77 12.62 22.08 15.77 39.42
71 | 69 3.73 2.24 17.89 29.82 7.45 14.91 20.87 14.91 11.93 20.87 14.91 37.27
72 | 68 3.53 2.12 16.97 28.28 7.07 14.14 19.79 14.14 11.31 19.79 14.14 35.34
73 | 67 3.36 2.02 16.13 26.89 6.72 13.44 18.82 13.44 10.75 18.82 13.44 33.61
74 | 66 3.20 1.92 15.38 25.63 6.41 12.81 17.94 12.81 10.25 17.94 12.81 32.03
75 | 65 3.06 1.84 14.69 24.48 6.12 12.24 17.13 12.24 9.79 17.13 12.24 30.60
76 | 64 2.93 1.76 14.06 23.43 5.86 11.71 16.40 11.71 9.37 16.40 11.71 29.29
77 | 63 2.81 1.68 13.48 22.47 5.62 11.23 15.73 11.23 8.99 15.73 11.23 28.08
78 | 62 2.70 1.62 12.95 21.58 5.39 10.79 15.11 10.79 8.63 15.11 10.79 26.97
79 | 61 2.59 1.56 12.46 20.76 5.19 10.38 14.53 10.38 8.30 14.53 10.38 25.95
80 | 60 2.50 1.50 12.00 20.00 5.00 10.00 14.00 10.00 8.00 14.00 10.00 25.00
81 | 59 2.45 1.47 11.77 19.62 4.90 9.81 13.73 9.81 7.85 13.73 9.81 24.52
82 | 58 2.40 1.44 11.54 19.23 4.81 9.62 13.46 9.62 7.69 13.46 9.62 24.04
83 | 57 2.36 1.41 11.31 18.85 4.71 9.42 13.19 9.42 7.54 13.19 9.42 23.56
84 | 56 2.31 1.38 11.08 18.46 4.62 9.23 12.92 9.23 7.38 12.92 9.23 23.08
85 | 55 2.26 1.36 10.85 18.08 4.52 9.04 12.65 9.04 7.23 12.65 9.04 22.60
86 | 54 2.21 1.33 10.62 17.69 4.42 8.85 12.38 8.85 7.08 12.38 8.85 22.12
87 | 53 2.16 1.30 10.38 17.31 4.33 8.65 12.12 8.65 6.92 12.12 8.65 21.63
88 | 52 2.12 1.27 10.15 16.92 4.23 8.46 11.85 8.46 6.77 11.85 8.46 21.15
89 | 51 2.07 1.24 9.92 16.54 4.13 8.27 11.58 8.27 6.62 11.58 8.27 20.67
90 | 50 2.02 1.21 9.69 16.15 4.04 8.08 11.31 8.08 6.46 11.31 8.08 20.19
91 | 49 1.97 1.18 9.46 15.77 3.94 7.88 11.04 7.88 6.31 11.04 7.88 19.71
92 | 48 1.92 1.15 9.23 15.38 3.85 7.69 10.77 7.69 6.15 10.77 7.69 19.23
93 | 47 1.88 1.13 9.00 15.00 3.75 7.50 10.50 7.50 6.00 10.50 7.50 18.75
94 | 46 1.83 1.10 8.77 14.62 3.65 7.31 10.23 7.31 5.85 10.23 7.31 18.27
95 | 45 1.78 1.07 8.54 14.23 3.56 7.12 9.96 7.12 5.69 9.96 7.12 17.79
96 | 44 1.73 1.04 8.31 13.85 3.46 6.92 9.69 6.92 5.54 9.69 6.92 17.31
97 | 43 1.68 1.01 8.08 13.46 3.37 6.73 9.42 6.73 5.38 9.42 6.73 16.83
98 | 42 1.63 0.98 7.85 13.08 3.27 6.54 9.15 6.54 5.23 9.15 6.54 16.35
99 | 41 1.59 0.95 7.62 12.69 3.17 6.35 8.88 6.35 5.08 8.88 6.35 15.87
100 | 40 1.54 0.92 7.38 12.31 3.08 6.15 8.62 6.15 4.92 8.62 6.15 15.38
101 | 39 1.49 0.89 7.15 11.92 2.98 5.96 8.35 5.96 4.77 8.35 5.96 14.90
102 | 38 1.44 0.87 6.92 11.54 2.88 5.77 8.08 5.77 4.62 8.08 5.77 14.42
103 | 37 1.39 0.84 6.69 11.15 2.79 5.58 7.81 5.58 4.46 7.81 5.58 13.94
104 | 36 1.35 0.81 6.46 10.77 2.69 5.38 7.54 5.38 4.31 7.54 5.38 13.46
105 | 35 1.30 0.78 6.23 10.38 2.60 5.19 7.27 5.19 4.15 7.27 5.19 12.98
106 | 34 1.25 0.75 6.00 10.00 2.50 5.00 7.00 5.00 4.00 7.00 5.00 12.50
107 | 33 1.20 0.72 5.77 9.62 2.40 4.81 6.73 4.81 3.85 6.73 4.81 12.02
108 | 32 1.15 0.69 5.54 9.23 2.31 4.62 6.46 4.62 3.69 6.46 4.62 11.54
109 | 31 1.11 0.66 5.31 8.85 2.21 4.42 6.19 4.42 3.54 6.19 4.42 11.06
110 | 30 1.06 0.63 5.08 8.46 2.12 4.23 5.92 4.23 3.38 5.92 4.23 10.58
111 | 29 1.01 0.61 4.85 8.08 2.02 4.04 5.65 4.04 3.23 5.65 4.04 10.10
112 | 28 0.96 0.58 4.62 7.69 1.92 3.85 5.38 3.85 3.08 5.38 3.85 9.62
113 | 27 0.91 0.55 4.38 7.31 1.83 3.65 5.12 3.65 2.92 5.12 3.65 9.13
114 | 26 0.87 0.52 4.15 6.92 1.73 3.46 4.85 3.46 2.77 4.85 3.46 8.65
115 | 25 0.82 0.49 3.92 6.54 1.63 3.27 4.58 3.27 2.62 4.58 3.27 8.17
116 | 24 0.77 0.46 3.69 6.15 1.54 3.08 4.31 3.08 2.46 4.31 3.08 7.69
117 | 23 0.72 0.43 3.46 5.77 1.44 2.88 4.04 2.88 2.31 4.04 2.88 7.21
118 | 22 0.67 0.40 3.23 5.38 1.35 2.69 3.77 2.69 2.15 3.77 2.69 6.73
119 | 21 0.63 0.38 3.00 5.00 1.25 2.50 3.50 2.50 2.00 3.50 2.50 6.25
120 | 20 0.58 0.35 2.77 4.62 1.15 2.31 3.23 2.31 1.85 3.23 2.31 5.77
121 | 19 0.53 0.32 2.54 4.23 1.06 2.12 2.96 2.12 1.69 2.96 2.12 5.29
122 | 18 0.48 0.29 2.31 3.85 0.96 1.92 2.69 1.92 1.54 2.69 1.92 4.81
123 | 17 0.43 0.26 2.08 3.46 0.87 1.73 2.42 1.73 1.38 2.42 1.73 4.33
124 | 16 0.38 0.23 1.85 3.08 0.77 1.54 2.15 1.54 1.23 2.15 1.54 3.85
125 | 15 0.34 0.20 1.62 2.69 0.67 1.35 1.88 1.35 1.08 1.88 1.35 3.37
126 | 14 0.29 0.17 1.38 2.31 0.58 1.15 1.62 1.15 0.92 1.62 1.15 2.88
127 | 13 0.24 0.14 1.15 1.92 0.48 0.96 1.35 0.96 0.77 1.35 0.96 2.40
128 | 12 0.19 0.12 0.92 1.54 0.38 0.77 1.08 0.77 0.62 1.08 0.77 1.92
129 | 11 0.14 0.09 0.69 1.15 0.29 0.58 0.81 0.58 0.46 0.81 0.58 1.44
130 | 10 0.10 0.06 0.46 0.77 0.19 0.38 0.54 0.38 0.31 0.54 0.38 0.96
131 | 9 0.05 0.03 0.23 0.38 0.10 0.19 0.27 0.19 0.15 0.27 0.19 0.48
132 | 8 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
133 | WepS Defe Dodge Parry Bloc M-Hit M-Crit M-Hst S-Hit S-Crit S-Hst Resil
134 |
135 | Agility needed for 1% Crit
136 | War Pal Hun Rog Pri Sha Mage Lock Dru
137 | 1 4.00 4.60 3.52 2.23 11.00 6.01 12.97 6.67 4.95
138 | 2 4.20 4.83 3.53 2.33 11.00 6.01 12.97 6.67 4.95
139 | 3 4.20 4.83 3.69 2.43 11.00 6.32 12.97 7.00 5.20
140 | 4 4.40 5.06 3.95 2.62 11.56 6.32 13.61 7.00 5.20
141 | 5 4.60 5.06 4.12 2.72 11.56 6.62 13.61 7.00 5.45
142 | 6 4.80 5.29 4.28 2.82 11.56 6.62 13.61 7.33 5.45
143 | 7 4.80 5.29 4.44 3.01 11.56 6.62 13.61 7.33 5.69
144 | 8 5.00 5.52 4.61 3.11 12.11 6.92 13.61 7.33 5.69
145 | 9 5.20 5.52 4.88 3.21 12.11 6.92 13.61 7.67 5.94
146 | 10 5.20 5.75 5.04 3.40 12.11 7.22 14.27 7.67 6.44
147 | 11 5.40 5.75 5.41 3.79 12.11 7.22 14.27 8.00 6.68
148 | 12 5.60 5.98 5.99 4.18 12.66 7.52 14.27 8.00 6.68
149 | 13 6.00 6.44 6.46 4.66 12.66 7.52 14.27 8.00 6.93
150 | 14 6.20 6.44 6.94 5.05 12.66 7.82 14.27 8.33 6.93
151 | 15 6.40 6.90 7.52 5.63 12.66 8.12 14.90 8.67 7.43
152 | 16 6.60 6.90 7.89 6.02 13.21 8.42 14.90 9.00 7.43
153 | 17 6.80 7.13 8.38 6.41 13.21 8.42 14.90 9.00 7.67
154 | 18 7.20 7.59 8.95 6.90 13.21 8.72 14.90 9.00 7.92
155 | 19 7.40 7.59 9.43 7.38 13.76 8.72 14.90 9.34 7.92
156 | 20 7.80 8.05 10.02 7.87 13.76 9.32 15.55 9.67 8.91
157 | 21 7.80 8.28 10.40 8.35 13.76 9.32 15.55 10.00 8.91
158 | 22 8.00 8.28 10.99 8.74 13.76 9.62 15.55 10.00 9.16
159 | 23 8.40 8.74 11.47 9.23 14.31 9.62 15.55 10.33 9.41
160 | 24 8.60 8.97 12.06 9.62 14.31 9.92 16.21 10.33 9.41
161 | 25 9.00 9.20 12.55 10.20 14.31 10.22 16.21 11.00 9.90
162 | 26 9.20 9.43 13.04 10.68 14.86 10.53 16.21 11.00 9.90
163 | 27 9.40 9.66 13.62 11.07 14.86 10.53 16.21 11.00 10.15
164 | 28 9.80 9.89 14.10 11.56 14.86 10.82 16.21 11.34 10.40
165 | 29 10.00 10.12 14.71 12.05 15.41 10.82 16.86 11.34 10.40
166 | 30 10.40 10.58 15.29 12.63 15.41 11.43 16.86 12.00 11.39
167 | 31 10.60 10.81 15.70 13.02 15.41 11.43 16.86 12.00 11.64
168 | 32 10.80 10.81 16.29 13.50 15.95 11.72 16.86 12.33 11.64
169 | 33 11.20 11.27 16.89 13.99 15.95 12.03 17.51 12.33 11.89
170 | 34 11.40 11.49 17.39 14.47 15.95 12.03 17.51 12.67 12.14
171 | 35 11.81 11.96 17.99 15.06 16.50 12.63 17.51 13.00 12.38
172 | 36 12.00 12.20 18.48 15.55 16.50 12.94 18.15 13.33 12.63
173 | 37 12.20 12.20 19.08 15.92 16.50 12.94 18.15 13.66 12.87
174 | 38 12.59 12.64 19.69 16.42 17.06 13.23 18.15 13.66 12.87
175 | 39 12.80 12.89 20.28 16.89 17.06 13.23 18.15 14.01 13.12
176 | 40 13.19 13.33 20.79 17.48 17.06 13.83 18.80 14.33 14.10
177 | 41 13.61 13.57 21.28 17.99 17.61 14.14 18.80 14.66 14.37
178 | 42 13.79 13.57 21.88 18.45 17.61 14.14 18.80 14.66 14.37
179 | 43 14.20 14.03 22.52 18.94 18.15 14.43 18.80 14.99 14.60
180 | 44 14.41 14.27 23.09 19.53 18.15 14.73 19.46 14.99 14.86
181 | 45 14.79 14.73 23.75 20.12 18.15 15.04 19.46 15.67 15.36
182 | 46 14.99 14.95 24.21 20.58 18.73 15.34 19.46 16.00 15.60
183 | 47 15.41 15.17 24.88 21.10 18.73 15.65 20.08 16.00 15.60
184 | 48 15.80 15.65 25.58 21.55 19.27 15.95 20.08 16.34 15.85
185 | 49 16.00 15.87 26.18 22.03 19.27 15.95 20.08 16.67 16.10
186 | 50 16.39 16.34 26.81 22.73 19.27 16.53 20.75 17.01 17.09
187 | 51 16.81 16.56 27.32 23.20 19.80 16.84 20.75 17.33 17.33
188 | 52 17.01 16.78 27.93 23.70 19.80 17.15 20.75 17.33 17.57
189 | 53 17.39 17.24 28.57 24.27 20.37 17.15 21.41 17.67 17.83
190 | 54 17.79 17.48 29.33 24.75 20.37 17.45 21.41 17.99 17.83
191 | 55 18.21 17.95 29.94 25.38 20.92 18.05 21.41 18.35 18.32
192 | 56 18.42 18.18 30.49 25.91 20.92 18.35 22.03 18.66 18.55
193 | 57 18.80 18.38 31.15 26.46 21.46 18.66 22.03 19.01 18.83
194 | 58 19.19 18.87 31.85 27.03 21.46 18.66 22.03 19.34 19.05
195 | 59 19.61 19.08 32.57 27.47 22.03 18.94 22.68 19.34 19.31
196 | 60 20.00 19.53 33.22 28.17 22.03 19.53 22.68 20.00 20.28
197 | 61 21.32 20.37 33.67 29.94 22.57 20.16 22.99 20.66 20.92
198 | 62 22.62 20.70 34.48 31.06 22.52 20.58 23.15 20.79 21.19
199 | 63 23.92 21.19 35.21 32.57 22.68 21.28 23.58 21.28 21.93
200 | 64 25.19 21.93 35.84 33.78 23.09 21.93 23.64 21.98 22.37
201 | 65 26.53 22.42 36.63 34.97 23.47 22.27 23.70 22.32 22.83
202 | 66 27.78 22.88 37.04 36.23 23.87 22.88 24.33 22.99 23.26
203 | 67 29.07 23.53 37.88 37.31 24.15 23.42 24.27 22.94 23.58
204 | 68 30.40 24.04 38.61 38.17 24.27 23.98 24.51 23.58 24.27
205 | 69 31.75 24.51 39.37 39.06 24.39 24.51 24.75 24.15 24.63
206 | 70 33.00 25.00 40.00 40.00 25.00 25.00 25.00 24.69 25.00
207 | War Pal Hun Rog Pri Sha Mage Lock Dru
208 |
209 | Intellect needed for 1% Spell Crit
210 | Pal Hun Pri Sha Mage Lock Dru
211 | 1 12.02 14.31 5.85 7.50 6.11 6.67 6.99
212 | 2 12.61 15.02 6.11 7.86 6.35 6.97 7.30
213 | 3 12.61 15.02 6.38 8.22 6.60 7.27 7.62
214 | 4 13.21 15.75 6.64 8.22 7.09 7.58 7.94
215 | 5 13.21 15.75 7.17 8.58 7.33 7.88 8.26
216 | 6 13.81 16.45 7.44 8.93 7.58 8.18 8.58
217 | 7 14.41 16.45 7.71 9.29 7.82 8.48 8.90
218 | 8 14.41 17.15 7.97 9.64 8.06 8.79 8.90
219 | 9 15.02 17.15 8.24 10.00 8.55 9.09 9.21
220 | 10 15.02 17.89 8.77 10.00 8.80 9.39 10.16
221 | 11 15.63 17.89 9.57 10.72 9.53 10.30 10.80
222 | 12 16.23 18.59 10.63 11.43 10.75 11.21 11.75
223 | 13 16.84 20.04 11.43 12.50 11.48 12.12 12.39
224 | 14 17.42 20.04 12.76 13.23 13.68 13.04 13.33
225 | 15 18.62 21.46 13.81 14.29 14.90 13.95 14.62
226 | 16 18.62 21.46 14.62 15.02 15.65 14.53 15.24
227 | 17 19.23 22.17 15.95 15.72 16.61 15.75 16.21
228 | 18 20.41 23.58 16.75 16.78 17.61 16.67 16.84
229 | 19 20.41 23.58 17.79 17.51 18.59 17.57 17.79
230 | 20 21.65 25.06 19.12 18.59 19.80 18.48 19.38
231 | 21 22.22 25.77 19.92 19.31 20.53 19.38 20.00
232 | 22 22.83 25.77 21.28 20.00 21.74 20.28 20.96
233 | 23 23.42 27.17 22.08 21.10 22.47 21.23 21.60
234 | 24 24.04 27.93 23.36 21.79 23.70 22.42 22.88
235 | 25 25.25 28.57 24.45 22.88 24.69 23.31 23.81
236 | 26 25.84 29.33 25.51 23.58 25.64 23.92 24.45
237 | 27 25.84 30.03 26.60 24.27 26.88 25.13 25.38
238 | 28 27.03 30.77 27.62 25.38 29.59 26.04 26.04
239 | 29 27.62 31.45 28.74 26.11 30.77 27.25 27.32
240 | 30 28.82 32.89 30.03 27.17 32.05 28.17 28.90
241 | 31 29.41 33.67 31.06 28.25 32.79 28.82 29.50
242 | 32 30.03 33.67 32.15 28.90 34.01 30.03 30.77
243 | 33 30.67 35.09 33.22 30.03 34.97 30.86 31.45
244 | 34 31.25 35.71 34.60 30.77 35.97 32.15 32.36
245 | 35 32.47 37.17 35.59 31.85 37.17 33.00 33.67
246 | 36 33.00 37.88 36.63 32.89 38.17 33.90 34.25
247 | 37 33.67 37.88 38.02 33.56 39.37 35.21 35.21
248 | 38 34.84 39.37 39.06 34.60 40.32 36.10 36.23
249 | 39 35.46 40.00 40.16 35.34 41.49 37.31 37.17
250 | 40 36.63 41.49 41.49 36.76 42.55 38.17 39.06
251 | 41 37.31 42.19 42.55 37.45 43.48 39.06 39.68
252 | 42 37.88 42.19 43.86 38.17 46.51 40.32 40.98
253 | 43 39.06 43.67 44.84 39.37 47.39 41.15 41.67
254 | 44 39.06 44.44 46.30 40.32 48.54 42.37 42.92
255 | 45 40.32 45.87 47.62 41.49 49.75 43.67 43.86
256 | 46 40.82 46.51 48.54 42.55 50.76 44.64 44.84
257 | 47 42.02 47.17 50.00 43.29 52.08 45.45 45.66
258 | 48 43.29 48.54 51.02 44.25 53.19 46.73 46.73
259 | 49 43.86 49.26 52.36 45.45 54.35 47.85 47.85
260 | 50 45.05 50.76 53.76 46.51 55.87 49.02 49.50
261 | 51 45.66 51.55 54.64 47.62 56.82 50.00 50.51
262 | 52 46.30 52.08 56.18 48.31 57.80 51.28 51.81
263 | 53 47.39 53.76 57.14 49.75 58.82 52.36 52.36
264 | 54 48.08 54.35 58.48 50.25 60.24 53.76 53.76
265 | 55 49.26 55.87 60.24 51.81 61.73 54.95 54.95
266 | 56 49.75 56.50 60.98 52.63 64.94 55.87 55.87
267 | 57 50.51 57.14 62.50 53.48 66.23 56.82 56.82
268 | 58 52.36 58.82 63.69 54.95 67.11 58.14 57.80
269 | 59 52.91 59.52 64.94 55.87 68.49 59.52 59.17
270 | 60 54.05 60.98 66.23 57.14 69.93 60.61 60.98
271 | 61 63.69 63.69 67.57 60.98 69.93 62.89 61.73
272 | 62 65.36 64.94 68.97 62.89 69.93 64.94 63.69
273 | 63 67.57 66.67 69.93 65.79 69.93 67.57 66.67
274 | 64 69.93 69.44 71.94 68.03 70.42 69.93 68.49
275 | 65 71.43 70.92 72.99 70.42 70.42 72.46 70.42
276 | 66 73.53 72.99 74.63 72.46 72.46 74.07 72.99
277 | 67 75.19 75.19 75.76 74.63 75.19 76.92 75.19
278 | 68 76.34 76.92 76.92 76.34 76.34 78.74 76.34
279 | 69 78.13 78.13 78.74 78.13 78.13 80.00 78.13
280 | 70 80.00 80.00 80.00 80.00 80.00 81.97 80.00
281 | Pal Hun Pri Sha Mage Lock Dru
282 |
283 | **************************************************
284 | ** 2.4.0 Spirit-Based Mana Regeneration Formula **
285 | **************************************************
286 | The new formula formula in 2.4:
287 |
288 | ManaRegen(SPI, INT, LEVEL) = (0.001 + SPI * BASE_REGEN[LEVEL] * (INT^0.5)) * 5
289 |
290 | BASE_REGEN[LEVEL]=
291 | 1 0.034965
292 | 2 0.034191
293 | 3 0.033465
294 | 4 0.032526
295 | 5 0.031661
296 | 6 0.031076
297 | 7 0.030523
298 | 8 0.029994
299 | 9 0.029307
300 | 10 0.028661
301 | 11 0.027584
302 | 12 0.026215
303 | 13 0.025381
304 | 14 0.024300
305 | 15 0.023345
306 | 16 0.022748
307 | 17 0.021958
308 | 18 0.021386
309 | 19 0.020790
310 | 20 0.020121
311 | 21 0.019733
312 | 22 0.019155
313 | 23 0.018819
314 | 24 0.018316
315 | 25 0.017936
316 | 26 0.017576
317 | 27 0.017201
318 | 28 0.016919
319 | 29 0.016581
320 | 30 0.016233
321 | 31 0.015994
322 | 32 0.015707
323 | 33 0.015464
324 | 34 0.015204
325 | 35 0.014956
326 | 36 0.014744
327 | 37 0.014495
328 | 38 0.014302
329 | 39 0.014094
330 | 40 0.013895
331 | 41 0.013724
332 | 42 0.013522
333 | 43 0.013363
334 | 44 0.013175
335 | 45 0.012996
336 | 46 0.012853
337 | 47 0.012687
338 | 48 0.012539
339 | 49 0.012384
340 | 50 0.012233
341 | 51 0.012113
342 | 52 0.011973
343 | 53 0.011859
344 | 54 0.011714
345 | 55 0.011575
346 | 56 0.011473
347 | 57 0.011342
348 | 58 0.011245
349 | 59 0.011110
350 | 60 0.010999
351 | 61 0.010700
352 | 62 0.010522
353 | 63 0.010290
354 | 64 0.010119
355 | 65 0.009968
356 | 66 0.009808
357 | 67 0.009651
358 | 68 0.009553
359 | 69 0.009445
360 | 70 0.009327
361 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 |
294 | Copyright (C)
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | , 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
--------------------------------------------------------------------------------
/locales/enUS.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | Name: RatingBuster enUS locale
3 | Translated by:
4 | - raethkcj
5 | ]]
6 |
7 | local _, addon = ...
8 | addon.tocversion = select(4, GetBuildInfo())
9 |
10 | ---@class RatingBusterLocale
11 | ---@field numberPatterns table
12 | ---@field exclusions table
13 | ---@field separators table
14 | ---@field statPatterns { [Stat]: string[] }
15 | ---@field [string] string
16 |
17 | ---@class RatingBusterDefaultLocale : RatingBusterLocale
18 | ---@field [string] string|true
19 |
20 | ---@type RatingBusterDefaultLocale
21 | local L = LibStub("AceLocale-3.0"):NewLocale("RatingBuster", "enUS", true)
22 | addon.S = {}
23 | local S = addon.S
24 | L["RatingBuster Options"] = true
25 | local StatLogic = LibStub("StatLogic")
26 | ---------------------------
27 | -- Slash Command Options --
28 | ---------------------------
29 | -- /rb help
30 | L["Help"] = true
31 | L["Show this help message"] = true
32 | -- /rb win
33 | L["Options Window"] = true
34 | L["Shows the Options Window"] = true
35 | -- /rb statmod
36 | L["Enable Stat Mods"] = true
37 | L["Enable support for Stat Mods"] = true
38 | L["Enable Avoidance Diminishing Returns"] = true
39 | L["Dodge, Parry, Miss Avoidance values will be calculated using the avoidance deminishing return formula with your current stats"] = true
40 |
41 | -- /rb itemid
42 | L["Show ItemID"] = true
43 | L["Show the ItemID in tooltips"] = true
44 | -- /rb itemlevel
45 | L["Show ItemLevel"] = true
46 | L["Show the ItemLevel in tooltips"] = true
47 | -- /rb usereqlv
48 | L["Use required level"] = true
49 | L["Calculate using the required level if you are below the required level"] = true
50 | -- /rb setlevel
51 | L["Set level"] = true
52 | L["Set the level used in calculations (0 = your level)"] = true
53 | -- /rb color
54 | L["Change text color"] = true
55 | L["Changes the color of added text"] = true
56 | L["Change number color"] = true
57 | -- /rb rating
58 | L["Rating"] = true
59 | L["Options for Rating display"] = true
60 | -- /rb rating show
61 | L["Show Rating conversions"] = true
62 | L["Show Rating conversions in tooltips"] = true
63 | L["Enable integration with Blizzard Reforging UI"] = true
64 | -- /rb rating spell
65 | L["Show Spell Hit/Haste"] = true
66 | L["Show Spell Hit/Haste from Hit/Haste Rating"] = true
67 | -- /rb rating physical
68 | L["Show Physical Hit/Haste"] = true
69 | L["Show Physical Hit/Haste from Hit/Haste Rating"] = true
70 | -- /rb rating detail
71 | L["Show detailed conversions text"] = true
72 | L["Show detailed text for Resilience and Expertise conversions"] = true
73 | -- /rb rating def
74 | L["Defense breakdown"] = true
75 | L["Convert Defense into Crit Avoidance, Hit Avoidance, Dodge, Parry and Block"] = true
76 | -- /rb rating wpn
77 | L["Weapon Skill breakdown"] = true
78 | L["Convert Weapon Skill into Crit, Hit, Dodge Reduction, Parry Reduction and Block Reduction"] = true
79 | -- /rb rating exp -- 2.3.0
80 | L["Expertise breakdown"] = true
81 | L["Convert Expertise into Dodge Reduction and Parry Reduction"] = true
82 |
83 | -- /rb stat
84 | L["Stat Breakdown"] = true
85 | L["Changes the display of base stats"] = true
86 | -- /rb stat show
87 | L["Show base stat conversions"] = true
88 | L["Show base stat conversions in tooltips"] = true
89 | L["Changes the display of %s"] = true
90 | ---------------------------------------------------------------------------
91 | -- /rb sum
92 | L["Stat Summary"] = true
93 | L["Options for stat summary"] = true
94 | L["Sum %s"] = true
95 | -- /rb sum show
96 | L["Show stat summary"] = true
97 | L["Show stat summary in tooltips"] = true
98 | -- /rb sum ignore
99 | L["Ignore settings"] = true
100 | L["Ignore stuff when calculating the stat summary"] = true
101 | -- /rb sum ignore unused
102 | L["Ignore unused item types"] = true
103 | L["Show stat summary only for highest level armor type and items you can use with uncommon quality and up"] = true
104 | L["Ignore non-primary stat"] = true
105 | L["Show stat summary only for items with your specialization's primary stat"] = true
106 | -- /rb sum ignore equipped
107 | L["Ignore equipped items"] = true
108 | L["Hide stat summary for equipped items"] = true
109 | -- /rb sum ignore enchant
110 | L["Ignore enchants"] = true
111 | L["Ignore enchants on items when calculating the stat summary"] = true
112 | -- /rb sum ignore gem
113 | L["Ignore gems"] = true
114 | L["Ignore gems on items when calculating the stat summary"] = true
115 | L["Ignore extra sockets"] = true
116 | L["Ignore sockets from professions or consumable items when calculating the stat summary"] = true
117 | -- /rb sum diffstyle
118 | L["Display style for diff value"] = true
119 | L["Display diff values in the main tooltip or only in compare tooltips"] = true
120 | L["Hide Blizzard Item Comparisons"] = true
121 | L["Disable Blizzard stat change summary when using the built-in comparison tooltip"] = true
122 | -- /rb sum space
123 | L["Add empty line"] = true
124 | L["Add a empty line before or after stat summary"] = true
125 | -- /rb sum space before
126 | L["Add before summary"] = true
127 | L["Add a empty line before stat summary"] = true
128 | -- /rb sum space after
129 | L["Add after summary"] = true
130 | L["Add a empty line after stat summary"] = true
131 | -- /rb sum icon
132 | L["Show icon"] = true
133 | L["Show the sigma icon before stat summary"] = true
134 | -- /rb sum title
135 | L["Show title text"] = true
136 | L["Show the title text before stat summary"] = true
137 | L["Show profile name"] = true
138 | L["Show profile name before stat summary"] = true
139 | -- /rb sum showzerostat
140 | L["Show zero value stats"] = true
141 | L["Show zero value stats in summary for consistancy"] = true
142 | -- /rb sum calcsum
143 | L["Calculate stat sum"] = true
144 | L["Calculate the total stats for the item"] = true
145 | -- /rb sum calcdiff
146 | L["Calculate stat diff"] = true
147 | L["Calculate the stat difference for the item and equipped items"] = true
148 | -- /rb sum sort
149 | L["Sort StatSummary alphabetically"] = true
150 | L["Enable to sort StatSummary alphabetically, disable to sort according to stat type(basic, physical, spell, tank)"] = true
151 | -- /rb sum avoidhasblock
152 | L["Include block chance in Avoidance summary"] = true
153 | L["Enable to include block chance in Avoidance summary, Disable for only dodge, parry, miss"] = true
154 | -- /rb sum basic
155 | L["Stat - Basic"] = true
156 | L["Choose basic stats for summary"] = true
157 | -- /rb sum physical
158 | L["Stat - Physical"] = true
159 | L["Choose physical damage stats for summary"] = true
160 | L["Ranged"] = true
161 | L["Weapon"] = true
162 | -- /rb sum spell
163 | L["Stat - Spell"] = true
164 | L["Choose spell damage and healing stats for summary"] = true
165 | -- /rb sum tank
166 | L["Stat - Tank"] = true
167 | L["Choose tank stats for summary"] = true
168 | -- /rb sum stat hp
169 | L["Health <- Health, Stamina"] = true
170 | -- /rb sum stat mp
171 | L["Mana <- Mana, Intellect"] = true
172 | -- /rb sum stat ap
173 | L["Attack Power <- Attack Power, Strength, Agility"] = true
174 | -- /rb sum stat rap
175 | L["Ranged Attack Power <- Ranged Attack Power, Intellect, Attack Power, Strength, Agility"] = true
176 | -- /rb sum stat dmg
177 | L["Spell Damage <- Spell Damage, Intellect, Spirit, Stamina"] = true
178 | -- /rb sum stat dmgholy
179 | L["Holy Spell Damage <- Holy Spell Damage, Spell Damage, Intellect, Spirit"] = true
180 | -- /rb sum stat dmgarcane
181 | L["Arcane Spell Damage <- Arcane Spell Damage, Spell Damage, Intellect"] = true
182 | -- /rb sum stat dmgfire
183 | L["Fire Spell Damage <- Fire Spell Damage, Spell Damage, Intellect, Stamina"] = true
184 | -- /rb sum stat dmgnature
185 | L["Nature Spell Damage <- Nature Spell Damage, Spell Damage, Intellect"] = true
186 | -- /rb sum stat dmgfrost
187 | L["Frost Spell Damage <- Frost Spell Damage, Spell Damage, Intellect"] = true
188 | -- /rb sum stat dmgshadow
189 | L["Shadow Spell Damage <- Shadow Spell Damage, Spell Damage, Intellect, Spirit, Stamina"] = true
190 | -- /rb sum stat heal
191 | L["Healing <- Healing, Intellect, Spirit, Agility, Strength"] = true
192 | -- /rb sum stat hit
193 | L["Hit Chance <- Hit Rating, Weapon Skill Rating"] = true
194 | -- /rb sum stat crit
195 | L["Crit Chance <- Crit Rating, Agility, Weapon Skill Rating"] = true
196 | -- /rb sum stat haste
197 | L["Haste <- Haste Rating"] = true
198 | L["Ranged Hit Chance <- Hit Rating, Weapon Skill Rating, Ranged Hit Rating"] = true
199 | -- /rb sum physical rangedcrit
200 | L["Ranged Crit Chance <- Crit Rating, Agility, Weapon Skill Rating, Ranged Crit Rating"] = true
201 | -- /rb sum physical rangedhaste
202 | L["Ranged Haste <- Haste Rating, Ranged Haste Rating"] = true
203 |
204 | -- /rb sum stat critspell
205 | L["Spell Crit Chance <- Spell Crit Rating, Intellect"] = true
206 | -- /rb sum stat hitspell
207 | L["Spell Hit Chance <- Spell Hit Rating"] = true
208 | -- /rb sum stat hastespell
209 | L["Spell Haste <- Spell Haste Rating"] = true
210 | -- /rb sum stat mp5
211 | L["Mana Regen <- Mana Regen, Spirit"] = true
212 | -- /rb sum stat mp5nc
213 | L["Mana Regen while not casting <- Spirit"] = true
214 | -- /rb sum stat hp5
215 | L["Health Regen <- Health Regen"] = true
216 | -- /rb sum stat hp5oc
217 | L["Health Regen when out of combat <- Spirit"] = true
218 | -- /rb sum stat armor
219 | L["Armor <- Armor from items, Armor from bonuses, Agility, Intellect"] = true
220 | -- /rb sum stat blockvalue
221 | L["Block Value <- Block Value, Strength"] = true
222 | -- /rb sum stat dodge
223 | L["Dodge Chance <- Dodge Rating, Agility, Defense Rating"] = true
224 | -- /rb sum stat parry
225 | L["Parry Chance <- Parry Rating, Defense Rating"] = true
226 | -- /rb sum stat block
227 | L["Block Chance <- Block Rating, Defense Rating"] = true
228 | -- /rb sum stat avoidhit
229 | L["Hit Avoidance <- Defense Rating"] = true
230 | -- /rb sum stat avoidcrit
231 | L["Crit Avoidance <- Defense Rating, Resilience"] = true
232 | -- /rb sum stat Reductiondodge
233 | L["Dodge Reduction <- Expertise, Weapon Skill Rating"] = true -- 2.3.0
234 | -- /rb sum stat Reductionparry
235 | L["Parry Reduction <- Expertise, Weapon Skill Rating"] = true -- 2.3.0
236 |
237 | -- /rb sum statcomp def
238 | L["Defense <- Defense Rating"] = true
239 | -- /rb sum statcomp wpn
240 | L["Weapon Skill <- Weapon Skill Rating"] = true
241 | -- /rb sum statcomp exp -- 2.3.0
242 | L["Expertise <- Expertise Rating"] = true
243 | -- /rb sum statcomp avoid
244 | L["Avoidance <- Dodge, Parry, MobMiss, Block(Optional)"] = true
245 | -- /rb sum gem
246 | L["Gems"] = true
247 | L["Auto fill empty gem slots"] = true
248 | L["ItemID or Link of the gem you would like to auto fill"] = true
249 | L[""] = true
250 | L["%s is now set to %s"] = true
251 | L["Queried server for Gem: %s. Try again in 5 secs."] = true
252 |
253 | -----------------------
254 | -- Item Level and ID --
255 | -----------------------
256 | L["ItemLevel: "] = true
257 | L["ItemID: "] = true
258 |
259 | -------------------
260 | -- Always Buffed --
261 | -------------------
262 | L["Enables RatingBuster to calculate selected buff effects even if you don't really have them"] = true
263 | L["$class Self Buffs"] = true -- $class will be replaced with localized player class
264 | L["Raid Buffs"] = true
265 | L["Stat Multiplier"] = true
266 | L["Attack Power Multiplier"] = true
267 | L["Reduced Physical Damage Taken"] = true
268 |
269 | L["Swap Profiles"] = true
270 | L["Swap Profile Keybinding"] = true
271 | L["Use a keybind to swap between Primary and Secondary Profiles.\n\nIf \"Enable spec profiles\" is enabled, will use the Primary and Secondary Talents profiles, and will preview items with that spec's talents, glyphs, and passives.\n\nYou can re-use an existing keybind! It will only be used for RatingBuster when an item tooltip is shown."] = true
272 | L["Primary Profile"] = true
273 | L["Select the primary profile for use with the swap profile keybind. If spec profiles are enabled, this will instead use the Primary Talents profile."] = true
274 | L["Secondary Profile"] = true
275 | L["Select the secondary profile for use with the swap profile keybind. If spec profiles are enabled, this will instead use the Secondary Talents profile."] = true
276 |
277 | -- These patterns are used to reposition stat breakdowns.
278 | -- They are not mandatory; if not present for a given stat,
279 | -- the breakdown will simply appear after the number.
280 | -- They will only ever position the breakdown further after the number; not before it.
281 | -- E.g. default positioning:
282 | -- "Strength +5 (10 AP)"
283 | -- "+5 (10 AP) Strength"
284 | -- If "strength" is added in statPatterns:
285 | -- "Strength +5 (10 AP)"
286 | -- "+5 Strength (10 AP)"
287 | -- The strings are lowerecased and passed into string.find,
288 | -- so you should escape the magic characters ^$()%.[]*+-? with a %
289 | -- Use /rb debug to help with debugging stat patterns
290 | L["statPatterns"] = {
291 | [StatLogic.Stats.Strength] = { SPELL_STAT1_NAME:lower() },
292 | [StatLogic.Stats.Agility] = { SPELL_STAT2_NAME:lower() },
293 | [StatLogic.Stats.Stamina] = { SPELL_STAT3_NAME:lower() },
294 | [StatLogic.Stats.Intellect] = { SPELL_STAT4_NAME:lower() },
295 | [StatLogic.Stats.Spirit] = { SPELL_STAT5_NAME:lower() },
296 | [StatLogic.Stats.DefenseRating] = { "defense rating" },
297 | [StatLogic.Stats.Defense] = { DEFENSE:lower() },
298 | [StatLogic.Stats.DodgeRating] = { "dodge rating", "dodge" },
299 | [StatLogic.Stats.BlockRating] = { "block rating", "block" },
300 | [StatLogic.Stats.ParryRating] = { "parry rating", "parry" },
301 |
302 | [StatLogic.Stats.SpellPower] = { "spell power" },
303 | [StatLogic.Stats.GenericAttackPower] = { "attack power" },
304 |
305 | [StatLogic.Stats.MeleeCritRating] = { "critical strike", "critical hit rating", "critical rating", "crit rating", "crit" },
306 | [StatLogic.Stats.RangedCritRating] = { "ranged critical strike", "ranged critical hit rating", "ranged critical rating", "ranged crit rating" },
307 | [StatLogic.Stats.SpellCritRating] = { "spell critical strike rating", "spell critical hit rating", "spell critical rating", "spell crit rating", "spell critical" },
308 | [StatLogic.Stats.CritRating] = { "critical strike", "critical hit rating", "critical rating", "crit rating", "crit" },
309 |
310 | [StatLogic.Stats.MeleeHitRating] = { "hit rating", "hit" },
311 | [StatLogic.Stats.RangedHitRating] = { "ranged hit rating" },
312 | [StatLogic.Stats.SpellHitRating] = { "spell hit rating" },
313 | [StatLogic.Stats.HitRating] = { "hit rating", "hit" },
314 |
315 | [StatLogic.Stats.ResilienceRating] = { "resilience" },
316 | [StatLogic.Stats.PvpPowerRating] = { ITEM_MOD_PVP_POWER_SHORT:lower() },
317 |
318 | [StatLogic.Stats.MeleeHasteRating] = { "haste rating", "haste" },
319 | [StatLogic.Stats.RangedHasteRating] = { "ranged haste rating" },
320 | [StatLogic.Stats.SpellHasteRating] = { "spell haste rating" },
321 | [StatLogic.Stats.HasteRating] = { "haste rating", "haste" },
322 |
323 | [StatLogic.Stats.ExpertiseRating] = { "expertise" },
324 |
325 | [StatLogic.Stats.AllStats] = { SPELL_STATALL:lower() },
326 |
327 | [StatLogic.Stats.ArmorPenetrationRating] = { "armor penetration" },
328 | [StatLogic.Stats.MasteryRating] = { "mastery rating", "mastery" },
329 | [StatLogic.Stats.Armor] = { ARMOR:lower() },
330 | }
331 | -------------------------
332 | -- Added info patterns --
333 | -------------------------
334 | -- Controls the order of values and stats in stat breakdowns
335 | -- "%s %s" -> "+1.34% Crit"
336 | -- "%2$s $1$s" -> "Crit +1.34%"
337 | L["StatBreakdownOrder"] = "%s %s"
338 | L["numberSuffix"] = ""
339 | L["Show %s"] = SHOW.." %s"
340 | L["Show Modified %s"] = "Show Modified %s"
341 | -- for hit rating showing both physical and spell conversions
342 | -- (+1.21%, S+0.98%)
343 | -- (+1.21%, +0.98% S)
344 | L["Spell"] = "Spell"
345 |
346 | -- Basic Attributes
347 | L[StatLogic.Stats.Strength] = SPELL_STAT1_NAME
348 | L[StatLogic.Stats.Agility] = SPELL_STAT2_NAME
349 | L[StatLogic.Stats.Stamina] = SPELL_STAT3_NAME
350 | L[StatLogic.Stats.Intellect] = SPELL_STAT4_NAME
351 | L[StatLogic.Stats.Spirit] = SPELL_STAT5_NAME
352 | L[StatLogic.Stats.Mastery] = STAT_MASTERY
353 | L[StatLogic.Stats.MasteryEffect] = SPELL_LASTING_EFFECT:format(STAT_MASTERY)
354 | L[StatLogic.Stats.MasteryRating] = STAT_MASTERY.." "..RATING
355 |
356 | -- Resources
357 | L[StatLogic.Stats.Health] = HEALTH
358 | S[StatLogic.Stats.Health] = "HP"
359 | L[StatLogic.Stats.Mana] = MANA
360 | S[StatLogic.Stats.Mana] = "MP"
361 | L[StatLogic.Stats.ManaRegen] = "Mana Regen"
362 | S[StatLogic.Stats.ManaRegen] = "MP5"
363 |
364 | local ManaRegenOutOfCombat = "Mana Regen (Out of Combat)"
365 | L[StatLogic.Stats.ManaRegenOutOfCombat] = ManaRegenOutOfCombat
366 | if addon.tocversion < 40000 then
367 | L[StatLogic.Stats.ManaRegenNotCasting] = "Mana Regen (Not Casting)"
368 | else
369 | L[StatLogic.Stats.ManaRegenNotCasting] = ManaRegenOutOfCombat
370 | end
371 | S[StatLogic.Stats.ManaRegenNotCasting] = "MP5(NC)"
372 |
373 | L[StatLogic.Stats.HealthRegen] = "Health Regen"
374 | S[StatLogic.Stats.HealthRegen] = "HP5"
375 | L[StatLogic.Stats.HealthRegenOutOfCombat] = "Health Regen (Out of Combat)"
376 | S[StatLogic.Stats.HealthRegenOutOfCombat] = "HP5(NC)"
377 |
378 | -- Physical Stats
379 | L[StatLogic.Stats.AttackPower] = ATTACK_POWER_TOOLTIP
380 | S[StatLogic.Stats.AttackPower] = "AP"
381 | L[StatLogic.Stats.FeralAttackPower] = "Feral "..ATTACK_POWER_TOOLTIP
382 | L[StatLogic.Stats.IgnoreArmor] = "Ignore Armor"
383 | L[StatLogic.Stats.ArmorPenetration] = "Armor Penetration"
384 | L[StatLogic.Stats.ArmorPenetrationRating] = ITEM_MOD_ARMOR_PENETRATION_RATING_SHORT
385 |
386 | -- Weapon Stats
387 | L[StatLogic.Stats.AverageWeaponDamage] = "Average Damage"
388 | L[StatLogic.Stats.WeaponDPS] = "Damage Per Second"
389 |
390 | L[StatLogic.Stats.Hit] = STAT_HIT_CHANCE
391 | L[StatLogic.Stats.Crit] = MELEE_CRIT_CHANCE
392 | L[StatLogic.Stats.Haste] = STAT_HASTE
393 |
394 | L[StatLogic.Stats.HitRating] = ITEM_MOD_HIT_RATING_SHORT
395 | L[StatLogic.Stats.CritRating] = ITEM_MOD_CRIT_RATING_SHORT
396 | L[StatLogic.Stats.HasteRating] = ITEM_MOD_HASTE_RATING_SHORT
397 |
398 | -- Melee Stats
399 | L[StatLogic.Stats.MeleeHit] = STAT_HIT_CHANCE
400 | L[StatLogic.Stats.MeleeHitRating] = COMBAT_RATING_NAME6 -- COMBAT_RATING_NAME6 = "Hit Rating"
401 | L[StatLogic.Stats.MeleeCrit] = MELEE_CRIT_CHANCE -- MELEE_CRIT_CHANCE = "Crit Chance"
402 | S[StatLogic.Stats.MeleeCrit] = "Crit"
403 | L[StatLogic.Stats.MeleeCritRating] = COMBAT_RATING_NAME9 -- COMBAT_RATING_NAME9 = "Crit Rating"
404 | L[StatLogic.Stats.MeleeHaste] = STAT_HASTE
405 | L[StatLogic.Stats.MeleeHasteRating] = STAT_HASTE.." "..RATING
406 |
407 | L[StatLogic.Stats.WeaponSkill] = "Weapon "..SKILL
408 | L[StatLogic.Stats.Expertise] = STAT_EXPERTISE
409 | L[StatLogic.Stats.ExpertiseRating] = STAT_EXPERTISE.." "..RATING
410 | L[StatLogic.Stats.DodgeReduction] = DODGE.." Reduction"
411 | S[StatLogic.Stats.DodgeReduction] = "to be Dodged"
412 | L[StatLogic.Stats.ParryReduction] = PARRY.." Reduction"
413 | S[StatLogic.Stats.ParryReduction] = "to be Parried"
414 |
415 | -- Ranged Stats
416 | L[StatLogic.Stats.RangedAttackPower] = RANGED_ATTACK_POWER
417 | S[StatLogic.Stats.RangedAttackPower] = "RAP"
418 | L[StatLogic.Stats.RangedHit] = PLAYERSTAT_RANGED_COMBAT.." "..STAT_HIT_CHANCE
419 | L[StatLogic.Stats.RangedHitRating] = PLAYERSTAT_RANGED_COMBAT.." "..COMBAT_RATING_NAME6 -- PLAYERSTAT_RANGED_COMBAT = "Ranged"
420 | L[StatLogic.Stats.RangedCrit] = PLAYERSTAT_RANGED_COMBAT.." "..MELEE_CRIT_CHANCE
421 | L[StatLogic.Stats.RangedCritRating] = PLAYERSTAT_RANGED_COMBAT.." "..COMBAT_RATING_NAME9
422 | L[StatLogic.Stats.RangedHaste] = PLAYERSTAT_RANGED_COMBAT.." "..STAT_HASTE
423 | L[StatLogic.Stats.RangedHasteRating] = PLAYERSTAT_RANGED_COMBAT.." "..STAT_HASTE.." "..RATING
424 |
425 | -- Spell Stats
426 | L[StatLogic.Stats.SpellPower] = STAT_SPELLPOWER
427 | L[StatLogic.Stats.SpellDamage] = STAT_SPELLDAMAGE
428 | S[StatLogic.Stats.SpellDamage] = "Spell Dmg"
429 | L[StatLogic.Stats.HealingPower] = "Healing" -- STAT_SPELL_HEALING
430 | S[StatLogic.Stats.HealingPower] = "Heal"
431 | L[StatLogic.Stats.SpellPenetration] = PLAYERSTAT_SPELL_COMBAT.." "..SPELL_PENETRATION
432 |
433 | L[StatLogic.Stats.HolyDamage] = SPELL_SCHOOL1_CAP.." "..DAMAGE
434 | L[StatLogic.Stats.FireDamage] = SPELL_SCHOOL2_CAP.." "..DAMAGE
435 | L[StatLogic.Stats.NatureDamage] = SPELL_SCHOOL3_CAP.." "..DAMAGE
436 | L[StatLogic.Stats.FrostDamage] = SPELL_SCHOOL4_CAP.." "..DAMAGE
437 | L[StatLogic.Stats.ShadowDamage] = SPELL_SCHOOL5_CAP.." "..DAMAGE
438 | L[StatLogic.Stats.ArcaneDamage] = SPELL_SCHOOL6_CAP.." "..DAMAGE
439 |
440 | L[StatLogic.Stats.SpellHit] = PLAYERSTAT_SPELL_COMBAT.." "..STAT_HIT_CHANCE
441 | S[StatLogic.Stats.SpellHit] = "Spell Hit"
442 | L[StatLogic.Stats.SpellHitRating] = PLAYERSTAT_SPELL_COMBAT.." "..COMBAT_RATING_NAME6 -- PLAYERSTAT_SPELL_COMBAT = "Spell"
443 | L[StatLogic.Stats.SpellCrit] = PLAYERSTAT_SPELL_COMBAT.." "..MELEE_CRIT_CHANCE
444 | S[StatLogic.Stats.SpellCrit] = "Spell Crit"
445 | L[StatLogic.Stats.SpellCritRating] = PLAYERSTAT_SPELL_COMBAT.." "..COMBAT_RATING_NAME9
446 | L[StatLogic.Stats.SpellHaste] = PLAYERSTAT_SPELL_COMBAT.." "..STAT_HASTE
447 | L[StatLogic.Stats.SpellHasteRating] = PLAYERSTAT_SPELL_COMBAT.." "..STAT_HASTE.." "..RATING
448 |
449 | -- Tank Stats
450 | L[StatLogic.Stats.Armor] = ARMOR
451 | L[StatLogic.Stats.BonusArmor] = ARMOR
452 |
453 | L[StatLogic.Stats.Avoidance] = STAT_AVOIDANCE
454 | L[StatLogic.Stats.Dodge] = DODGE
455 | S[StatLogic.Stats.Dodge] = "Dodge"
456 | L[StatLogic.Stats.DodgeRating] = COMBAT_RATING_NAME3 -- COMBAT_RATING_NAME3 = "Dodge Rating"
457 | L[StatLogic.Stats.Parry] = PARRY
458 | S[StatLogic.Stats.Parry] = "Parry"
459 | L[StatLogic.Stats.ParryRating] = COMBAT_RATING_NAME4 -- COMBAT_RATING_NAME4 = "Parry Rating"
460 | L[StatLogic.Stats.BlockChance] = BLOCK_CHANCE
461 | L[StatLogic.Stats.BlockRating] = COMBAT_RATING_NAME5 -- COMBAT_RATING_NAME5 = "Block Rating"
462 | L[StatLogic.Stats.BlockValue] = "Block Value"
463 | S[StatLogic.Stats.BlockValue] = "Block"
464 | L[StatLogic.Stats.Miss] = MISS
465 |
466 | L[StatLogic.Stats.Defense] = DEFENSE
467 | L[StatLogic.Stats.DefenseRating] = COMBAT_RATING_NAME2.." "..RATING -- COMBAT_RATING_NAME2 = "Defense Rating"
468 | L[StatLogic.Stats.CritAvoidance] = CRIT_ABBR.." "..STAT_AVOIDANCE
469 | S[StatLogic.Stats.CritAvoidance] = "Crit Avoid"
470 |
471 | L[StatLogic.Stats.Resilience] = COMBAT_RATING_NAME15
472 | L[StatLogic.Stats.ResilienceRating] = COMBAT_RATING_NAME15 .. " " .. RATING
473 | L[StatLogic.Stats.CritDamageReduction] = "Crit Damage Reduction"
474 | S[StatLogic.Stats.CritDamageReduction] = "Crit Dmg Reduction"
475 | L[StatLogic.Stats.PvPDamageReduction] = "PvP Damage Reduction"
476 | L[StatLogic.Stats.PvpPower] = ITEM_MOD_PVP_POWER_SHORT
477 | L[StatLogic.Stats.PvpPowerRating] = ITEM_MOD_PVP_POWER_SHORT .. " " .. RATING
478 |
479 | L[StatLogic.Stats.FireResistance] = RESISTANCE2_NAME
480 | L[StatLogic.Stats.NatureResistance] = RESISTANCE3_NAME
481 | L[StatLogic.Stats.FrostResistance] = RESISTANCE4_NAME
482 | L[StatLogic.Stats.ShadowResistance] = RESISTANCE5_NAME
483 | L[StatLogic.Stats.ArcaneResistance] = RESISTANCE6_NAME
--------------------------------------------------------------------------------