From 34b48be542b0a7dcd64a22fbef89ea0039980fe9 Mon Sep 17 00:00:00 2001 From: Andrew6810 <16847730+andrew6180@users.noreply.github.com> Date: Sun, 23 Oct 2022 21:31:42 -0700 Subject: [PATCH] init --- README.md | 4 +- RatingBuster/About RatingBuster.txt | 1125 ++ RatingBuster/Changelog-RatingBuster-r295.txt | 79 + RatingBuster/GPL.txt | 339 + RatingBuster/RB-Example.jpg | Bin 0 -> 154184 bytes RatingBuster/RatingBuster-Locale-deDE.lua | 726 + RatingBuster/RatingBuster-Locale-enUS.lua | 726 + RatingBuster/RatingBuster-Locale-esES.lua | 699 + RatingBuster/RatingBuster-Locale-frFR.lua | 660 + RatingBuster/RatingBuster-Locale-koKR.lua | 728 + RatingBuster/RatingBuster-Locale-ruRU.lua | 789 + RatingBuster/RatingBuster-Locale-zhCN.lua | 695 + RatingBuster/RatingBuster-Locale-zhTW.lua | 713 + RatingBuster/RatingBuster.lua | 4561 ++++++ RatingBuster/RatingBuster.toc | 39 + RatingBuster/UTF8/utf8.lua | 327 + RatingBuster/UTF8/utf8data.lua | 1860 +++ RatingBuster/embeds.xml | 19 + RatingBuster/images/Sigma.blp | Bin 0 -> 2564 bytes .../libs/AceAddon-3.0/AceAddon-3.0.lua | 642 + .../libs/AceAddon-3.0/AceAddon-3.0.xml | 4 + .../libs/AceConfig-3.0/AceConfig-3.0.lua | 57 + .../libs/AceConfig-3.0/AceConfig-3.0.xml | 8 + .../AceConfigCmd-3.0/AceConfigCmd-3.0.lua | 787 + .../AceConfigCmd-3.0/AceConfigCmd-3.0.xml | 4 + .../AceConfigDialog-3.0.lua | 1901 +++ .../AceConfigDialog-3.0.xml | 4 + .../AceConfigRegistry-3.0.lua | 346 + .../AceConfigRegistry-3.0.xml | 4 + .../libs/AceConsole-3.0/AceConsole-3.0.lua | 250 + .../libs/AceConsole-3.0/AceConsole-3.0.xml | 4 + RatingBuster/libs/AceDB-3.0/AceDB-3.0.lua | 728 + RatingBuster/libs/AceDB-3.0/AceDB-3.0.xml | 4 + .../AceDBOptions-3.0/AceDBOptions-3.0.lua | 420 + .../AceDBOptions-3.0/AceDBOptions-3.0.xml | 4 + .../libs/AceEvent-3.0/AceEvent-3.0.lua | 126 + .../libs/AceEvent-3.0/AceEvent-3.0.xml | 4 + RatingBuster/libs/AceGUI-3.0/AceGUI-3.0.lua | 805 + RatingBuster/libs/AceGUI-3.0/AceGUI-3.0.xml | 28 + .../AceGUIContainer-BlizOptionsGroup.lua | 133 + .../widgets/AceGUIContainer-DropDownGroup.lua | 157 + .../widgets/AceGUIContainer-Frame.lua | 298 + .../widgets/AceGUIContainer-InlineGroup.lua | 102 + .../widgets/AceGUIContainer-ScrollFrame.lua | 203 + .../widgets/AceGUIContainer-SimpleGroup.lua | 69 + .../widgets/AceGUIContainer-TabGroup.lua | 348 + .../widgets/AceGUIContainer-TreeGroup.lua | 670 + .../widgets/AceGUIContainer-Window.lua | 331 + .../widgets/AceGUIWidget-Button.lua | 92 + .../widgets/AceGUIWidget-CheckBox.lua | 289 + .../widgets/AceGUIWidget-ColorPicker.lua | 186 + .../widgets/AceGUIWidget-DropDown-Items.lua | 465 + .../widgets/AceGUIWidget-DropDown.lua | 707 + .../widgets/AceGUIWidget-EditBox.lua | 232 + .../widgets/AceGUIWidget-Heading.lua | 78 + .../AceGUI-3.0/widgets/AceGUIWidget-Icon.lua | 144 + .../widgets/AceGUIWidget-InteractiveLabel.lua | 101 + .../widgets/AceGUIWidget-Keybinding.lua | 230 + .../AceGUI-3.0/widgets/AceGUIWidget-Label.lua | 162 + .../widgets/AceGUIWidget-MultiLineEditBox.lua | 308 + .../widgets/AceGUIWidget-Slider.lua | 281 + .../libs/AceLocale-3.0/AceLocale-3.0.lua | 136 + .../libs/AceLocale-3.0/AceLocale-3.0.xml | 4 + .../CallbackHandler-1.0.lua | 240 + .../CallbackHandler-1.0.xml | 4 + .../LibBabble-Inventory-3.0/LibBabble-3.0.lua | 292 + .../LibBabble-Inventory-3.0.lua | 1330 ++ .../LibBabble-Inventory-3.0.toc | 16 + .../libs/LibBabble-Inventory-3.0/lib.xml | 5 + .../libs/LibDualSpec-1.0/LibDualSpec-1.0.lua | 312 + .../libs/LibDualSpec-1.0/LibDualSpec-1.0.toc | 16 + RatingBuster/libs/LibDualSpec-1.0/LibStub.lua | 30 + .../LibStatLogic-1.2/LibStatLogic-1.2.lua | 12503 ++++++++++++++++ RatingBuster/libs/LibStatLogic-1.2/lib.xml | 6 + RatingBuster/libs/LibStub/LibStub.lua | 30 + RatingBuster/libs/LibStub/LibStub.toc | 13 + .../LibTipHooker-1.1/LibTipHooker-1.1.lua | 407 + RatingBuster/libs/LibTipHooker-1.1/lib.xml | 6 + 78 files changed, 41153 insertions(+), 2 deletions(-) create mode 100644 RatingBuster/About RatingBuster.txt create mode 100644 RatingBuster/Changelog-RatingBuster-r295.txt create mode 100644 RatingBuster/GPL.txt create mode 100644 RatingBuster/RB-Example.jpg create mode 100644 RatingBuster/RatingBuster-Locale-deDE.lua create mode 100644 RatingBuster/RatingBuster-Locale-enUS.lua create mode 100644 RatingBuster/RatingBuster-Locale-esES.lua create mode 100644 RatingBuster/RatingBuster-Locale-frFR.lua create mode 100644 RatingBuster/RatingBuster-Locale-koKR.lua create mode 100644 RatingBuster/RatingBuster-Locale-ruRU.lua create mode 100644 RatingBuster/RatingBuster-Locale-zhCN.lua create mode 100644 RatingBuster/RatingBuster-Locale-zhTW.lua create mode 100644 RatingBuster/RatingBuster.lua create mode 100644 RatingBuster/RatingBuster.toc create mode 100644 RatingBuster/UTF8/utf8.lua create mode 100644 RatingBuster/UTF8/utf8data.lua create mode 100644 RatingBuster/embeds.xml create mode 100644 RatingBuster/images/Sigma.blp create mode 100644 RatingBuster/libs/AceAddon-3.0/AceAddon-3.0.lua create mode 100644 RatingBuster/libs/AceAddon-3.0/AceAddon-3.0.xml create mode 100644 RatingBuster/libs/AceConfig-3.0/AceConfig-3.0.lua create mode 100644 RatingBuster/libs/AceConfig-3.0/AceConfig-3.0.xml create mode 100644 RatingBuster/libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua create mode 100644 RatingBuster/libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.xml create mode 100644 RatingBuster/libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua create mode 100644 RatingBuster/libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.xml create mode 100644 RatingBuster/libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.lua create mode 100644 RatingBuster/libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.xml create mode 100644 RatingBuster/libs/AceConsole-3.0/AceConsole-3.0.lua create mode 100644 RatingBuster/libs/AceConsole-3.0/AceConsole-3.0.xml create mode 100644 RatingBuster/libs/AceDB-3.0/AceDB-3.0.lua create mode 100644 RatingBuster/libs/AceDB-3.0/AceDB-3.0.xml create mode 100644 RatingBuster/libs/AceDBOptions-3.0/AceDBOptions-3.0.lua create mode 100644 RatingBuster/libs/AceDBOptions-3.0/AceDBOptions-3.0.xml create mode 100644 RatingBuster/libs/AceEvent-3.0/AceEvent-3.0.lua create mode 100644 RatingBuster/libs/AceEvent-3.0/AceEvent-3.0.xml create mode 100644 RatingBuster/libs/AceGUI-3.0/AceGUI-3.0.lua create mode 100644 RatingBuster/libs/AceGUI-3.0/AceGUI-3.0.xml create mode 100644 RatingBuster/libs/AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua create mode 100644 RatingBuster/libs/AceGUI-3.0/widgets/AceGUIContainer-DropDownGroup.lua create mode 100644 RatingBuster/libs/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua create mode 100644 RatingBuster/libs/AceGUI-3.0/widgets/AceGUIContainer-InlineGroup.lua create mode 100644 RatingBuster/libs/AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua create mode 100644 RatingBuster/libs/AceGUI-3.0/widgets/AceGUIContainer-SimpleGroup.lua create mode 100644 RatingBuster/libs/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua create mode 100644 RatingBuster/libs/AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua create mode 100644 RatingBuster/libs/AceGUI-3.0/widgets/AceGUIContainer-Window.lua create mode 100644 RatingBuster/libs/AceGUI-3.0/widgets/AceGUIWidget-Button.lua create mode 100644 RatingBuster/libs/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua create mode 100644 RatingBuster/libs/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua create mode 100644 RatingBuster/libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua create mode 100644 RatingBuster/libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua create mode 100644 RatingBuster/libs/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua create mode 100644 RatingBuster/libs/AceGUI-3.0/widgets/AceGUIWidget-Heading.lua create mode 100644 RatingBuster/libs/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua create mode 100644 RatingBuster/libs/AceGUI-3.0/widgets/AceGUIWidget-InteractiveLabel.lua create mode 100644 RatingBuster/libs/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua create mode 100644 RatingBuster/libs/AceGUI-3.0/widgets/AceGUIWidget-Label.lua create mode 100644 RatingBuster/libs/AceGUI-3.0/widgets/AceGUIWidget-MultiLineEditBox.lua create mode 100644 RatingBuster/libs/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua create mode 100644 RatingBuster/libs/AceLocale-3.0/AceLocale-3.0.lua create mode 100644 RatingBuster/libs/AceLocale-3.0/AceLocale-3.0.xml create mode 100644 RatingBuster/libs/CallbackHandler-1.0/CallbackHandler-1.0.lua create mode 100644 RatingBuster/libs/CallbackHandler-1.0/CallbackHandler-1.0.xml create mode 100644 RatingBuster/libs/LibBabble-Inventory-3.0/LibBabble-3.0.lua create mode 100644 RatingBuster/libs/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.lua create mode 100644 RatingBuster/libs/LibBabble-Inventory-3.0/LibBabble-Inventory-3.0.toc create mode 100644 RatingBuster/libs/LibBabble-Inventory-3.0/lib.xml create mode 100644 RatingBuster/libs/LibDualSpec-1.0/LibDualSpec-1.0.lua create mode 100644 RatingBuster/libs/LibDualSpec-1.0/LibDualSpec-1.0.toc create mode 100644 RatingBuster/libs/LibDualSpec-1.0/LibStub.lua create mode 100644 RatingBuster/libs/LibStatLogic-1.2/LibStatLogic-1.2.lua create mode 100644 RatingBuster/libs/LibStatLogic-1.2/lib.xml create mode 100644 RatingBuster/libs/LibStub/LibStub.lua create mode 100644 RatingBuster/libs/LibStub/LibStub.toc create mode 100644 RatingBuster/libs/LibTipHooker-1.1/LibTipHooker-1.1.lua create mode 100644 RatingBuster/libs/LibTipHooker-1.1/lib.xml diff --git a/README.md b/README.md index 226db33..e9a5aa8 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -# Addon Name +# Rating Buster -This is the repository for . Modified for Ascension.gg. \ No newline at end of file +This is the repository for Rating Buster. Modified for Ascension.gg. \ No newline at end of file diff --git a/RatingBuster/About RatingBuster.txt b/RatingBuster/About RatingBuster.txt new file mode 100644 index 0000000..a08008a --- /dev/null +++ b/RatingBuster/About RatingBuster.txt @@ -0,0 +1,1125 @@ +RatingBuster - A tool for item comparison + +************************ +** About RatingBuster ** +************************ + +RatingBuster started out as an addon that converts combat ratings in your tooltips into percentages, so that you have more meaningful information when comparing different items. + +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. + + +********************* +** Support Modules ** +********************* + +- RatingBuster_AlwaysBuffed: http://wow.curse.com/downloads/wow-addons/details/ratingbuster-alwaysbuffed.aspx + This addon enables RatingBuster to calculate selected buff effects even if you don't really have them. + +************** +** Features ** +************** + +- Rating Conversion: + Converts combat ratings into percentages. + +- Stat Breakdown: + Breakdown Strength, Agility, Stamina, Intellect and Spirit into base stats. + Supports talents, buffs and racials that give you extra bonuses. + Ex talent: Lunar Guidance - "Increases your spell damage and healing by 8%/16%/25% of your total Intellect." + Ex talent: Heart of the Wild - "Increases your Intellect by 4%/8%/12%/16%/20%. In addition, ......etc" + Ex: +13 Intellect (+234 Mana, +0.18% Spell Crit, +3.9 Dmg) + +- Stat Summary: + 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. + 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. + +- Item Level and Item ID: + Item Level is obtained from the WoW API, not a calculated value. + Item ID is useful for advanced users. + +- Supports talents, buffs and racials that modify your stats for all classes. + +- Fully customizable, decide what you need to see and what you don't want. + + +************************************* +** Auto fill gems in empty sockets ** +************************************* + +1. You can set the default gems for each type of empty socket using "/rabu sum gem " or using the options window. +2. To specify the gem of your choice, you will need to give RatingBuster the ItemLink or the ItemID of the gem. +3. ItemLink example: type "/rabu sum gem blue " (last char is a space) and link the gem (from your bags, AH, ItemSync or whatever), then press . +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, + for example "http://www.wowhead.com/?item=32193", 32193 is the ItemID for that gem. + Go back in wow, type "/rabu sum gem red 32193" and press . + +Note1: If you have "/rabu sum ignore gem" on, the auto fill gems won't work. +Note2: Meta gem conditions and SetBonuses work, so if you don't meet the conditions, StatSummary won't count them. +Note3: RatingBuster will only auto fill empty sockets, if the item already has some gems on it, it will remain. +Note4: Empty sockets filled by RatingBuster will keep the "Empty Socket Icon" so you can still easily tell what color socket it is. +Note5: Gem text filled by RatingBuster will be shown in gray color to differentiate from real gems. + + +********************** +** Supported Addons ** +********************** + +EquipCompare, EQCompare, tekKompare, +LinkWrangler, MultiTips, Links, +AtlasLoot, ItemMagic, Sniff, +LinkHeaven, Mirror, TooltipExchange, AtlasQuest. + +Also works with all bag mods! + + +************************ +** GUI Options Window ** +************************ + +Type /rabu win + + +******************** +** Slash Commands ** +******************** + +Use: /rabu or /ratingbuster + +/rabu : Display command help +/rabu standby : Toggle disable/enable RatingBuster in game, defaults Enable +/rabu level (0-83) : Set the level used in calculations, defaults 0 (0 = your level) +/rabu itemlevel : Toggle show/hide ItemLevel, defaults Show +/rabu itemid : Toggle show/hide ItemID, defaults Hide +/rabu usereqlv : Toggle calculate using the required level if you are below the required level, defaults Off +/rabu statmod : Toggle support for talent and buff mods, defaults On +/rabu avoidancedr : Dodge, Parry, Hit Avoidance values will be calculated using the avoidance deminishing return formula with your current stats, defaults On + +/rabu rating : Options for Rating Conversion +/rabu rating show : Toggle show/hide Rating Conversion in tooltips, defaults Show +/rabu rating def : Toggle Defense breakdown, Convert Defense into Crit Avoidance, Hit Avoidance, Dodge, Parry and Block, defaults Off +/rabu rating wpn : Toggle Weapon Skill breakdown, Convert Weapon Skill into Crit, Hit, Dodge Neglect, Parry Neglect and Block Neglect, defaults Off +/rabu rating color enable : Toggle enable/disable colored text, defaults On +/rabu rating color pick : Choose a color for the added text, defaults Light Yellow +/rabu rating spell : Show Spell Hit from Hit Rating +/rabu rating physical : Show Physical Hit from Hit Rating +/rabu rating detail : Show detailed text for Resiliance and Expertise conversions +/rabu rating exp : Convert Expertise into Dodge Neglect and Parry Neglect + +/rabu stat : Options for Stat Breakdown +/rabu stat show : Toggle show/hide Stat Breakdown in tooltips, defaults Show +/rabu stat str : Options for Strength breakdown -> AP, Block, Healing(Talent) +/rabu stat agi : Options for Agility breakdown -> Crit, Dodge, AP, RAP, Armor +/rabu stat sta : Options for Stamina breakdown -> Health, SpellDmg(Talent) +/rabu stat int : Options for Intellect breakdown -> Mana, SpellCrit, SpellDmg(Talent), Healing(Talent), MP5(Talent), RAP(Talent), Armor(Talent) +/rabu stat spi : Options for Spirit breakdown -> MP5(Talent), MP5NC, HP5, SpellDmg(Talent), Healing(Talent) + +/rabu sum : Options for Stat Summary +/rabu sum show : Toggle show/hide Stat Summary in tooltips, defaults Show +/rabu sum ignore unused : Show stat summary only for armor types you will and can use, and on items with uncommon quality and up, defaults On +/rabu sum ignore equipped : Hide stat summary for equipped items, defaults Off +/rabu sum ignore enchant : Ignore enchants on items when calculating the stat summary, defaults Off +/rabu sum ignore gem : Ignore gems on items when calculating the stat summary, defaults Off +/rabu sum diffstyle : Display diff values in the main tooltip or only in compare tooltips, defaults Main +/rabu sum space before : Add a blank line before stat summary for readability, defaults On +/rabu sum space after : Add a blank line after stat summary, defaults Off +/rabu sum icon : Show the sigma icon before summary listing, defaults On +/rabu sum title : Show the title text before summary listing, defaults On +/rabu sum showzerostat : Show zero value stats in summary for consistency, defaults Off +/rabu sum calcsum : Calculate the total stats for the item, defaults On +/rabu sum calcdiff : Calculate the stat difference for the item and equipped items, defaults On +/rabu sum sort : Enable to sort StatSummary alphabetically, disable to sort according to stat type(basic, physical, spell, tank) +/rabu sum avoidhasblock : Enable to include block chance in Avoidance summary, Disable for only dodge, parry, miss +/rabu sum basic : Choose basic stats for summary +/rabu sum physical : Choose physical stats for summary +/rabu sum spell : Choose spell stats for summary +/rabu sum tank : Choose tank stats for summary +/rabu sum gem : Auto fill gems in empty sockets + + +*********************************** +** Avoidance diminishing returns ** +*********************************** + +This includes: +1. Dodge from Dodge Rating, Defense Rating, Agility. +2. Parry from Parry Rating, Defense Rating. +3. Chance to be missed from Defense Rating. + +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. +1. DR for Dodge, Parry, Missed are calculated separately. +2. Base avoidances are not affected by DR, (Ex: Dodge from base Agility) +3. Death Knight's Parry from base Strength is affected by DR, base for parry is 5%. +4. Direct percentage gains from talents and spells(ex: Evasion) are not affected by DR. +5. c and k values depend on class but does not change with level. + +Avoidance DR formula and k, C_p, C_d constants derived by Whitetooth (hotdogee [at] gmail [dot] com) +6. The DR formula: 1 / x' = 1 / c + k / x + x' is the diminished stat before converting to IEEE754. + x is the stat before diminishing returns. + c is the cap of the stat, and changes with class. + k is is a value that changes with class. + + k C_p 1/C_p C_d 1/C_d C_m +Warrior 0.9560 47.003525 0.021275 88.129021 0.011347 16 +Paladin 0.9560 47.003525 0.021275 88.129021 0.011347 16 +Hunter 0.9880 145.560408 0.006870 145.560408 0.006870 +Rogue 0.9880 145.560408 0.006870 145.560408 0.006870 +Priest 0.9830 0 0 150.375940 0.006650 +Deathknight 0.9560 47.003525 0.021275 88.129021 0.011347 16 +Shaman 0.9880 145.560408 0.006870 145.560408 0.006870 +Mage 0.9830 0 0 150.375940 0.006650 +Warlock 0.9830 0 0 150.375940 0.006650 +Druid 0.9720 0 0 116.890707 0.008555 + + Lv80 Dodge/Agi Lv80 Agi/1%Dodge Base Agi +Warrior 0.011800 84.74576271 3.66400 +Paladin 0.016700 59.88023952 3.49430 +Hunter 0.011600 86.20689655 -4.08730 +Rogue 0.020900 47.84688995 2.09570 +Priest 0.016700 59.88023952 3.41780 +Deathknight 0.011800 84.74576271 3.66400 +Shaman 0.016700 59.88023952 2.10800 +Mage 0.017000 58.82352941 3.65870 +Warlock 0.016700 59.88023952 2.42110 +Druid 0.020900 47.84688995 5.60970 + + +************************************** +** How I derived the Rating Formula ** +************************************** + +As soon as I saw the blue post on combat ratings system, I began to think about coding this addon. +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. +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. + +1. Get more data +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. + +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)). + +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. + +After hours of work, this is what I got: +A B C D E F G H +Lv Type Rating Percentage =C/D 60base =E/F =1/G +19 crit 2 0.6753247631 2.9615380764 14 0.211538434 4.727273342 +21 crit 2 0.5714285714 3.5000000000 14 0.25 4 +22 crit 2 0.5306122010 3.7692310810 14 0.269230792 3.714285407 +28 crit 2 0.3714286018 5.3846149445 14 0.384615353 2.6 +29 crit 2 0.3537415195 5.6538457870 14 0.403846128 2.476190637 +36 crit 14 1.8557142035 7.5442651532 14 0.538876082 1.855714204 +48 crit 14 1.2999998760 10.7692317963 14 0.769230843 1.3 +50 crit 14 1.2380952140 11.3076925278 14 0.807692323 1.238095214 +60 crit 112 8.0000000000 14.0000000000 14 1 1 +61 crit 56 3.8536582293 14.5316467285 14 1.037974766 0.963414557 +62 hit 50 4.6341464061 10.7894735336 10 1.078947353 0.926829281 +62 crit 56 3.7073167036 15.1052646637 14 1.078947476 0.926829176 +63 crit 31 1.9712541049 15.7260293961 14 1.123287814 0.890243789 +64 crit 17 1.0365853900 16.3999996185 14 1.171428544 0.853658556 +65 crit 56 3.2682925906 17.1343288422 14 1.223880632 0.817073148 +66 crit 168 9.3658536585 17.9375000000 14 1.28125 0.780487805 +66 sp_hit 48 4.6829268293 10.2500000000 8 1.28125 0.780487805 +67 crit 78 4.1445989933 18.8196735382 14 1.344262396 0.743902383 +67 crit 76 4.0383272242 18.8196735382 14 1.344262396 0.743902383 + +2. Think very hard +After some creative thinking, this is what I got: + +Percentage = Rating / F * H +Lv 8 to 60: 1/H = 1/52 * Level - 8/52 +Lv 60 to 70: H = -3/82 * Level + 131/41 +Lv 70 to 80: H = 82/52 * (131/63)^((Level - 70) / 10) + + F= +Expertise 2.5 +Defense 1.5 +Dodge 13.8 +Parry 13.8 +Block 5.0 +Hit 10.0 +Crit 14.0 +Haste 10.0 +Spell Hit 8.0 +Spell Crit 14.0 +Spell Haste 10.0 +Resilience 28.75 +Armor Penetration 3.756097412 + +This formula is correct to the 13th decimal place, so I'm 100% sure this is what blizzard uses. + + +**************************************** +** Stat Conversion Data for Reference ** +**************************************** +(Patch 3.2.0 Data) + Combat rating needed for 1 point of stat + Expt Def Dodge Parry Block M-Hit S-Hit Crit Resil Haste ArP +1 0.10 0.75 6.90 6.90 2.50 0.38 0.31 0.54 14.38 0.38 0.14 +2 0.10 0.75 6.90 6.90 2.50 0.38 0.31 0.54 14.38 0.38 0.14 +3 0.10 0.75 6.90 6.90 2.50 0.38 0.31 0.54 14.38 0.38 0.14 +4 0.10 0.75 6.90 6.90 2.50 0.38 0.31 0.54 14.38 0.38 0.14 +5 0.10 0.75 6.90 6.90 2.50 0.38 0.31 0.54 14.38 0.38 0.14 +6 0.10 0.75 6.90 6.90 2.50 0.38 0.31 0.54 14.38 0.38 0.14 +7 0.10 0.75 6.90 6.90 2.50 0.38 0.31 0.54 14.38 0.38 0.14 +8 0.10 0.75 6.90 6.90 2.50 0.38 0.31 0.54 14.38 0.38 0.14 +9 0.10 0.75 6.90 6.90 2.50 0.38 0.31 0.54 14.38 0.38 0.14 +10 0.10 0.75 6.90 6.90 2.50 0.38 0.31 0.54 14.38 0.38 0.14 +11 0.14 0.75 6.90 6.90 2.50 0.58 0.46 0.81 14.38 0.58 0.22 +12 0.19 0.75 6.90 6.90 2.50 0.77 0.62 1.08 14.38 0.77 0.29 +13 0.24 0.75 6.90 6.90 2.50 0.96 0.77 1.35 14.38 0.96 0.36 +14 0.29 0.75 6.90 6.90 2.50 1.15 0.92 1.62 14.38 1.15 0.43 +15 0.34 0.75 6.90 6.90 2.50 1.35 1.08 1.88 14.38 1.35 0.51 +16 0.38 0.75 6.90 6.90 2.50 1.54 1.23 2.15 14.38 1.54 0.58 +17 0.43 0.75 6.90 6.90 2.50 1.73 1.38 2.42 14.38 1.73 0.65 +18 0.48 0.75 6.90 6.90 2.50 1.92 1.54 2.69 14.38 1.92 0.72 +19 0.53 0.75 6.90 6.90 2.50 2.12 1.69 2.96 14.38 2.12 0.79 +20 0.58 0.75 6.90 6.90 2.50 2.31 1.85 3.23 14.38 2.31 0.87 +21 0.63 0.75 6.90 6.90 2.50 2.50 2.00 3.50 14.38 2.50 0.94 +22 0.67 0.75 6.90 6.90 2.50 2.69 2.15 3.77 14.38 2.69 1.01 +23 0.72 0.75 6.90 6.90 2.50 2.88 2.31 4.04 14.38 2.88 1.08 +24 0.77 0.75 6.90 6.90 2.50 3.08 2.46 4.31 14.38 3.08 1.16 +25 0.82 0.75 6.90 6.90 2.50 3.27 2.62 4.58 14.38 3.27 1.23 +26 0.87 0.75 6.90 6.90 2.50 3.46 2.77 4.85 14.38 3.46 1.30 +27 0.91 0.75 6.90 6.90 2.50 3.65 2.92 5.12 14.38 3.65 1.37 +28 0.96 0.75 6.90 6.90 2.50 3.85 3.08 5.38 14.38 3.85 1.44 +29 1.01 0.75 6.90 6.90 2.50 4.04 3.23 5.65 14.38 4.04 1.52 +30 1.06 0.75 6.90 6.90 2.50 4.23 3.38 5.92 14.38 4.23 1.59 +31 1.11 0.75 6.90 6.90 2.50 4.42 3.54 6.19 14.38 4.42 1.66 +32 1.15 0.75 6.90 6.90 2.50 4.62 3.69 6.46 14.38 4.62 1.73 +33 1.20 0.75 6.90 6.90 2.50 4.81 3.85 6.73 14.38 4.81 1.81 +34 1.25 0.75 6.90 6.90 2.50 5.00 4.00 7.00 14.38 5.00 1.88 +35 1.30 0.78 7.17 7.17 2.60 5.19 4.15 7.27 14.93 5.19 1.95 +36 1.35 0.81 7.43 7.43 2.69 5.38 4.31 7.54 15.48 5.38 2.02 +37 1.39 0.84 7.70 7.70 2.79 5.58 4.46 7.81 16.03 5.58 2.09 +38 1.44 0.87 7.96 7.96 2.88 5.77 4.62 8.08 16.59 5.77 2.17 +39 1.49 0.89 8.23 8.23 2.98 5.96 4.77 8.35 17.14 5.96 2.24 +40 1.54 0.92 8.49 8.49 3.08 6.15 4.92 8.62 17.69 6.15 2.31 +41 1.59 0.95 8.76 8.76 3.17 6.35 5.08 8.88 18.25 6.35 2.38 +42 1.63 0.98 9.02 9.02 3.27 6.54 5.23 9.15 18.80 6.54 2.46 +43 1.68 1.01 9.29 9.29 3.37 6.73 5.38 9.42 19.35 6.73 2.53 +44 1.73 1.04 9.55 9.55 3.46 6.92 5.54 9.69 19.90 6.92 2.60 +45 1.78 1.07 9.82 9.82 3.56 7.12 5.69 9.96 20.46 7.12 2.67 +46 1.83 1.10 10.08 10.08 3.65 7.31 5.85 10.23 21.01 7.31 2.74 +47 1.88 1.13 10.35 10.35 3.75 7.50 6.00 10.50 21.56 7.50 2.82 +48 1.92 1.15 10.62 10.62 3.85 7.69 6.15 10.77 22.12 7.69 2.89 +49 1.97 1.18 10.88 10.88 3.94 7.88 6.31 11.04 22.67 7.88 2.96 +50 2.02 1.21 11.15 11.15 4.04 8.08 6.46 11.31 23.22 8.08 3.03 +51 2.07 1.24 11.41 11.41 4.13 8.27 6.62 11.58 23.77 8.27 3.11 +52 2.12 1.27 11.68 11.68 4.23 8.46 6.77 11.85 24.33 8.46 3.18 +53 2.16 1.30 11.94 11.94 4.33 8.65 6.92 12.12 24.88 8.65 3.25 +54 2.21 1.33 12.21 12.21 4.42 8.85 7.08 12.38 25.43 8.85 3.32 +55 2.26 1.36 12.47 12.47 4.52 9.04 7.23 12.65 25.99 9.04 3.39 +56 2.31 1.38 12.74 12.74 4.62 9.23 7.38 12.92 26.54 9.23 3.47 +57 2.36 1.41 13.00 13.00 4.71 9.42 7.54 13.19 27.09 9.42 3.54 +58 2.40 1.44 13.27 13.27 4.81 9.62 7.69 13.46 27.64 9.62 3.61 +59 2.45 1.47 13.53 13.53 4.90 9.81 7.85 13.73 28.20 9.81 3.68 +60 2.50 1.50 13.80 13.80 5.00 10.00 8.00 14.00 28.75 10.00 3.76 +61 2.59 1.56 14.32 14.32 5.19 10.38 8.30 14.53 29.84 10.38 3.90 +62 2.70 1.62 14.89 14.89 5.39 10.79 8.63 15.11 31.02 10.79 4.05 +63 2.81 1.68 15.50 15.50 5.62 11.23 8.99 15.73 32.29 11.23 4.22 +64 2.93 1.76 16.17 16.17 5.86 11.71 9.37 16.40 33.68 11.71 4.40 +65 3.06 1.84 16.89 16.89 6.12 12.24 9.79 17.13 35.19 12.24 4.60 +66 3.20 1.92 17.68 17.68 6.41 12.81 10.25 17.94 36.84 12.81 4.81 +67 3.36 2.02 18.55 18.55 6.72 13.44 10.75 18.82 38.65 13.44 5.05 +68 3.53 2.12 19.51 19.51 7.07 14.14 11.31 19.79 40.65 14.14 5.31 +69 3.73 2.24 20.57 20.57 7.45 14.91 11.93 20.87 42.86 14.91 5.60 +70 3.94 2.37 21.76 21.76 7.88 15.77 12.62 22.08 45.34 15.77 5.92 +71 4.24 2.55 23.41 23.41 8.48 16.97 13.57 23.75 48.78 16.97 6.37 +72 4.56 2.74 25.19 25.19 9.13 18.26 14.60 25.56 52.48 18.26 6.86 +73 4.91 2.95 27.11 27.11 9.82 19.64 15.71 27.50 56.47 19.64 7.38 +74 5.28 3.17 29.16 29.16 10.57 21.13 16.91 29.59 60.76 21.13 7.94 +75 5.68 3.41 31.38 31.38 11.37 22.74 18.19 31.83 65.38 22.74 8.54 +76 6.12 3.67 33.76 33.76 12.23 24.47 19.57 34.25 70.34 24.47 9.19 +77 6.58 3.95 36.33 36.33 13.16 26.32 21.06 36.85 75.68 26.32 9.89 +78 7.08 4.25 39.09 39.09 14.16 28.32 22.66 39.65 81.43 28.32 10.64 +79 7.62 4.57 42.06 42.06 15.24 30.48 24.38 42.67 87.62 30.48 11.45 +80 8.20 4.92 45.25 45.25 16.39 32.79 26.23 45.91 94.27 32.79 12.32 + Expt Def Dodge Parry Block M-Hit S-Hit Crit Resil Haste ArP + + Agility needed for 1% Crit + War Pal Hun Rog Pri DK Sha Mage Lock Dru +1 3.87 4.62 3.52 2.23 10.96 3.87 9.62 12.94 8.41 7.92 +2 4.42 4.62 3.53 2.33 10.96 4.42 9.62 12.94 8.41 7.92 +3 4.42 4.62 3.69 2.43 10.96 4.42 10.10 12.94 8.83 8.32 +4 4.42 5.20 3.95 2.62 11.52 4.42 10.10 13.59 8.83 8.32 +5 4.42 5.20 4.12 2.72 11.52 4.42 10.58 13.59 8.83 8.71 +6 4.97 5.20 4.28 2.82 11.52 4.97 10.58 13.59 9.25 8.71 +7 4.97 5.20 4.44 3.01 11.52 4.97 10.58 13.59 9.25 9.11 +8 4.97 5.77 4.61 3.11 12.06 4.97 11.07 13.59 9.25 9.11 +9 4.97 5.77 4.88 3.21 12.06 4.97 11.07 13.59 9.67 9.51 +10 4.97 5.77 5.04 3.40 12.06 4.97 11.55 14.22 9.67 10.30 +11 5.52 5.77 5.41 3.79 12.06 5.52 11.55 14.22 10.09 10.70 +12 5.52 5.77 5.99 4.18 12.61 5.52 12.03 14.22 10.09 10.70 +13 6.08 6.35 6.46 4.66 12.61 6.08 12.03 14.22 10.09 11.09 +14 6.08 6.35 6.94 5.05 12.61 6.08 12.52 14.22 10.43 11.09 +15 6.63 6.93 7.52 5.63 12.61 6.63 12.99 14.88 10.59 11.88 +16 6.63 6.93 7.89 6.02 13.16 6.63 13.48 14.88 10.78 11.88 +17 6.63 6.93 8.38 6.41 13.16 6.63 13.48 14.88 10.94 12.29 +18 7.18 7.51 8.95 6.90 13.16 7.18 13.95 14.88 11.12 12.67 +19 7.18 7.51 9.43 7.38 13.72 7.18 13.95 14.88 11.30 12.67 +20 7.73 8.08 10.02 7.87 13.72 7.73 14.93 15.53 11.48 14.27 +21 7.73 8.08 10.40 8.35 13.72 7.73 14.93 15.53 11.67 14.27 +22 7.73 8.08 10.99 8.74 13.72 7.73 15.41 15.53 11.85 14.66 +23 8.29 8.67 11.47 9.23 14.27 8.29 15.41 15.53 12.03 15.06 +24 8.83 9.24 12.06 9.62 14.27 8.83 15.87 16.18 12.22 15.06 +25 8.83 9.24 12.55 10.20 14.27 8.83 16.37 16.18 12.42 15.85 +26 9.39 9.24 13.04 10.68 14.81 9.39 16.84 16.18 12.63 15.85 +27 9.39 9.81 13.62 11.07 14.81 9.39 16.84 16.18 12.82 16.23 +28 9.94 9.81 14.10 11.56 14.81 9.94 17.33 16.18 13.02 16.64 +29 9.94 10.40 14.71 12.05 15.36 9.94 17.33 16.81 13.23 16.64 +30 10.49 10.40 15.29 12.63 15.36 10.49 18.28 16.81 13.42 18.21 +31 10.49 10.98 15.70 13.02 15.36 10.49 18.28 16.81 13.64 18.62 +32 11.05 10.98 16.29 13.50 15.90 11.05 18.76 16.81 13.85 18.62 +33 11.05 11.55 16.89 13.99 15.90 11.05 19.23 17.45 14.06 19.01 +34 11.60 11.55 17.39 14.47 15.90 11.60 19.23 17.45 14.29 19.42 +35 11.60 12.12 17.99 15.06 16.45 11.60 20.20 17.45 14.49 19.80 +36 12.15 12.12 18.48 15.55 16.45 12.15 20.70 18.12 14.73 20.20 +37 12.15 12.12 19.08 15.92 16.45 12.15 20.70 18.12 14.95 20.62 +38 12.71 12.71 19.69 16.42 17.01 12.71 21.19 18.12 15.17 20.62 +39 12.71 12.71 20.28 16.89 17.01 12.71 21.19 18.12 15.41 21.01 +40 13.25 13.28 20.79 17.48 17.01 13.25 22.12 18.76 15.65 22.57 +41 13.81 13.28 21.28 17.99 17.54 13.81 22.62 18.76 15.87 22.99 +42 13.81 13.28 21.88 18.45 17.54 13.81 22.62 18.76 16.13 22.99 +43 14.37 13.87 22.52 18.94 18.08 14.37 23.09 18.76 16.37 23.36 +44 14.37 14.43 23.09 19.53 18.08 14.37 23.58 19.42 16.61 23.75 +45 14.90 14.43 23.75 20.12 18.08 14.90 24.04 19.42 16.86 24.57 +46 14.90 15.02 24.21 20.58 18.66 14.90 24.57 19.42 17.12 24.94 +47 15.46 15.02 24.88 21.10 18.66 15.46 25.00 20.04 17.36 24.94 +48 16.03 15.60 25.58 21.55 19.19 16.03 25.51 20.04 17.64 25.38 +49 16.03 15.60 26.18 22.03 19.19 16.03 25.51 20.04 17.89 25.77 +50 16.56 16.18 26.81 22.73 19.19 16.56 26.46 20.70 18.15 27.32 +51 16.56 16.75 27.32 23.20 19.72 16.56 26.95 20.70 18.42 27.70 +52 17.12 16.75 27.93 23.70 19.72 17.12 27.40 20.70 18.69 28.09 +53 17.67 17.33 28.57 24.27 20.28 17.67 27.40 21.37 18.98 28.49 +54 17.67 17.33 29.33 24.75 20.28 17.67 27.93 21.37 19.27 28.49 +55 18.21 17.89 29.94 25.38 20.83 18.21 28.90 21.37 19.53 29.33 +56 18.21 17.89 30.49 25.91 20.83 18.21 29.33 21.98 19.84 29.67 +57 18.76 18.48 31.15 26.46 21.37 18.76 29.85 21.98 20.12 30.12 +58 19.34 19.05 31.85 27.03 21.37 19.34 29.85 21.98 20.41 30.49 +59 19.34 19.05 32.57 27.47 21.93 19.34 30.30 22.62 20.70 30.86 +60 19.88 19.65 33.22 28.17 21.93 19.88 31.25 22.62 21.01 32.47 +61 20.96 20.20 33.67 29.94 22.47 20.96 32.26 22.62 21.32 33.44 +62 22.08 20.79 34.48 31.06 22.42 22.08 32.89 22.62 21.65 33.90 +63 23.20 21.37 35.21 32.57 22.57 23.20 34.01 23.31 21.98 35.09 +64 23.75 21.93 35.84 33.78 23.04 23.75 35.09 23.31 22.27 35.84 +65 24.88 22.52 36.63 34.97 23.42 24.88 35.59 23.31 22.62 36.50 +66 25.97 22.52 37.04 36.23 23.75 25.97 36.63 23.92 22.94 37.17 +67 27.03 23.70 37.88 37.31 24.10 27.03 37.45 23.92 23.26 37.74 +68 28.17 23.70 38.61 38.17 24.21 28.17 38.31 23.92 23.58 38.76 +69 29.24 24.27 39.37 39.06 24.27 29.24 39.22 24.57 23.92 39.37 +70 29.85 24.81 40.00 40.00 24.94 29.85 40.00 24.57 24.27 40.00 +71 32.05 27.17 43.10 43.10 26.88 32.05 43.10 26.53 26.04 43.10 +72 34.84 28.90 46.30 46.30 29.07 34.84 46.30 28.49 28.17 46.30 +73 37.59 31.15 49.75 49.75 31.25 37.59 49.75 30.40 30.30 49.75 +74 40.32 33.44 53.48 53.48 33.44 40.32 53.48 33.00 32.36 53.48 +75 43.10 36.36 57.80 57.80 36.23 43.10 57.80 35.59 34.84 57.80 +76 46.30 38.76 62.11 62.11 38.91 46.30 62.11 38.17 37.88 62.11 +77 50.25 41.67 66.67 66.67 41.67 50.25 66.67 41.32 40.82 66.67 +78 54.05 45.05 71.94 71.94 45.05 54.05 71.94 44.05 43.67 71.94 +79 58.14 48.54 77.52 77.52 48.31 58.14 77.52 47.85 47.17 77.52 +80 62.50 52.08 83.33 83.33 52.08 62.50 83.33 51.02 50.51 83.33 + War Pal Hun Rog Pri DK Sha Mage Lock Dru + + Intellect needed for 1% Spell Crit + Pal Hun Pri Sha Mage Lock Dru +1 12.02 14.31 5.85 7.50 6.11 6.67 6.99 +2 12.61 15.02 6.11 7.86 6.35 6.97 7.30 +3 12.61 15.02 6.38 8.22 6.60 7.27 7.62 +4 13.21 15.75 6.64 8.22 7.09 7.58 7.94 +5 13.21 15.75 7.17 8.58 7.33 7.88 8.26 +6 13.81 16.45 7.44 8.93 7.58 8.18 8.58 +7 14.41 16.45 7.71 9.29 7.82 8.48 8.90 +8 14.41 17.15 7.97 9.64 8.06 8.79 8.90 +9 15.02 17.15 8.24 10.00 8.55 9.09 9.21 +10 15.02 17.89 8.77 10.00 8.80 9.39 10.16 +11 15.63 17.89 9.57 10.72 9.53 10.30 10.80 +12 16.23 18.59 10.63 11.43 10.75 11.21 11.75 +13 16.84 20.04 11.43 12.50 11.48 12.12 12.39 +14 17.42 20.04 12.76 13.23 13.68 13.04 13.33 +15 18.62 21.46 13.81 14.29 14.90 13.95 14.62 +16 18.62 21.46 14.62 15.02 15.65 14.53 15.24 +17 19.23 22.17 15.95 15.72 16.61 15.75 16.21 +18 20.41 23.58 16.75 16.78 17.61 16.67 16.84 +19 20.41 23.58 17.79 17.51 18.59 17.57 17.79 +20 21.65 25.06 19.12 18.59 19.80 18.48 19.38 +21 22.22 25.77 19.92 19.31 20.53 19.38 20.00 +22 22.83 25.77 21.28 20.00 21.74 20.28 20.96 +23 23.42 27.17 22.08 21.10 22.47 21.23 21.60 +24 24.04 27.93 23.36 21.79 23.70 22.42 22.88 +25 25.25 28.57 24.45 22.88 24.69 23.31 23.81 +26 25.84 29.33 25.51 23.58 25.64 23.92 24.45 +27 25.84 30.03 26.60 24.27 26.88 25.13 25.38 +28 27.03 30.77 27.62 25.38 29.59 26.04 26.04 +29 27.62 31.45 28.74 26.11 30.77 27.25 27.32 +30 28.82 32.89 30.03 27.17 32.05 28.17 28.90 +31 29.41 33.67 31.06 28.25 32.79 28.82 29.50 +32 30.03 33.67 32.15 28.90 34.01 30.03 30.77 +33 30.67 35.09 33.22 30.03 34.97 30.86 31.45 +34 31.25 35.71 34.60 30.77 35.97 32.15 32.36 +35 32.47 37.17 35.59 31.85 37.17 33.00 33.67 +36 33.00 37.88 36.63 32.89 38.17 33.90 34.25 +37 33.67 37.88 38.02 33.56 39.37 35.21 35.21 +38 34.84 39.37 39.06 34.60 40.32 36.10 36.23 +39 35.46 40.00 40.16 35.34 41.49 37.31 37.17 +40 36.63 41.49 41.49 36.76 42.55 38.17 39.06 +41 37.31 42.19 42.55 37.45 43.48 39.06 39.68 +42 37.88 42.19 43.86 38.17 46.51 40.32 40.98 +43 39.06 43.67 44.84 39.37 47.39 41.15 41.67 +44 39.06 44.44 46.30 40.32 48.54 42.37 42.92 +45 40.32 45.87 47.62 41.49 49.75 43.67 43.86 +46 40.82 46.51 48.54 42.55 50.76 44.64 44.84 +47 42.02 47.17 50.00 43.29 52.08 45.45 45.66 +48 43.29 48.54 51.02 44.25 53.19 46.73 46.73 +49 43.86 49.26 52.36 45.45 54.35 47.85 47.85 +50 45.05 50.76 53.76 46.51 55.87 49.02 49.50 +51 45.66 51.55 54.64 47.62 56.82 50.00 50.51 +52 46.30 52.08 56.18 48.31 57.80 51.28 51.81 +53 47.39 53.76 57.14 49.75 58.82 52.36 52.36 +54 48.08 54.35 58.48 50.25 60.24 53.76 53.76 +55 49.26 55.87 60.24 51.81 61.73 54.95 54.95 +56 49.75 56.50 60.98 52.63 64.94 55.87 55.87 +57 50.51 57.14 62.50 53.48 66.23 56.82 56.82 +58 52.36 58.82 63.69 54.95 67.11 58.14 57.80 +59 52.91 59.52 64.94 55.87 68.49 59.52 59.17 +60 54.05 60.98 66.23 57.14 69.93 60.61 60.98 +61 62.89 63.69 67.57 60.98 69.93 62.89 61.73 +62 64.94 64.94 68.97 62.89 69.93 64.94 63.69 +63 67.11 66.67 69.93 65.79 69.93 67.57 66.67 +64 68.97 69.44 71.94 68.03 69.93 69.93 68.49 +65 71.43 70.92 72.99 70.42 70.42 72.46 70.42 +66 73.53 72.99 74.63 72.46 72.46 74.07 72.99 +67 74.63 75.19 75.76 74.63 74.63 76.92 75.19 +68 76.34 76.92 76.92 76.34 76.34 78.74 76.34 +69 78.13 78.13 78.74 78.13 78.13 79.37 78.13 +70 80.00 80.00 80.00 80.00 80.00 80.00 80.00 +71 86.21 86.21 86.21 86.21 86.21 86.21 86.21 +72 92.59 92.59 92.59 92.59 92.59 92.59 92.59 +73 99.01 99.01 99.01 99.01 99.01 99.01 99.01 +74 107.53 107.53 107.53 107.53 107.53 107.53 107.53 +75 114.94 114.94 114.94 114.94 114.94 114.94 114.94 +76 123.46 123.46 123.46 123.46 123.46 123.46 123.46 +77 133.33 133.33 133.33 133.33 133.33 133.33 133.33 +78 142.86 142.86 142.86 142.86 142.86 142.86 142.86 +79 153.85 153.85 153.85 153.85 153.85 153.85 153.85 +80 166.67 166.67 166.67 166.67 166.67 166.67 166.67 + Pal Hun Pri Sha Mage Lock Dru + +******************************************** +** Spirit-Based Mana Regeneration Formula ** +******************************************** +(Patch 3.2.0 Data) + +ManaRegen(SPI, INT, LEVEL) = (0.001 + SPI * BASE_REGEN[LEVEL] * (INT^0.5)) * 5 + +BASE_REGEN[LEVEL]= +1 0.020979 21 0.011840 41 0.008235 61 0.006421 +2 0.020515 22 0.011494 42 0.008113 62 0.006314 +3 0.020079 23 0.011292 43 0.008018 63 0.006175 +4 0.019516 24 0.010990 44 0.007906 64 0.006072 +5 0.018997 25 0.010761 45 0.007798 65 0.005981 +6 0.018646 26 0.010546 46 0.007713 66 0.005885 +7 0.018314 27 0.010321 47 0.007612 67 0.005791 +8 0.017997 28 0.010151 48 0.007524 68 0.005732 +9 0.017584 29 0.009949 49 0.007430 69 0.005668 +10 0.017197 30 0.009740 50 0.007340 70 0.005596 +11 0.016551 31 0.009597 51 0.007268 71 0.005316 +12 0.015729 32 0.009425 52 0.007184 72 0.005049 +13 0.015229 33 0.009278 53 0.007116 73 0.004796 +14 0.014580 34 0.009123 54 0.007029 74 0.004555 +15 0.014008 35 0.008974 55 0.006945 75 0.004327 +16 0.013650 36 0.008847 56 0.006884 76 0.004110 +17 0.013175 37 0.008698 57 0.006805 77 0.003903 +18 0.012832 38 0.008581 58 0.006747 78 0.003708 +19 0.012475 39 0.008457 59 0.006667 79 0.003522 +20 0.012073 40 0.008338 60 0.006600 80 0.003345 + + +********** +** TODO ** +********** +Readme: +Combat rating needed for 1 point of stat: parry needs to be updated + +Long term: +- Support for sets +- Option: Hide default stats +- Option: Show only in city +- Support for "+2% Spirit" type + +- Modifier keys for showing Rating, StatSummary +- Second set of defualt gems that can be switched with modifier keys + +There is no good way(afaik) to detect prismatic sockets, you would have to: +1. Parse the Link and remember how many gems are in this item. +2. Create a clean link with no gems and see how many sockets are in this item. +3. If the current item has more gems then sockets then it has a prismatic gem. +4. Check if player has Blacksmith and what if the player is high enough to add sockets. + +Doing: + +Note: +"Intelligently compare Crit Immunity in the StatSummary?" +[ ] Tick Box. +Ticked -- Tooltip: StatSummary will now show '% to be critted' comparisons while AWARE of your opponent's level as defined below. +Unticked (Default) -- Tooltip: StatSummary will now show '% to be critted' comparisons while UNAWARE of your opponent's level. +[ ] Number Field. +Illuminates when Ticked and Dims when Unticked (Default value, but Dimmed, is 73) -- Tooltip: Type the opponent's level you'd like StatSummary to stop comparing 'crit immunity' for. + +-- Failed -- +Try to fix mana oil enchants: was unable to find a way to scan the oil text + +-- Transition to 3.0.2 +if select(2, GetBuildInfo()) >= "9061" then + + +********************* +** Version History ** +********************* +1.5.1 +- Support new API changes in LibStatLogic-1.1 r?? +1.5.0 +- NEW: Support for RatingBuster_AlwaysBuffed: http://wow.curse.com/downloads/wow-addons/details/ratingbuster-alwaysbuffed.aspx +- Rating options: "Show Spell Hit" changed to "Show Spell Hit/Haste", and "Show Physical Hit" changed to "Show Physical Hit/Haste" +- Stat Breakdown: Show MP5 from Int will now show effects from Replenishment +- Stat Summary: Added Expertise Rating Summary +- Localization updates +1.4.9 +- Update for 3.3.3 +- Use /rabu for commands, since /rb is now used by the blizzard interface to launch the new raid browser window. +- 3.3.3: Death Knight: Endless Winter: Grants 2/4% strength. +- 3.3.3: Death Knight: Unbreakable Armor: The amount of strength granted is now 20%, up from 10%. +- 3.3.3: Warrior: Vitality: Now boosts Stamina by 3/6/9% +1.4.8 +- Update for 3.3.0 +- NEW: Rating Conversion, Stat Breakdown, Stat Summary can each be set to show on ALT, SHIFT, CTRL, Always, or Never. +- NEW: Two extra default gem sets which you can toggle with a modifier key +- Improved "Ignore undesirable items" option: Separate options for Cloth, Leather, Mail, and Plate items, can also set the minimum item quality +- Warlock: Fixed Demonic Knowledge calculations +- Warlock: Added Glyph of Life Tap +- Mage: 2pc Tier 9 support +- 3.2.2: Paladin: Touched by the Light: This talent now provides 20/40/60% of the paladins strength as spell power instead of 10/20/30% of the paladins stamina. +- 3.2.0: Warrior: Armored to the Teeth: This talent now provides 1/2/3 attack power per 108 armor, up from per 180 armor. +- Change options text style to match Blizzard options +- Optimized checking of unusable items +- Locale updates +1.4.7 +- NEW: Option to ignore prismatic sockets +- LibDualSpec-1.0 now optional, can be deleted if not needed. +- Update for 3.2.2 +- Armor Penetration Rating: The 25% buff is scaled back to 10% +- Death Knight: Unbreakable Armor: Now grants 25% additional armor. The amount of strength granted has been reduced to 10%. +- Death Knight: Glyph of Unbreakable Armor: Now increases the armor gained from Unbreakable Armor by 20%. +- Paladin: Blessing of Sanctuary: This blessing now grants 10% strength in addition to its current effects. +- Priest: Twisted Faith now grants spell power equal to 4/8/12/16/20% of spirit, up from 2/4/6/8/10%. +- Bug Fixes +- Mage: Removed Arcane Instability: Does not increase spell power +- Fixed Dodge from Agi formula +1.4.6 +- NEW: Option to enable dual profile support, will automatically swap profiles on talent switch when enabled. +- NEW: Option to disable Blizzard's stat change summary. +- Fixed comp style stat summary +- Dodge/parry neglect no longer truncated to integer expertise +- No longer displays "query server" message on invalid gem input, and will correctly inform user of invalid input. +- Setting default gems in colorblind mode now works correctly +- Paladin: Fixed Touched by the Light detection +1.4.5 +- Updated for 3.2.0 +- Fixed Resilience formula for levels 1 to 34 +- Fixed parry conversion for classes that can't parry +- Dodge Rating: The amount of dodge rating required per percentage of dodge has been increased by 15%. +- Parry Rating: The amount of parry rating required per percentage of parry has been reduced by 8%. +- Resilience: The amount of resilience needed to reduce critical strike chance, critical strike damage and overall damage has been increased by 15%. +- Agility: BaseDodge changed for all classes +- Fixed Avoidance DR values for Priest, Mage and Warlock +- Druid: Updated Improved Moonkin Form: Now grants 10/20/30% of spirit as spell power. +- Druid: Updated Improved Tree of Life: The armor bonus to Tree of Life Form from this talent has been reduced to 67/133/200% bonus armor. +- Druid: Fixed Natural Reaction: Only add dodge in Bear Form and Dire Bear Form +- Death Knight: Updated Frost Presence: 10% bonus health reduced to 6% bonus stamina. +- Death Knight: Updated Toughness: This talent now grants 2/4/6/8/10% armor instead of 3/6/9/12/15%. +- Death Knight: Updated Veteran of the Third War: Stamina bonus reduced to 1/2/3%. +- Death Knight: Updated Improved Frost Presence: While in Blood Presence or Unholy Presence, you retain 3/6% stamina from Frost Presence, and damage done to you is decreased by an additional 1/2% in Frost Presence. +- Death Knight: Updated Unbreakable Armor: Now grants damage reduction instead of physical damage reduction, and increases your Strength by 25% up from 10% +- Paladin: Updated Blessing of Sanctuary: This blessing now also increases stamina by 10%. This effect is not cumulative with Blessing of Kings. +- Paladin: Updated Lay on Hands: Now reduces the physical damage taken by the target by 10/20% instead of increasing the target's armor. +- Paladin: Updated Divine Intellect: This talent now gives 2/4/6/8/10% increased intellect instead of 3/6/9/12/15%. +- Priest: Updated Inspiration: The buff from this ability now reduces the physical damage taken by the target by 3/7/10% instead of increasing the target's armor. +- Shaman: Updated Ancestral Healing: The buff from this ability now reduces the physical damage taken by the target by 3/7/10% instead of increasing the target's armor. +- Shaman: Updated Unleashed Rage: Reduced to 3 points, down from 5. +- Warlock: Updated Demonic Embrace: Now a 3 point talent, down from 5 points. +1.4.4 +- StatBreakdown now shows Armor to AP for Armored to the Teeth(Warrior) and Bladed Armor(Death Knight) +- Better support for 3.0.8 bonus armor changes +- Dodge Rating: Low-level players will now convert Dodge Rating at the same rate as level 34 players. +- Armor Penetration Rating: All classes now receive 25% more benefit from Armor Penetration Rating. +- Haste Rating: shamans, paladins, druids, and death knights now receive 30% more melee haste from Haste Rating. +- Spirit: The amount of mana regeneration granted by this stat has been reduced by 40%. +- Druid: Updated Talent: Heart of the Wild: Stamina bonus changed to 2/4/6/8/10%. +- Druid: Updated Talent: Survival of the Fittest: Bonus armor reduced to 11/22/33% instead of 22/44/66%. +- Druid: Added Talent: Improved Mark of the Wild: Now also increases all of your total attributes by 1/2%. +- Druid: Updated Talent: Intensity: Now grants 17/33/50% of mana regeneration while casting. +- Druid: Updated Talent: Improved Tree of Life: Now receives 80/160/240% increased armor. +- Hunter: Added Talent: Hunting Party: now increases your total agility by an additional 1/2/3%. +- Mage: Updated Buff: Mage Armor: Now grants 50% of mana regeneration while casting. +- Mage: Updated Talent: Arcane Meditation: Now grants 17/33/50% of mana regeneration while casting. +- Mage: Updated Talent: Pyromaniac: Now grants 17/33/50% of mana regeneration while casting. +- Mage: Molten Armor: 35% Spirit -> Spell Crit Rating +- Paladin: Updated Talent: Sacred Duty now increases stamina by 4/8%. +- Priest: Added Talent: Improved Power Word: Fortitude: Now also increases your total stamina by 2/4%. +- Priest: Updated Talent: Meditation: Now grants 17/33/50% of mana regeneration while casting. +- Shaman: Updated Talent: Toughness: No longer increases your armor. Instead, this talent now increases your total stamina by 2/4/6/8/10%. +1.4.3 +- Now uses Ace3 +- Partial support for 3.0.8 bonus armor changes +- Stat Breakdown: Fixed Parry from Strength not showing when values are < 0.5% +- Rogue: Added Talent: Endurance +- Rogue: Added Talent: Savage Combat +- Mage: Added Talent: Pyromaniac now gives mana regen +- Shaman: Fixed Talent: Unrelenting Storm is now 3 ranks +- Changed base stat mods to compute multiplicatively +- Updated localizations +1.4.2 +- Chance to be missed diminishing returns now supported +- Rating conversion and StatSummary sum now supports avoidance diminishing returns too +- Clear cache after profile switch +- Shield Mastery and Redoubt now affect block value from strength +- StatSummary: Put Health with Stamina, Mana with Intellect +- Mage: Added Buff: Mage Armor +- Mage: Added Glyph: Glyph of Mage Armor +- Death Knight: Added Glyph: Glyph of Unbreakable Armor +- Warrior: Will compare 2H weapons with MH and OH instead of MH+OH if player has Titan Grip +- Warrior: Fixed Talents: Vitality, Strength of Arms +- Tauren: Removed Endurance +- 3.0.8: Druid: Updated Talent: Survival of the Fittest: This talent now grants 22/44/66% bonus armor in Bear Form and Dire Bear Form in addition to all of its previous effects. +- Support for Argent Crusade head enchant (+37 sta / +20 defense rating) +- Support for direct Defense gains which isn't affected by DR (Rune of the Stoneskin Gargoyle) +- Support for meta gem statmods: +- Austere Earthsiege Diamond: 2% Increased Armor Value from Items +- Beaming Earthsiege Diamond: +2% Mana +- MetaGem: Eternal Earthsiege Diamond: +5% Shield Block Value +- MetaGem: Eternal Earthstorm Diamond: +5% Shield Block Value +- MetaGem: Ember Skyfire Diamond: +2% Intellect +- MetaGem: Ember Skyflare Diamond: +2% Intellect +- Support for enchant statmods: +- Enchant: Rune of the Stoneskin Gargoyle: +2% Stamina +- enUS: Fixed +2% Intellect parsed as +2 Intellect on Ember meta gems +- Use LibStatLogic-1.1 and LibTipHooker-1.1 +- Updated localizations: Russian, Spanish, Taiwan, China, French, German, Korean +- Code cleanup +1.4.1 +- Increase /rb level option max value to 83 +- Avoidance diminishing returns support for /rb sum avoidance +- Support for "+x to All Stats", "+x Armor Penetration Rating", "+x Expertise Rating" Gems +- Fixed: Error when Druids enable Show Ranged Attack Power in StatSummary +- Warlock: Fixed Buff: Fel Armor - 30% spell power from spirit wasn't being detected +- Priest: Removed Talent: Focused Power +- Hunter: Removed Talent: Master Marksman - No longer increases RAP +- Shaman: Updated Talent: Mental Quickness - Moved to 2,21 +- Paladin: Added Talent: Redoubt - Increases your block value by 10%/20%/30% +- Death Knight BaseDodge changed from 0.758% to 3.4636%. +- Updated localizations: Taiwan, French, Russian, German, Korean +1.4.0 +- Updated toc to 30000, this versions is compatible with both TBC and WotLK +- Fixed: when removing gems it will continue to show the gem text in empty sockets +- Added Russian localizations by Orsana +- Updated localizations: Korean, French, German +- Minor bug fixes +- **WotLK Support** +- WotLK support with version checking, up to date with build 9061 +- Formulas updated for Death Knights and level 80 +- Support for Spell Power stat +- Support for Armor Penetration Rating +- Avoidance diminishing returns implemented for StatSummary Dodge% and Parry% diff values, because I think thats where its most needed and makes most sense. +- (Dodge% and Parry% in Rating/Stat conversion and StatSummary totals are before dminishing returns) +- Option to show physical hit, spell hit or both from hit rating(crit and haste are the same for physical and spell) +- StatSummery: Added Ranged Hit Chance, Ranged Hit Rating, Ranged Haste, Ranged Haste Rating, Ranged Crit Chance, and Ranged Crit Rating +- StatSummery: Hit Rating, Critical Strike Rating, and Haste Rating now modify both melee attacks and spells. + +- Support for WotLK talent and buff stat mods, detailed change log for each class: +Warrior +- Added Talent: Armored to the Teeth: 1/2/3 for every 180 armor +- Added Talent: Strength of Arms: Increases Strength and Stamina by 2%/4%. +- Added Buff(TBC): Last Stand: +30% of your maximum health +- Updated Talent: Vitality: Increases your total Strength and Stamina by 2%/4%/6% +- Updated Talent: Shield Mastery: 10%/20%/30% -> 15%/30% + +Warlock +- Added options: Show Spell Damage from Spirit (Fel Armor) +- Added options: Show Healing from Spirit (Fel Armor) +- Added Talent: Demonic Aegis: Increases the effectiveness of your Demon Armor and Fel Armor spells by 10%/20%/30%. +- Added Talent: Fel Synergy: Your Summoned Demons share an additional 5%/10% of your Armor, Intellect and Stamina +- Added Talent: Fel Vitality: Increases your maximum health and mana by 1%/2%/3%. +- Added Buff: Fel Armor: Increases spell power equal to 30% of your Spirit. +- Added Buff: Demonic Pact: Your pet's criticals apply the Demonic Pact effect to your party or raid members. Demonic Pact increases spell power by 2%/4%/6%/8%/10% of your Spell Damage for 12 sec. +- Added Buff: Metamorphosis: You gain Demon Form, increasing your armor by 360%. +- Removed Talent: Fel Stamina +- Removed Talent: Fel Intellect +- Updated Talent: Demonic Embrace: No longer reduces spirit. Stamina 3%/6%/9%/12%/15% -> 2%/4%/6%/8%/10% + +Shaman +- Added options: Show Attack Power from Intellect (Mental Dexterity) +- Updated Formula: 1 AP from 1 Agi, 1AP from 1 Str +- Added Talent: Mental Dexterity: Increases your Attack Power by 33%/66%/100% of your Intellect. +- Added Buff: Astral Shift: When stunned, feared or silenced you shift into the Astral Plane reducing all damage taken by 30% +- Added Buff: Unleashed Rage: Melee attack power increased by 10%. +- Removed Talent: Shield Specialization +- Updated Talent: Nature's Blessing: spell damage and healing -> healing, 10%/20%/30% -> 5%/10%/15% +- Updated Talent: Anticipation: 1%/2%/3%/4%/5% -> 1%/2%/3% +- Updated Talent: Ancestral Knowledge: maximum Mana -> intellect. 1%/2%/3%/4%/5% -> 2%/4%/6%/8%/10%. + +Rogue +- Removed Talent: Vitality + +Priest +- Added Talent: Focused Power: Increases your total spell damage and healing done by 2%/4%. +- Added Talent: Twisted Faith: Increases your spell power by 2%/4%/6%/8%/10% of your total Spirit +- Updated Talent: Improved Divine Spirit: No longer increases spell power by spirit +- Updated Talent: Mental Strength: Increases your maximum Mana -> total Intellect +- Updated Talent: Enlightenment: Stamina, Intellect and Spirit -> Stamina, Spirit and Spell Haste + +Paladin +- Added options: Show Spell Damage from Stamina (Touched by the Light) +- Added options: Show Healing from Stamina (Touched by the Light) +- Added options: Show Spell Damage from Strength (Sheath of Light) +- Added options: Show Healing from Strength (Sheath of Light) +- Added Talent: Touched by the Light: Increases your spell power by an amount equal to 10%/20%/30% of your Stamina +- Added Talent: Sheath of Light: Increases your spell power by an amount equal to 10%/20%/30% of your attack power +- Updated Talent: Holy Guidance: 35% -> 20% +- Updated Talent: Divine Strength: Increases your total Strength by 3%/6%/9%/12%/15% +- Updated Talent: Combat Expertise: Changed to 3 ranks +- Removed Talent: Shield Specialization + +Mage +- Added Talent: Student of the Mind: Increases your total Spirit by 4%/7%/10%. +- Added Talent(WotLK & TBC): Arcane Instability: Increases your spell damage and critical strike chance by 1%/2%/3%. +- Updated Talent: Arcane Fortitude: Increases your armor by an amount equal to 50%/100%/150% of your Intellect. +- Updated Talent: Mind Mastery: Increases spell damage by up to 3%/6%/9%/12%/15% of your total Intellect. + +Hunter +- Added options: Show Spell Damage from Stamina +- Added options: Show Attack Power from Stamina (Hunter vs. Wild) +- Added Talent: Hunter vs. Wild: Increases you and your pet's attack power and ranged attack power equal to 10%/20%/30% of your total Stamina. +- Updated Buff: Aspect of the Viper: no longer gives MP5 from Int +- Updated Talent: Careful Aim: now adds 33%/66%/100% RAP from Int +- Updated Talent: Survivalist: Increases your Stamina by 2%/4%/6%/8%/10%. +- Updated Talent: Combat Experience: Increases your total Agility and Intellect by 2%/4%. +- Updated Talent: Survival Instincts - No longer increases AP + +DeathKnight +- Added options: Show Parry from Strength (Forceful Deflection) +- Added Pasive: Forceful Deflection: Increases your Parry Rating by 25% of your total Strength. +- Added Talent: Bladed Armor: 1/2/3/4/5 AP every 180 Armor. +- Added Talent: Veteran of the Third War: Increases your total Strength by 2%/4%/6% and your total Stamina by 1%/2%/3%. +- Added Talent: Will of the Necropolis: When you have less than 35% health, your total armor increases by 10%/20%/30%. +- Added Talent: Toughness: Increases your armor value from items by 3%/6%/9%/12%/15% +- Added Talent: Ravenous Dead: Increases the total Strength of you by 1%/2%/3% +- Added Talent: Shadow of Death: Increases your total Strength and Stamina by 2%. +- Added Talent: Abomination's Might: Increases your total Strength by 1%/2%. +- Added Buff: Abominable Might: Attack power increased by 10%. +- Added Buff: Unbreakable Armor: Increases your armor by 25%, your total Strength by 10%. +- Added Buff: Frost Presence: Increases armor by 60%, health by 10% + +Druid +- Added options: Show Spell Damage from Spirit (Improved Moonkin Form) +- Added options: Show Healing from Spirit (Improved Tree of Life) +- Added Talent: Predatory Strikes: Increases 20% of any attack power on your equipped weapon. +- Added Talent: Furor: Increases your total Intellect while in Moonkin form by 2%/4%/6%/8%/10%. +- Added Talent: Improved Tree of Life: Increases your Armor while in Tree of Life Form by 33%/66%/100%, increases healing by 5%/10%/15% of spirit. +- Added Talent: Protector of the Pack: Increases your attack power in Bear Form and Dire Bear Form by 2%/4%/6%. +- Added Buff: Survival Instincts: +30% of your maximum health +- Updated Talent: Lunar Guidance: 8%/16%/25% -> 4%/8%/12% +- Updated Talent: Nurturing Instinct: 50%/100% -> 35%/70% of your Agility +- Updated Talent: Survival of the Fittest: 1%/2%/3% -> 2%/4%/6% +- Updated Buff: Dire Bear Form, Moonkin Form: Armor +400% -> +370% +- Master Shapeshifter doesn't affect char window stats + +1.3.8 +- NEW: Support for negative stats +- 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 +- Fixed: Better JewelTips support +- Fixed: Druid - Nurturing Instinct (Str->Agi) +- Fixed: Mage - Arcane Fortitude (50% -> 100% Armor from Int) +- Optimized library usage +- Updated localizations +1.3.7a +- Fixed: Loading error +1.3.7 +- Changed: Will only show stat breakdown options your class can use +- Changed: Class specific stat breakdown options will show the talents required +- Added: Stat breakdown support for Mental Quickness (Shaman) +- Fixed: Support for new Demonic Knowledge(Warlock) and Nurturing Instinct(Druid) +- Fixed: Library errors +1.3.6 +- Updated toc to 20400 +- Fixed: Able to clear default gem settings +- Fixed: Deadly Fire Opal now shows rating conversion +1.3.5 +- NEW: Default gems for empty sockets! Set the gems to use for each socket using /rb sum gem +- 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. +- Fixed: Will now work with [Insightful Earthstorm Diamond] +- Fixed: Profiles should now work +- Changed: Use "/rb win" to open the options window instead of "/rb optionswin" +1.3.1 +- Fixed: Spell Haste summary works now +- Fixed: Doesn't match percentages anymore (ex: Increases healing by up to 10% of your total Intellect) +- Fixed: Error when sorting StatSummary alphabetically +- Updated localizations: Taiwan, French, China, German, Spanish +1.3.0 +- Updated: TOC to 20300 +- Updated localizations: Taiwan, Korean, China, German +- Fixed: Socketed gem stat text color after percentage conversion is no longer yellow +- Fixed: "+X healing and +X spell damage" type gems and enchants now gives correct healing summary +- NEW: Categorized StatSummery Options in to Basic, Physical damage, Spell damage and healing, Tank +- NEW: StatSummary is sorted(basic, physical damage, spell damage and healing, tank in that order) +- NEW: Option to sort StatSummary alphabetically instead of the above +- NEW: Option to include block chance in Avoidance summary +- StatSummary Added: + Resilience + Haste + Haste Rating + Spell Haste + Spell Haste Rating + Penetration + IgnoreArmor + HitRating + CritRating + SpellHitRating + SpellCritRating + DodgeRating + ParryRating + BlockRating +1.2.8 +- Fixed: +X Spell Power gives healing too +- In 2.3.0: Support for Spell Damage bonus in +Healing stats +1.2.7 +- NEW: Option to Show detail text for Resilience and Expertise conversions +- NEW: Option to Show Avoidance Summary <- Dodge, Parry, MobMiss +- NEW: TankPoints support, if you have TankPoints loaded you get 2 new summary options: TankPoints and Total Reduction +- In 2.3.0: Added Expertise stat support +- 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 +- In 2.3.0: Intensity (Druid Restoration talent) increased to 10/20/30% mana regeneration +- In 2.3.0: Arcane Meditation (Mage Arcane talent) increased to 10/20/30% mana regeneration +- In 2.3.0: Meditation (Priest Discipline talent) increased to 10/20/30% mana regeneration +- 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% +- 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 +- All 2.3.0 Changes will only take affect when using a 2.3.0 client. +- Updated: German localization +1.2.6 +- Fixed: Ranged AP Calculations +1.2.5 +- Updated: toc to 20200 +- Fixed: Haste rating change in 2.2.0 +- Fixed: Hunter Survival Instincts talent support +- Fixed: Armor multiplier no longer apply to Armor from enchants +- NEW: Added China localization by iceburn(candykiss) +- Updated: Taiwan localization +- Updated: Korean localization by fenlis +- Updated: German localization by Dleh +- Code optimizations +- Updated: Libs +1.2.4 +- Fixed: Error when difftype is set to comp +- Made Waterfall-1.0 optional +1.2.3 +- NEW: You can now open the options window using /rb optionswin +- Updated Taiwan localization +- Updated Korean localizations by fenlis +1.2.2 +- New option to hide the StatSummary title +- New option to hide the sigma icon in the StatSummary title +- New option to add a empty line after the StatSummary +- Updated Taiwan localization +- Other localizations needs to be updated +1.2.1 +- Updated Taiwan localization +- Improved stat scanning +- Updated German localization +1.2.0 +- Updated French localization by Tixu and Silaor, now supports StatSummary +- Fixed a bug causing StatSummary not showing correctly for languages other then English +- Fixed Parry/SpellHaste rating conversions +- Updated libs +1.1.9 +- Pre updated the TOC to 2.1.0 +- Improved the Sigma icon +- Updated readme file +1.1.8 +- StatSummary: "Mana Regen while Not casting" now shows the correct value +- StatSummary: "Health Regen while Out of Combat" now shows the correct value +- StatSummary: fixed lines with "and" counting stats twice +- Added support for Gnome +5% Intellect Racial +- Added support for Human +10% Spirit Racial +- Fixed StatLogic line 6285 strfind error (thanks to everyone that helped) +- Updated Korean localizations by fenlis +1.1.7 +- Minor bug fixes +- Updated Taiwan localizations by mcc +- Updated Korean localizations by fenlis +- Updated French localizations by renchap +1.1.6 +- Stat Summary now has the option to show resistances +- Fixed Feral Attack Power name +- /rb sum ignore unused now shows leather for hunters +- 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 +1.1.5 +- Fixed MP5NC, HP5OC summary +- Changed default diff style from comp to main, since not everyone uses a compare addon +- Attempt to fix some more funny bugs +1.1.4 +- Option to display Weapon Max Damage in summary +- Improved option for ignoring enchants and gems, they are now 2 different options +- Fixed some classes not showing summary for cloaks +- Fixed incorrect shield diffs +- Improved diff style code should fix funny errors +1.1.3 +- Fixed EQCompare, tekKompare support +- Updated Taiwan localizations +1.1.2 +- Option to Display diff values in the main tooltip or only in compare tooltips for readability +- Option to Ignore enchants and gems on items when calculating the stat summary +- /rb sum ignore unused now shows all armor types they are use for druids, paladins and shamans +- Updated Taiwan localizations +- Code clean up +1.1.1 +- Option to Show stat summary only for highest level armor type and items you can use with uncommon quality and up +- Option to Hide stat summary for equipped items +- Option to Add a blank line before stat summary for readability +- Mage, Warlock, Shaman now shows spellcrit as default summary instead of crit +- Updated Taiwan localizations +- Minor bug fixes +1.1.0 +- NEW: Stat Summary - Display the sum of stats of the item and/or the stat difference of the item and your equipped items +- Choose the stats you really care about to be show in the summary +- 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" +- Option descriptions now show class names for class specific stat conversions +- Added support for Aspect of the Viper +- Option to hide rating conversions +- Option to hide all base stat conversions +- Option to further breakdown Defense into Crit Avoidance, Hit Avoidance, Dodge, Parry and Block +- Option to further breakdown Weapon Skills into Crit, Hit, Dodge Neglect, Parry Neglect, Block Neglect +- Fixed Taiwan and French localization errors +- Fixed locale registering twice error +- Fixed mp5 and hp5 calculations for Shaman, Druid, Mage, Warlock +- Agi -> Dodge only works for your current level, for best results turn off /rb usereqlv, and set /rb level 0 +1.0.0 +- Support for talents and buffs that modify your stats +- Supports the following stat conversions +- Str -> AP, Block, Healing(Talent) +- Agi -> Crit, Dodge, AP, RAP, Armor +- Sta -> Health, SpellDmg(Talent) +- Int -> Mana, SpellCrit, SpellDmg(Talent), Healing(Talent), MP5(Talent), RAP(Talent), Armor(Talent) +- Spi -> MP5(Talent), MP5NC, HP5, SpellDmg(Talent), Healing(Talent) +- If you need a GUI config window for RatingBuster, use Niagara (Download at: http://files.wowace.com/) +0.9.5 +- Fixed library error +0.9.4 +- Added Taiwan localizations by CuteMiyu +0.9.3 +- Updated Korean localization by kcgcom +0.9.2 +- Code clean up +- Finally removed Compost +0.9.1a +- Really fixed locales +0.9.1 +- Fixed locales +- Added Korean localization by kcgcom +0.9.0 +- Optimized parsing algorithm to use fewer resources +- showCritFromAgi and showSpellCritFromInt will now correctly save as per class data +- /rb level will now save +- No longer scans buffs +- Code clean up +0.8.6 +- tekKompare support +- Sniff support +0.8.5 +- AtlasLoot support +- ItemMagic support +- Fixed line 785 error +0.8.4 +- Spell Crit from Intellect defaults off for Hunters too +0.8.3 +- Fixed color picker bug +- Updated French localization (Tixu) +0.8.2 +- Fixed % signs showing before some periods bug +0.8.1 +- Option to enable colored text (/rb color) +- Fixed Defense showing the % sign bug +- Fixed Haste Rating conversion +- Updated French localization (Tixu) +0.8.0 +- Option to show Crit from Agility, Ex: "+15 Agility (+0.72% Crit)" +- Option to show Spell Crit from Intellect, Ex: "+23 Intellect (+0.35% Spell Crit)" +- Support for "grant you xx stat" type pattern, ex: Quel'Serrar, Assassination Armor set +- "+14 (1.21%) Rating" type strings changed to "+14 Rating (+1.21%)" +- Recoded tooltip scanner is now more easily extendable and has support for multiple separators for better accuracy. +0.7.6 +- The amount of haste granted by a point of haste rating has been increased by 50% (Patch 2.0.7) +- Fixed Mutltitips support +- Minor code tweaks +0.7.5 +- Fixed double conversion bug +- Fixed GetItem error +- Support for Hit Avoidance Rating (assuming its the same as melee Hit Rating) +0.7.1 +- Fixed a hooking bug +0.7.0 +- Now uses the OnTooltipSetItem script handler instead of hooking all the SetX methods, + this combined with the new Tooltip:GetItem() method should also fix problems where + RatingBuster doesn't always work, like at the mailbox. +0.6.6 +- MultiTips support +0.6.5 +- LinkWrangler support +0.6.4 +- Updated Libs +0.6.3 +- Use Required Level defaults to true +- Support for EQCompare +- 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) +0.6.2 +- Added German localization by Runenstetter@Nathrezim.EU +- Fixed French localization +0.6.1 +- Added French localization by Tixu +0.6 +- Added option to calculate using the required level if you are below the required level +- Redesigned the tooltip scanner to be more locale friendly, should be easier to do translations now. +0.5.1 +- Fixed line 457 error +0.5 +- Improved ItemLevel and ItemID algorithm, will now work on most tooltips +- Updated Libs +0.4.3 +- Fixed line 499 error +- Temporarily removed ItemLevel and ID support for Bagnon, working on a better implementation +0.4.2 +- Fixed a rare error in line 487 +- Updated Libs +0.4.1 +- Inspect frame support for ItemLevel and ItemID +- Two-Handed skill ratings now works +0.4 +- Bagnon support for ItemLevel and ItemID +- Fixed some errors +- Updated libs +0.3.2 +- Fixed auction house bug +0.3.1 +- Fixed keyring bug +0.3 +- Works with enchant links +- Works with keyring items +0.2.1 +- Fixed AceConsole error +0.2 +- Simplified the localization file for easier localization +- Added keyword "spell crit" +- Added Item Level, Item ID support for profession trainer items +- Set Debugging to false +0.1.1 +- Removed AceHook2.1 cause it was causing problems with other Ace2 addons +0.1 +- Initial release \ No newline at end of file diff --git a/RatingBuster/Changelog-RatingBuster-r295.txt b/RatingBuster/Changelog-RatingBuster-r295.txt new file mode 100644 index 0000000..a6e6a45 --- /dev/null +++ b/RatingBuster/Changelog-RatingBuster-r295.txt @@ -0,0 +1,79 @@ +------------------------------------------------------------------------ +r295 | cremor | 2010-10-22 16:37:30 +0000 (Fri, 22 Oct 2010) | 1 line +Changed paths: + M /trunk/RatingBuster-Locale-deDE.lua + +- deDE update +------------------------------------------------------------------------ +r294 | whitetooth | 2010-10-22 16:07:47 +0000 (Fri, 22 Oct 2010) | 2 lines +Changed paths: + M /trunk/RatingBuster-Locale-deDE.lua + M /trunk/RatingBuster-Locale-enUS.lua + M /trunk/RatingBuster-Locale-esES.lua + M /trunk/RatingBuster-Locale-frFR.lua + M /trunk/RatingBuster-Locale-koKR.lua + M /trunk/RatingBuster-Locale-ruRU.lua + M /trunk/RatingBuster-Locale-zhCN.lua + M /trunk/RatingBuster-Locale-zhTW.lua + M /trunk/RatingBuster.lua + +- Removed deprecated stats +- Update libs +------------------------------------------------------------------------ +r293 | cremor | 2010-10-22 14:12:12 +0000 (Fri, 22 Oct 2010) | 1 line +Changed paths: + M /trunk/RatingBuster-Locale-deDE.lua + +- deDE update +------------------------------------------------------------------------ +r292 | whitetooth | 2010-10-21 07:47:03 +0000 (Thu, 21 Oct 2010) | 1 line +Changed paths: + M /trunk/RatingBuster-Locale-deDE.lua + M /trunk/RatingBuster-Locale-enUS.lua + M /trunk/RatingBuster-Locale-esES.lua + M /trunk/RatingBuster-Locale-frFR.lua + M /trunk/RatingBuster-Locale-koKR.lua + M /trunk/RatingBuster-Locale-ruRU.lua + M /trunk/RatingBuster-Locale-zhCN.lua + M /trunk/RatingBuster-Locale-zhTW.lua + M /trunk/RatingBuster.lua + +- Partial support for Master Rating +------------------------------------------------------------------------ +r289 | whitetooth | 2010-10-19 17:22:17 +0000 (Tue, 19 Oct 2010) | 1 line +Changed paths: + M /trunk/RatingBuster.lua + +- Removed "ADD_AP_MOD_SPELL_DMG" +------------------------------------------------------------------------ +r288 | whitetooth | 2010-10-19 17:01:30 +0000 (Tue, 19 Oct 2010) | 1 line +Changed paths: + M /trunk + M /trunk/.pkgmeta + M /trunk/About RatingBuster.txt + M /trunk/RatingBuster.lua + M /trunk/RatingBuster.toc + M /trunk/embeds.xml + +- Core updated to LibStatLogic-1.2 +------------------------------------------------------------------------ +r287 | 7destiny | 2010-10-15 16:39:21 +0000 (Fri, 15 Oct 2010) | 1 line +Changed paths: + M /trunk/RatingBuster-Locale-koKR.lua + +- koKR Update +------------------------------------------------------------------------ +r286 | whitetooth | 2010-10-02 10:15:26 +0000 (Sat, 02 Oct 2010) | 1 line +Changed paths: + M /trunk/RatingBuster.lua + +- Fixed some loading errors in 4.0 +------------------------------------------------------------------------ +r285 | cremor | 2010-06-03 14:46:28 +0000 (Thu, 03 Jun 2010) | 2 lines +Changed paths: + M /trunk/RatingBuster-Locale-deDE.lua + M /trunk/RatingBuster.lua + +- "Hide Blizzard Item Comparisons" now also works for ItemRefTooltips +- deDE update +------------------------------------------------------------------------ diff --git a/RatingBuster/GPL.txt b/RatingBuster/GPL.txt new file mode 100644 index 0000000..d511905 --- /dev/null +++ b/RatingBuster/GPL.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/RatingBuster/RB-Example.jpg b/RatingBuster/RB-Example.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e412bf0d6974f111456cabc9d6b7d7e25dabb33b GIT binary patch literal 154184 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

lX-G!kaim7PUBj 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"] = true +L["|cffffff7f%s|r is now set to |cffffff7f[%s]|r"] = "|cffffff7f%s|r ist nun auf |cffffff7f[%s]|r gesetzt" +L["Invalid input: %s. ItemID or ItemLink required."] = "Ungültige Eingabe: %s. ItemID oder ItemLink benötigt." +L["Queried server for Gem: %s. Try again in 5 secs."] = "Frage den Server nach Edelstein: %s. Versuche es in 5 Sekunden noch einmal." +-- /rb sum gem yellow +L["Yellow Socket"] = EMPTY_SOCKET_YELLOW +-- /rb sum gem blue +L["Blue Socket"] = EMPTY_SOCKET_BLUE +-- /rb sum gem meta +L["Meta Socket"] = EMPTY_SOCKET_META +-- /rb sum gem2 +L["Second set of default gems which can be toggled with a modifier key"] = "Zweites Set von Standardedelsteinen, das mit einer Umschalttaste angezeigt werden kann" +L["Can't use the same modifier as Gem Set 3"] = "Kann nicht die gleiche Umschalttaste wie das dritte Set benutzen" +-- /rb sum gem2 key +L["Toggle Key"] = "Umschalttaste" +L["Use this key to toggle alternate gems"] = "Benutze diese Taste um zu den alternativen Edelsteinen umzuschalten" +-- /rb sum gem3 +L["Third set of default gems which can be toggled with a modifier key"] = "Drittes Set von Standardedelsteinen, das mit einer Umschalttaste angezeigt werden kann" +L["Can't use the same modifier as Gem Set 2"] = "Kann nicht die gleiche Umschalttaste wie das zweite Set benutzen" + +----------------------- +-- Item Level and ID -- +----------------------- +L["ItemLevel: "] = true +L["ItemID: "] = true +----------------------- +-- Matching Patterns -- +----------------------- +-- Items to check -- +-------------------- +-- [Potent Ornate Topaz] +-- +6 Spell Damage, +5 Spell Crit Rating +-------------------- +-- ZG enchant +-- +10 Defense Rating/+10 Stamina/+15 Block Value +-------------------- +-- [Glinting Flam Spessarite] +-- +3 Hit Rating and +3 Agility +-------------------- +-- ItemID: 22589 +-- [Atiesh, Greatstaff of the Guardian] warlock version +-- Equip: Increases the spell critical strike rating of all party members within 30 yards by 28. +-------------------- +-- [Brilliant Wizard Oil] +-- Use: While applied to target weapon it increases spell damage by up to 36 and increases spell critical strike rating by 14 . Lasts for 30 minutes. +---------------------------------------------------------------------------------------------------- +-- I redesigned the tooltip scanner using a more locale friendly, 2 pass matching matching algorithm. +-- +-- The first pass searches for the rating number, the patterns are read from L["numberPatterns"] here, +-- " by (%d+)" will match strings like: "Increases defense rating by 16." +-- "%+(%d+)" will match strings like: "+10 Defense Rating" +-- You can add additional patterns if needed, its not limited to 2 patterns. +-- The separators are a table of strings used to break up a line into multiple lines what will be parsed seperately. +-- For example "+3 Hit Rating, +5 Spell Crit Rating" will be split into "+3 Hit Rating" and " +5 Spell Crit Rating" +-- +-- The second pass searches for the rating name, the names are read from L["statList"] here, +-- It will look through the table in order, so you can put common strings at the begining to speed up the search, +-- and longer strings should be listed first, like "spell critical strike" should be listed before "critical strike", +-- this way "spell critical strike" does get matched by "critical strike". +-- Strings need to be in lower case letters, because string.lower is called on lookup +-- +-- IMPORTANT: there may not exist a one-to-one correspondence, meaning you can't just translate this file, +-- but will need to go in game and find out what needs to be put in here. +-- For example, in english I found 3 different strings that maps to CR_CRIT_MELEE: "critical strike", "critical hit" and "crit". +-- You will need to find out every string that represents CR_CRIT_MELEE, and so on. +-- In other languages there may be 5 different strings that should all map to CR_CRIT_MELEE. +-- so please check in game that you have all strings, and not translate directly off this table. +-- +-- Tip1: When doing localizations, I recommend you set debugging to true in RatingBuster.lua +-- Find RatingBuster:SetDebugging(false) and change it to RatingBuster:SetDebugging(true) +-- or you can type /rb debug to enable it in game +-- +-- Tip2: The strings are passed into string.find, so you should escape the magic characters ^$()%.[]*+-? with a % +L["numberPatterns"] = { + {pattern = " um (%d+)", addInfo = "AfterNumber",}, + {pattern = "([%+%-]%d+)", addInfo = "AfterStat",}, + {pattern = "verleiht.-(%d+)", addInfo = "AfterNumber",}, -- for "grant you xx stat" type pattern, ex: Quel'Serrar, Assassination Armor set + {pattern = "(%d+) erhöhen.", addInfo = "AfterNumber",}, -- for "add xx stat" type pattern, ex: Adamantite Sharpening Stone + -- Added [^%%] so that it doesn't match strings like "Increases healing by up to 10% of your total Intellect." [Whitemend Pants] ID: 24261 + -- Added [^|] so that it doesn't match enchant strings (JewelTips) + {pattern = "(%d+)([^%d%%|]+)", addInfo = "AfterStat",}, -- [發光的暗影卓奈石] +6法術傷害及5耐力 +} +L["separators"] = { + "/", " und ", ",", "%. ", " für ", "&", ":", + -- Fix for [Mirror of Truth] + -- Equip: Chance on melee and ranged critical strike to increase your attack power by 1000 for 10 secs. + -- 1000 was falsely detected detected as ranged critical strike + --"increase your", +} +--[[ Rating ID +CR_WEAPON_SKILL = 1; +CR_DEFENSE_SKILL = 2; +CR_DODGE = 3; +CR_PARRY = 4; +CR_BLOCK = 5; +CR_HIT_MELEE = 6; +CR_HIT_RANGED = 7; +CR_HIT_SPELL = 8; +CR_CRIT_MELEE = 9; +CR_CRIT_RANGED = 10; +CR_CRIT_SPELL = 11; +CR_HIT_TAKEN_MELEE = 12; +CR_HIT_TAKEN_RANGED = 13; +CR_HIT_TAKEN_SPELL = 14; +CR_CRIT_TAKEN_MELEE = 15; +CR_CRIT_TAKEN_RANGED = 16; +CR_CRIT_TAKEN_SPELL = 17; +CR_HASTE_MELEE = 18; +CR_HASTE_RANGED = 19; +CR_HASTE_SPELL = 20; +CR_WEAPON_SKILL_MAINHAND = 21; +CR_WEAPON_SKILL_OFFHAND = 22; +CR_WEAPON_SKILL_RANGED = 23; +CR_EXPERTISE = 24; +-- +SPELL_STAT1_NAME = "Stärke" +SPELL_STAT2_NAME = "Beweglichkeit" +SPELL_STAT3_NAME = "Ausdauer" +SPELL_STAT4_NAME = "Intelligenz" +SPELL_STAT5_NAME = "Willenskraft" +--]] +L["statList"] = { + {pattern = string.lower(SPELL_STAT1_NAME), id = SPELL_STAT1_NAME}, -- Strength + {pattern = string.lower(SPELL_STAT2_NAME), id = SPELL_STAT2_NAME}, -- Agility + {pattern = string.lower(SPELL_STAT3_NAME), id = SPELL_STAT3_NAME}, -- Stamina + {pattern = string.lower(SPELL_STAT4_NAME), id = SPELL_STAT4_NAME}, -- Intellect + {pattern = string.lower(SPELL_STAT5_NAME), id = SPELL_STAT5_NAME}, -- Spirit + {pattern = "verteidigungswertung", id = CR_DEFENSE_SKILL}, + {pattern = "ausweichwertung", id = CR_DODGE}, + {pattern = "blockwertung", id = CR_BLOCK}, -- block enchant: "+10 Shield Block Rating" + {pattern = "parierwertung", id = CR_PARRY}, +-- Falls jemand ein Item mit den unten auskommentierten Patterns hat, die nicht der Übersetzung entsprechen soll er mir bescheid sagen, ich habe nix gefunden... + {pattern = "kritische zaubertrefferwertung", id = CR_CRIT_SPELL}, +-- {pattern = "spell critical hit rating", id = CR_CRIT_SPELL}, +-- {pattern = "spell critical rating", id = CR_CRIT_SPELL}, +-- {pattern = "spell crit rating", id = CR_CRIT_SPELL}, + {pattern = "kritische distanztrefferwertung", id = CR_CRIT_RANGED}, +-- {pattern = "ranged critical strike", id = CR_CRIT_RANGED}, -- [Heartseeker Scope] +-- {pattern = "ranged critical hit rating", id = CR_CRIT_RANGED}, +-- {pattern = "ranged critical rating", id = CR_CRIT_RANGED}, +-- {pattern = "ranged crit rating", id = CR_CRIT_RANGED}, + {pattern = "kritische trefferwertung", id = CR_CRIT_MELEE}, +-- {pattern = "critical hit rating", id = CR_CRIT_MELEE}, +-- {pattern = "critical rating", id = CR_CRIT_MELEE}, +-- {pattern = "crit rating", id = CR_CRIT_MELEE}, + + {pattern = "zaubertrefferwertung", id = CR_HIT_SPELL}, + {pattern = "distanztrefferwertung", id = CR_HIT_RANGED}, + {pattern = "trefferwertung", id = CR_HIT_MELEE}, + + {pattern = "abhärtungswertung", id = CR_CRIT_TAKEN_MELEE}, -- resilience is implicitly a rating + + {pattern = "zaubertempowertung", id = CR_HASTE_SPELL}, + {pattern = "distanztempowertung", id = CR_HASTE_RANGED}, + {pattern = "angriffstempowertung", id = CR_HASTE_MELEE}, + {pattern = "nahkampftempowertung", id = CR_HASTE_MELEE}, + {pattern = "tempowertung", id = CR_HASTE_MELEE}, -- [Drums of Battle] + +-- {pattern = "skill rating", id = CR_WEAPON_SKILL}, -- seit 2.3.0 entfernt denke ich.. + {pattern = "waffenkundewertung", id = CR_EXPERTISE}, +-- {pattern = "hit avoidance rating", id = CR_HIT_TAKEN_MELEE}, - seit 2.0.10 gibt es kein item mehr damit + {pattern = "rüstungsdurchschlagwertung", id = CR_ARMOR_PENETRATION}, + {pattern = "meisterschaftswertung", id = CR_MASTERY}, + {pattern = string.lower(ARMOR), id = ARMOR}, + --[[ + {pattern = "dagger skill rating", id = CR_WEAPON_SKILL}, + {pattern = "sword skill rating", id = CR_WEAPON_SKILL}, + {pattern = "two%-handed swords skill rating", id = CR_WEAPON_SKILL}, + {pattern = "axe skill rating", id = CR_WEAPON_SKILL}, + {pattern = "bow skill rating", id = CR_WEAPON_SKILL}, + {pattern = "crossbow skill rating", id = CR_WEAPON_SKILL}, + {pattern = "gun skill rating", id = CR_WEAPON_SKILL}, + {pattern = "feral combat skill rating", id = CR_WEAPON_SKILL}, + {pattern = "mace skill rating", id = CR_WEAPON_SKILL}, + {pattern = "polearm skill rating", id = CR_WEAPON_SKILL}, + {pattern = "staff skill rating", id = CR_WEAPON_SKILL}, + {pattern = "two%-handed axes skill rating", id = CR_WEAPON_SKILL}, + {pattern = "two%-handed maces skill rating", id = CR_WEAPON_SKILL}, + {pattern = "fist weapons skill rating", id = CR_WEAPON_SKILL}, + --]] +} +------------------------- +-- Added info patterns -- +------------------------- +-- $value will be replaced with the number +-- EX: "$value% Crit" -> "+1.34% Crit" +-- EX: "Crit $value%" -> "Crit +1.34%" +L["$value% Crit"] = "$value% krit." +L["$value% Spell Crit"] = "$value% Zauberkrit." +L["$value% Dodge"] = "$value% Ausweichen" +L["$value HP"] = true +L["$value MP"] = true +L["$value AP"] = true +L["$value RAP"] = true +L["$value Dmg"] = "$value Schaden" +L["$value Heal"] = "$value Heilung" +L["$value Armor"] = "$value Rüstung" +L["$value Block"] = "$value Blocken" +L["$value MP5"] = true +L["$value MP5(NC)"] = true +L["$value HP5"] = true +L["$value to be Dodged/Parried"] = "$value wird Ausgewichen/Pariert" +L["$value to be Crit"] = "$value wird kritisch" +L["$value Crit Dmg Taken"] = "$value erlittener Schaden" +L["$value DOT Dmg Taken"] = "$value erlittener Schaden durch DOTs" +L["$value% Parry"] = "$value% Parieren" +-- for hit rating showing both physical and spell conversions +-- (+1.21%, S+0.98%) +-- (+1.21%, +0.98% S) +L["$value Spell"] = "$value Zauber" + +------------------ +-- Stat Summary -- +------------------ +L["Stat Summary"] = "Werteübersicht" \ No newline at end of file diff --git a/RatingBuster/RatingBuster-Locale-enUS.lua b/RatingBuster/RatingBuster-Locale-enUS.lua new file mode 100644 index 0000000..d7d2264 --- /dev/null +++ b/RatingBuster/RatingBuster-Locale-enUS.lua @@ -0,0 +1,726 @@ +--[[ +Name: RatingBuster enUS locale +Revision: $Revision: 294 $ +Translated by: +- Whitetooth (hotdogee [at] gmail [dot] com) +]] + +local L = LibStub("AceLocale-3.0"):NewLocale("RatingBuster", "enUS", true) +if not L then return end +-- This file is coded in UTF-8 +-- If you don't have a editor that can save in UTF-8, I recommend NotePad++ or Ultraedit +---- +-- To translate AceLocale strings, replace true with the translation string +-- Before: L["Show Item ID"] = true, +-- After: L["Show Item ID"] = "顯示物品編號", +--------------- +-- Waterfall -- +--------------- +L["RatingBuster Options"] = true +L["Waterfall-1.0 is required to access the GUI."] = true +L["Enabled"] = true +L["Suspend/resume this addon"] = true +--------------------------- +-- Slash Command Options -- +--------------------------- +L["Always"] = true +L["ALT Key"] = true +L["CTRL Key"] = true +L["SHIFT Key"] = true +L["Never"] = true +L["General Settings"] = true +L["Profiles"] = true +-- /rb win +L["Options Window"] = true +L["Shows the Options Window"] = true +-- /rb hidebzcomp +L["Hide Blizzard Item Comparisons"] = true +L["Disable Blizzard stat change summary when using the built-in comparison tooltip"] = true +-- /rb statmod +L["Enable Stat Mods"] = true +L["Enable support for Stat Mods"] = true +-- /rb avoidancedr +L["Enable Avoidance Diminishing Returns"] = true +L["Dodge, Parry, Hit Avoidance values will be calculated using the avoidance deminishing return formula with your current stats"] = true +-- /rb itemid +L["Show ItemID"] = true +L["Show the ItemID in tooltips"] = true +-- /rb itemlevel +L["Show ItemLevel"] = true +L["Show the ItemLevel in tooltips"] = true +-- /rb usereqlv +L["Use Required Level"] = true +L["Calculate using the required level if you are below the required level"] = true +-- /rb level +L["Set Level"] = true +L["Set the level used in calculations (0 = your level)"] = true +--------------------------------------------------------------------------- +-- /rb rating +L["Rating"] = true +L["Options for Rating display"] = true +-- /rb rating show +L["Show Rating Conversions"] = true +L["Show Rating conversions in tooltips"] = true +-- /rb rating spell +L["Show Spell Hit/Haste"] = true +L["Show Spell Hit/Haste from Hit/Haste Rating"] = true +-- /rb rating physical +L["Show Physical Hit/Haste"] = true +L["Show Physical Hit/Haste from Hit/Haste Rating"] = true +-- /rb rating detail +L["Show Detailed Conversions Text"] = true +L["Show detailed text for Resilience and Expertise conversions"] = true +-- /rb rating exp +L["Expertise Breakdown"] = true +L["Convert Expertise into Dodge Neglect and Parry Neglect"] = true +--------------------------------------------------------------------------- +-- /rb rating color +L["Change Text Color"] = true +L["Changes the color of added text"] = true +-- /rb rating color pick +L["Pick Color"] = true +L["Pick a color"] = true +-- /rb rating color enable +L["Enable Color"] = true +L["Enable colored text"] = true +--------------------------------------------------------------------------- +-- /rb stat +L["Stat Breakdown"] = true +L["Changes the display of base stats"] = true +-- /rb stat show +L["Show Base Stat Conversions"] = true +L["Show base stat conversions in tooltips"] = true +--------------------------------------------------------------------------- +-- /rb stat str +L["Strength"] = true +L["Changes the display of Strength"] = true +-- /rb stat str ap +L["Show Attack Power"] = true +L["Show Attack Power from Strength"] = true +-- /rb stat str block +L["Show Block Value"] = true +L["Show Block Value from Strength"] = true +-- /rb stat str dmg +L["Show Spell Damage"] = true +L["Show Spell Damage from Strength"] = true +-- /rb stat str heal +L["Show Healing"] = true +L["Show Healing from Strength"] = true +-- /rb stat str parry +L["Show Parry"] = true +L["Show Parry from Strength"] = true +--------------------------------------------------------------------------- +-- /rb stat agi +L["Agility"] = true +L["Changes the display of Agility"] = true +-- /rb stat agi crit +L["Show Crit"] = true +L["Show Crit chance from Agility"] = true +-- /rb stat agi dodge +L["Show Dodge"] = true +L["Show Dodge chance from Agility"] = true +-- /rb stat agi ap +L["Show Attack Power"] = true +L["Show Attack Power from Agility"] = true +-- /rb stat agi rap +L["Show Ranged Attack Power"] = true +L["Show Ranged Attack Power from Agility"] = true +-- /rb stat agi armor +L["Show Armor"] = true +L["Show Armor from Agility"] = true +-- /rb stat agi heal +L["Show Healing"] = true +L["Show Healing from Agility"] = true +--------------------------------------------------------------------------- +-- /rb stat sta +L["Stamina"] = true +L["Changes the display of Stamina"] = true +-- /rb stat sta hp +L["Show Health"] = true +L["Show Health from Stamina"] = true +-- /rb stat sta dmg +L["Show Spell Damage"] = true +L["Show Spell Damage from Stamina"] = true +-- /rb stat sta heal +L["Show Healing"] = true +L["Show Healing from Stamina"] = true +-- /rb stat sta ap +L["Show Attack Power"] = true +L["Show Attack Power from Stamina"] = true +--------------------------------------------------------------------------- +-- /rb stat int +L["Intellect"] = true +L["Changes the display of Intellect"] = true +-- /rb stat int spellcrit +L["Show Spell Crit"] = true +L["Show Spell Crit chance from Intellect"] = true +-- /rb stat int mp +L["Show Mana"] = true +L["Show Mana from Intellect"] = true +-- /rb stat int dmg +L["Show Spell Damage"] = true +L["Show Spell Damage from Intellect"] = true +-- /rb stat int heal +L["Show Healing"] = true +L["Show Healing from Intellect"] = true +-- /rb stat int mp5 +L["Show Mana Regen"] = true +L["Show Mana Regen while casting from Intellect"] = true +-- /rb stat int mp5nc +L["Show Mana Regen while NOT casting"] = true +L["Show Mana Regen while NOT casting from Intellect"] = true +-- /rb stat int rap +L["Show Ranged Attack Power"] = true +L["Show Ranged Attack Power from Intellect"] = true +-- /rb stat int armor +L["Show Armor"] = true +L["Show Armor from Intellect"] = true +-- /rb stat int ap +L["Show Attack Power"] = true +L["Show Attack Power from Intellect"] = true +--------------------------------------------------------------------------- +-- /rb stat spi +L["Spirit"] = true +L["Changes the display of Spirit"] = true +-- /rb stat spi mp5 +L["Show Mana Regen"] = true +L["Show Mana Regen while casting from Spirit"] = true +-- /rb stat spi mp5nc +L["Show Mana Regen while NOT casting"] = true +L["Show Mana Regen while NOT casting from Spirit"] = true +-- /rb stat spi hp5 +L["Show Health Regen"] = true +L["Show Health Regen from Spirit"] = true +-- /rb stat spi dmg +L["Show Spell Damage"] = true +L["Show Spell Damage from Spirit"] = true +-- /rb stat spi heal +L["Show Healing"] = true +L["Show Healing from Spirit"] = true +-- /rb stat spi spellcrit +L["Show Spell Crit"] = true +L["Show Spell Crit chance from Spirit"] = true +--------------------------------------------------------------------------- +-- /rb stat armor +L["Armor"] = true +L["Changes the display of Armor"] = true +-- /rb stat armor ap +L["Show Attack Power"] = true +L["Show Attack Power from Armor"] = true +--------------------------------------------------------------------------- +-- /rb sum +L["Stat Summary"] = true +L["Options for stat summary"] = true +-- /rb sum show +L["Show Stat Summary"] = true +L["Show stat summary in tooltips"] = true +-- /rb sum ignore +L["Ignore Settings"] = true +L["Ignore stuff when calculating the stat summary"] = true +-- /rb sum ignore unused +L["Ignore Undesirable Items"] = true +L["Hide stat summary for undesirable items"] = true +-- /rb sum ignore quality +L["Minimum Item Quality"] = true +L["Show stat summary only for selected quality items and up"] = true +-- /rb sum ignore armor +L["Armor Types"] = true +L["Select armor types you want to ignore"] = true +-- /rb sum ignore armor cloth +L["Ignore Cloth"] = true +L["Hide stat summary for all cloth armor"] = true +-- /rb sum ignore armor leather +L["Ignore Leather"] = true +L["Hide stat summary for all leather armor"] = true +-- /rb sum ignore armor mail +L["Ignore Mail"] = true +L["Hide stat summary for all mail armor"] = true +-- /rb sum ignore armor plate +L["Ignore Plate"] = true +L["Hide stat summary for all plate armor"] = true +-- /rb sum ignore equipped +L["Ignore Equipped Items"] = true +L["Hide stat summary for equipped items"] = true +-- /rb sum ignore enchant +L["Ignore Enchants"] = true +L["Ignore enchants on items when calculating the stat summary"] = true +-- /rb sum ignore gem +L["Ignore Gems"] = true +L["Ignore gems on items when calculating the stat summary"] = true +-- /rb sum ignore prismaticSocket +L["Ignore Prismatic Sockets"] = true +L["Ignore gems in prismatic sockets when calculating the stat summary"] = true +-- /rb sum diffstyle +L["Display Style For Diff Value"] = true +L["Display diff values in the main tooltip or only in compare tooltips"] = true +-- /rb sum space +L["Add Empty Line"] = true +L["Add a empty line before or after stat summary"] = true +-- /rb sum space before +L["Add Before Summary"] = true +L["Add a empty line before stat summary"] = true +-- /rb sum space after +L["Add After Summary"] = true +L["Add a empty line after stat summary"] = true +-- /rb sum icon +L["Show Icon"] = true +L["Show the sigma icon before summary listing"] = true +-- /rb sum title +L["Show Title Text"] = true +L["Show the title text before summary listing"] = true +-- /rb sum showzerostat +L["Show Zero Value Stats"] = true +L["Show zero value stats in summary for consistancy"] = true +-- /rb sum calcsum +L["Calculate Stat Sum"] = true +L["Calculate the total stats for the item"] = true +-- /rb sum calcdiff +L["Calculate Stat Diff"] = true +L["Calculate the stat difference for the item and equipped items"] = true +-- /rb sum sort +L["Sort StatSummary Alphabetically"] = true +L["Enable to sort StatSummary alphabetically, disable to sort according to stat type(basic, physical, spell, tank)"] = true +-- /rb sum avoidhasblock +L["Include Block Chance In Avoidance Summary"] = true +L["Enable to include block chance in Avoidance summary, Disable for only dodge, parry, miss"] = true +--------------------------------------------------------------------------- +-- /rb sum basic +L["Stat - Basic"] = true +L["Choose basic stats for summary"] = true +-- /rb sum basic hp +L["Sum Health"] = true +L["Health <- Health, Stamina"] = true +-- /rb sum basic mp +L["Sum Mana"] = true +L["Mana <- Mana, Intellect"] = true +-- /rb sum basic mp5 +L["Sum Mana Regen"] = true +L["Mana Regen <- Mana Regen, Spirit"] = true +-- /rb sum basic mp5nc +L["Sum Mana Regen while not casting"] = true +L["Mana Regen while not casting <- Spirit"] = true +-- /rb sum basic hp5 +L["Sum Health Regen"] = true +L["Health Regen <- Health Regen"] = true +-- /rb sum basic hp5oc +L["Sum Health Regen when out of combat"] = true +L["Health Regen when out of combat <- Spirit"] = true +-- /rb sum basic str +L["Sum Strength"] = true +L["Strength Summary"] = true +-- /rb sum basic agi +L["Sum Agility"] = true +L["Agility Summary"] = true +-- /rb sum basic sta +L["Sum Stamina"] = true +L["Stamina Summary"] = true +-- /rb sum basic int +L["Sum Intellect"] = true +L["Intellect Summary"] = true +-- /rb sum basic spi +L["Sum Spirit"] = true +L["Spirit Summary"] = true +-- /rb sum basic mastery +L["Sum Mastery"] = true +L["Mastery Summary"] = true +-- /rb sum basic masteryrating +L["Sum Mastery Rating"] = true +L["Mastery Rating Summary"] = true +--------------------------------------------------------------------------- +-- /rb sum physical +L["Stat - Physical"] = true +L["Choose physical damage stats for summary"] = true +-- /rb sum physical ap +L["Sum Attack Power"] = true +L["Attack Power <- Attack Power, Strength, Agility"] = true +-- /rb sum physical rap +L["Sum Ranged Attack Power"] = true +L["Ranged Attack Power <- Ranged Attack Power, Intellect, Attack Power, Strength, Agility"] = true +-- /rb sum physical fap +L["Sum Feral Attack Power"] = true +L["Feral Attack Power <- Feral Attack Power, Attack Power, Strength, Agility"] = true +-- /rb sum physical hit +L["Sum Hit Chance"] = true +L["Hit Chance <- Hit Rating"] = true +-- /rb sum physical hitrating +L["Sum Hit Rating"] = true +L["Hit Rating Summary"] = true +-- /rb sum physical crit +L["Sum Crit Chance"] = true +L["Crit Chance <- Crit Rating, Agility"] = true +-- /rb sum physical critrating +L["Sum Crit Rating"] = true +L["Crit Rating Summary"] = true +-- /rb sum physical haste +L["Sum Haste"] = true +L["Haste <- Haste Rating"] = true +-- /rb sum physical hasterating +L["Sum Haste Rating"] = true +L["Haste Rating Summary"] = true +-- /rb sum physical rangedhit +L["Sum Ranged Hit Chance"] = true +L["Ranged Hit Chance <- Hit Rating, Ranged Hit Rating"] = true +-- /rb sum physical rangedhitrating +L["Sum Ranged Hit Rating"] = true +L["Ranged Hit Rating Summary"] = true +-- /rb sum physical rangedcrit +L["Sum Ranged Crit Chance"] = true +L["Ranged Crit Chance <- Crit Rating, Agility, Ranged Crit Rating"] = true +-- /rb sum physical rangedcritrating +L["Sum Ranged Crit Rating"] = true +L["Ranged Crit Rating Summary"] = true +-- /rb sum physical rangedhaste +L["Sum Ranged Haste"] = true +L["Ranged Haste <- Haste Rating, Ranged Haste Rating"] = true +-- /rb sum physical rangedhasterating +L["Sum Ranged Haste Rating"] = true +L["Ranged Haste Rating Summary"] = true +-- /rb sum physical maxdamage +L["Sum Weapon Max Damage"] = true +L["Weapon Max Damage Summary"] = true +-- /rb sum physical weapondps +--L["Sum Weapon DPS"] = true +--L["Weapon DPS Summary"] = true +-- /rb sum physical wpn +L["Sum Weapon Skill"] = true +L["Weapon Skill <- Weapon Skill Rating"] = true +-- /rb sum physical exp +L["Sum Expertise"] = true +L["Expertise <- Expertise Rating"] = true +-- /rb sum physical exprating +L["Sum Expertise Rating"] = true +L["Expertise Rating Summary"] = true +--------------------------------------------------------------------------- +-- /rb sum spell +L["Stat - Spell"] = true +L["Choose spell damage and healing stats for summary"] = true +-- /rb sum spell dmg +L["Sum Spell Damage"] = true +L["Spell Damage <- Spell Damage, Intellect, Spirit, Stamina"] = true +-- /rb sum spell dmgholy +L["Sum Holy Spell Damage"] = true +L["Holy Spell Damage <- Holy Spell Damage, Spell Damage, Intellect, Spirit"] = true +-- /rb sum spell dmgarcane +L["Sum Arcane Spell Damage"] = true +L["Arcane Spell Damage <- Arcane Spell Damage, Spell Damage, Intellect"] = true +-- /rb sum spell dmgfire +L["Sum Fire Spell Damage"] = true +L["Fire Spell Damage <- Fire Spell Damage, Spell Damage, Intellect, Stamina"] = true +-- /rb sum spell dmgnature +L["Sum Nature Spell Damage"] = true +L["Nature Spell Damage <- Nature Spell Damage, Spell Damage, Intellect"] = true +-- /rb sum spell dmgfrost +L["Sum Frost Spell Damage"] = true +L["Frost Spell Damage <- Frost Spell Damage, Spell Damage, Intellect"] = true +-- /rb sum spell dmgshadow +L["Sum Shadow Spell Damage"] = true +L["Shadow Spell Damage <- Shadow Spell Damage, Spell Damage, Intellect, Spirit, Stamina"] = true +-- /rb sum spell heal +L["Sum Healing"] = true +L["Healing <- Healing, Intellect, Spirit, Agility, Strength"] = true +-- /rb sum spell crit +L["Sum Spell Crit Chance"] = true +L["Spell Crit Chance <- Spell Crit Rating, Intellect"] = true +-- /rb sum spell hit +L["Sum Spell Hit Chance"] = true +L["Spell Hit Chance <- Spell Hit Rating"] = true +-- /rb sum spell haste +L["Sum Spell Haste"] = true +L["Spell Haste <- Spell Haste Rating"] = true +-- /rb sum spell pen +L["Sum Penetration"] = true +L["Spell Penetration Summary"] = true +-- /rb sum spell hitrating +L["Sum Spell Hit Rating"] = true +L["Spell Hit Rating Summary"] = true +-- /rb sum spell critrating +L["Sum Spell Crit Rating"] = true +L["Spell Crit Rating Summary"] = true +-- /rb sum spell hasterating +L["Sum Spell Haste Rating"] = true +L["Spell Haste Rating Summary"] = true +--------------------------------------------------------------------------- +-- /rb sum tank +L["Stat - Tank"] = true +L["Choose tank stats for summary"] = true +-- /rb sum tank armor +L["Sum Armor"] = true +L["Armor <- Armor from items and bonuses"] = true +-- /rb sum tank dodge +L["Sum Dodge Chance"] = true +L["Dodge Chance <- Dodge Rating, Agility"] = true +-- /rb sum tank parry +L["Sum Parry Chance"] = true +L["Parry Chance <- Parry Rating"] = true +-- /rb sum tank block +L["Sum Block Chance"] = true +L["Block Chance <- Block Rating"] = true +-- /rb sum tank neglectdodge +L["Sum Dodge Neglect"] = true +L["Dodge Neglect <- Expertise"] = true +-- /rb sum tank neglectparry +L["Sum Parry Neglect"] = true +L["Parry Neglect <- Expertise"] = true +-- /rb sum tank resarcane +L["Sum Arcane Resistance"] = true +L["Arcane Resistance Summary"] = true +-- /rb sum tank resfire +L["Sum Fire Resistance"] = true +L["Fire Resistance Summary"] = true +-- /rb sum tank resnature +L["Sum Nature Resistance"] = true +L["Nature Resistance Summary"] = true +-- /rb sum tank resfrost +L["Sum Frost Resistance"] = true +L["Frost Resistance Summary"] = true +-- /rb sum tank resshadow +L["Sum Shadow Resistance"] = true +L["Shadow Resistance Summary"] = true +-- /rb sum tank dodgerating +L["Sum Dodge Rating"] = true +L["Dodge Rating Summary"] = true +-- /rb sum tank parryrating +L["Sum Parry Rating"] = true +L["Parry Rating Summary"] = true +-- /rb sum tank blockrating +L["Sum Block Rating"] = true +L["Block Rating Summary"] = true +-- /rb sum tank res +L["Sum Resilience"] = true +L["Resilience Summary"] = true +-- /rb sum tank tp +L["Sum TankPoints"] = true +L["TankPoints <- Health, Total Reduction"] = true +-- /rb sum tank tr +L["Sum Total Reduction"] = true +L["Total Reduction <- Armor, Dodge, Parry, Block, MobMiss, MobCrit, MobCrush, DamageTakenMods"] = true +-- /rb sum tank avoid +L["Sum Avoidance"] = true +L["Avoidance <- Dodge, Parry, MobMiss, Block(Optional)"] = true +--------------------------------------------------------------------------- +-- /rb sum gemset +L["Gem Set"] = true +L["Select a gem set to configure"] = true +L["Default Gem Set 1"] = true +L["Default Gem Set 2"] = true +L["Default Gem Set 3"] = true +-- /rb sum gem +L["Auto fill empty gem slots"] = true +-- /rb sum gem red +L["Red Socket"] = EMPTY_SOCKET_RED +L["ItemID or Link of the gem you would like to auto fill"] = true +L[""] = true +L["|cffffff7f%s|r is now set to |cffffff7f[%s]|r"] = true +L["Invalid input: %s. ItemID or ItemLink required."] = true +L["Queried server for Gem: %s. Try again in 5 secs."] = true +-- /rb sum gem yellow +L["Yellow Socket"] = EMPTY_SOCKET_YELLOW +-- /rb sum gem blue +L["Blue Socket"] = EMPTY_SOCKET_BLUE +-- /rb sum gem meta +L["Meta Socket"] = EMPTY_SOCKET_META +-- /rb sum gem2 +L["Second set of default gems which can be toggled with a modifier key"] = true +L["Can't use the same modifier as Gem Set 3"] = true +-- /rb sum gem2 key +L["Toggle Key"] = true +L["Use this key to toggle alternate gems"] = true +-- /rb sum gem3 +L["Third set of default gems which can be toggled with a modifier key"] = true +L["Can't use the same modifier as Gem Set 2"] = true + +----------------------- +-- Item Level and ID -- +----------------------- +L["ItemLevel: "] = true +L["ItemID: "] = true +----------------------- +-- Matching Patterns -- +----------------------- +-- Items to check -- +-------------------- +-- [Potent Ornate Topaz] +-- +6 Spell Damage, +5 Spell Crit Rating +-------------------- +-- ZG enchant +-- +10 Defense Rating/+10 Stamina/+15 Block Value +-------------------- +-- [Glinting Flam Spessarite] +-- +3 Hit Rating and +3 Agility +-------------------- +-- ItemID: 22589 +-- [Atiesh, Greatstaff of the Guardian] warlock version +-- Equip: Increases the spell critical strike rating of all party members within 30 yards by 28. +-------------------- +-- [Brilliant Wizard Oil] +-- Use: While applied to target weapon it increases spell damage by up to 36 and increases spell critical strike rating by 14 . Lasts for 30 minutes. +---------------------------------------------------------------------------------------------------- +-- I redesigned the tooltip scanner using a more locale friendly, 2 pass matching matching algorithm. +-- +-- The first pass searches for the rating number, the patterns are read from L["numberPatterns"] here, +-- " by (%d+)" will match strings like: "Increases defense rating by 16." +-- "%+(%d+)" will match strings like: "+10 Defense Rating" +-- You can add additional patterns if needed, its not limited to 2 patterns. +-- The separators are a table of strings used to break up a line into multiple lines what will be parsed seperately. +-- For example "+3 Hit Rating, +5 Spell Crit Rating" will be split into "+3 Hit Rating" and " +5 Spell Crit Rating" +-- +-- The second pass searches for the rating name, the names are read from L["statList"] here, +-- It will look through the table in order, so you can put common strings at the begining to speed up the search, +-- and longer strings should be listed first, like "spell critical strike" should be listed before "critical strike", +-- this way "spell critical strike" does get matched by "critical strike". +-- Strings need to be in lower case letters, because string.lower is called on lookup +-- +-- IMPORTANT: there may not exist a one-to-one correspondence, meaning you can't just translate this file, +-- but will need to go in game and find out what needs to be put in here. +-- For example, in english I found 3 different strings that maps to CR_CRIT_MELEE: "critical strike", "critical hit" and "crit". +-- You will need to find out every string that represents CR_CRIT_MELEE, and so on. +-- In other languages there may be 5 different strings that should all map to CR_CRIT_MELEE. +-- so please check in game that you have all strings, and not translate directly off this table. +-- +-- Tip1: When doing localizations, I recommend you set debugging to true in RatingBuster.lua +-- Find RatingBuster:SetDebugging(false) and change it to RatingBuster:SetDebugging(true) +-- or you can type /rb debug to enable it in game +-- +-- Tip2: The strings are passed into string.find, so you should escape the magic characters ^$()%.[]*+-? with a % +L["numberPatterns"] = { + {pattern = " by (%d+)", addInfo = "AfterNumber",}, + {pattern = "([%+%-]%d+)[^%%]", addInfo = "AfterStat",}, + --{pattern = "grant.-(%d+)", addInfo = "AfterNumber",}, -- for "grant you xx stat" type pattern, ex: Quel'Serrar ID:18348, Assassination Armor set + --{pattern = "add.-(%d+)", addInfo = "AfterNumber",}, -- for "add xx stat" type pattern, ex: Adamantite Sharpening Stone ID:23529 + -- Added [^%%] so that it doesn't match strings like "Increases healing by up to 10% of your total Intellect." [Whitemend Pants] ID:24261 + -- Added [^|] so that it doesn't match enchant strings (JewelTips) + {pattern = "(%d+)([^%d%%|]+)", addInfo = "AfterStat",}, -- [發光的暗影卓奈石] +6法術傷害及5耐力 +} +L["separators"] = { + "/", " and ", ",", "%. ", " for ", "&", ":", + -- Fix for [Mirror of Truth] + -- Equip: Chance on melee and ranged critical strike to increase your attack power by 1000 for 10 secs. + -- 1000 was falsely detected detected as ranged critical strike + "increase your", +} +--[[ Rating ID +CR_WEAPON_SKILL = 1; +CR_DEFENSE_SKILL = 2; +CR_DODGE = 3; +CR_PARRY = 4; +CR_BLOCK = 5; +CR_HIT_MELEE = 6; +CR_HIT_RANGED = 7; +CR_HIT_SPELL = 8; +CR_CRIT_MELEE = 9; +CR_CRIT_RANGED = 10; +CR_CRIT_SPELL = 11; +CR_HIT_TAKEN_MELEE = 12; +CR_HIT_TAKEN_RANGED = 13; +CR_HIT_TAKEN_SPELL = 14; +CR_CRIT_TAKEN_MELEE = 15; +CR_CRIT_TAKEN_RANGED = 16; +CR_CRIT_TAKEN_SPELL = 17; +CR_HASTE_MELEE = 18; +CR_HASTE_RANGED = 19; +CR_HASTE_SPELL = 20; +CR_WEAPON_SKILL_MAINHAND = 21; +CR_WEAPON_SKILL_OFFHAND = 22; +CR_WEAPON_SKILL_RANGED = 23; +CR_EXPERTISE = 24; +-- +SPELL_STAT1_NAME = "Strength" +SPELL_STAT2_NAME = "Agility" +SPELL_STAT3_NAME = "Stamina" +SPELL_STAT4_NAME = "Intellect" +SPELL_STAT5_NAME = "Spirit" +--]] +L["statList"] = { + {pattern = string.lower(SPELL_STAT1_NAME), id = SPELL_STAT1_NAME}, -- Strength + {pattern = string.lower(SPELL_STAT2_NAME), id = SPELL_STAT2_NAME}, -- Agility + {pattern = string.lower(SPELL_STAT3_NAME), id = SPELL_STAT3_NAME}, -- Stamina + {pattern = string.lower(SPELL_STAT4_NAME), id = SPELL_STAT4_NAME}, -- Intellect + {pattern = string.lower(SPELL_STAT5_NAME), id = SPELL_STAT5_NAME}, -- Spirit + {pattern = "defense rating", id = CR_DEFENSE_SKILL}, + {pattern = "dodge rating", id = CR_DODGE}, + {pattern = "block rating", id = CR_BLOCK}, -- block enchant: "+10 Shield Block Rating" + {pattern = "parry rating", id = CR_PARRY}, + + {pattern = "spell critical strike rating", id = CR_CRIT_SPELL}, + {pattern = "spell critical hit rating", id = CR_CRIT_SPELL}, + {pattern = "spell critical rating", id = CR_CRIT_SPELL}, + {pattern = "spell crit rating", id = CR_CRIT_SPELL}, + {pattern = "ranged critical strike rating", id = CR_CRIT_RANGED}, + {pattern = "ranged critical strike", id = CR_CRIT_RANGED}, -- [Heartseeker Scope] + {pattern = "ranged critical hit rating", id = CR_CRIT_RANGED}, + {pattern = "ranged critical rating", id = CR_CRIT_RANGED}, + {pattern = "ranged crit rating", id = CR_CRIT_RANGED}, + {pattern = "critical strike rating", id = CR_CRIT_MELEE}, + {pattern = "critical hit rating", id = CR_CRIT_MELEE}, + {pattern = "critical rating", id = CR_CRIT_MELEE}, + {pattern = "crit rating", id = CR_CRIT_MELEE}, + + {pattern = "spell hit rating", id = CR_HIT_SPELL}, + {pattern = "ranged hit rating", id = CR_HIT_RANGED}, + {pattern = "hit rating", id = CR_HIT_MELEE}, + + {pattern = "resilience", id = CR_CRIT_TAKEN_MELEE}, -- resilience is implicitly a rating + + {pattern = "spell haste rating", id = CR_HASTE_SPELL}, + {pattern = "ranged haste rating", id = CR_HASTE_RANGED}, + {pattern = "haste rating", id = CR_HASTE_MELEE}, + {pattern = "speed rating", id = CR_HASTE_MELEE}, -- [Drums of Battle] + + {pattern = "skill rating", id = CR_WEAPON_SKILL}, + {pattern = "expertise rating", id = CR_EXPERTISE}, + + {pattern = "hit avoidance rating", id = CR_HIT_TAKEN_MELEE}, + {pattern = "armor penetration rating", id = CR_ARMOR_PENETRATION}, + {pattern = "mastery rating", id = CR_MASTERY}, + {pattern = string.lower(ARMOR), id = ARMOR}, + --[[ + {pattern = "dagger skill rating", id = CR_WEAPON_SKILL}, + {pattern = "sword skill rating", id = CR_WEAPON_SKILL}, + {pattern = "two%-handed swords skill rating", id = CR_WEAPON_SKILL}, + {pattern = "axe skill rating", id = CR_WEAPON_SKILL}, + {pattern = "bow skill rating", id = CR_WEAPON_SKILL}, + {pattern = "crossbow skill rating", id = CR_WEAPON_SKILL}, + {pattern = "gun skill rating", id = CR_WEAPON_SKILL}, + {pattern = "feral combat skill rating", id = CR_WEAPON_SKILL}, + {pattern = "mace skill rating", id = CR_WEAPON_SKILL}, + {pattern = "polearm skill rating", id = CR_WEAPON_SKILL}, + {pattern = "staff skill rating", id = CR_WEAPON_SKILL}, + {pattern = "two%-handed axes skill rating", id = CR_WEAPON_SKILL}, + {pattern = "two%-handed maces skill rating", id = CR_WEAPON_SKILL}, + {pattern = "fist weapons skill rating", id = CR_WEAPON_SKILL}, + --]] +} +------------------------- +-- Added info patterns -- +------------------------- +-- $value will be replaced with the number +-- EX: "$value% Crit" -> "+1.34% Crit" +-- EX: "Crit $value%" -> "Crit +1.34%" +L["$value% Crit"] = true +L["$value% Spell Crit"] = true +L["$value% Dodge"] = true +L["$value HP"] = true +L["$value MP"] = true +L["$value AP"] = true +L["$value RAP"] = true +L["$value Dmg"] = true +L["$value Heal"] = true +L["$value Armor"] = true +L["$value Block"] = true +L["$value MP5"] = true +L["$value MP5(NC)"] = true +L["$value HP5"] = true +L["$value to be Dodged/Parried"] = true +L["$value to be Crit"] = true +L["$value Crit Dmg Taken"] = true +L["$value DOT Dmg Taken"] = true +L["$value% Parry"] = true +-- for hit rating showing both physical and spell conversions +-- (+1.21%, S+0.98%) +-- (+1.21%, +0.98% S) +L["$value Spell"] = true + +------------------ +-- Stat Summary -- +------------------ +L["Stat Summary"] = true \ No newline at end of file diff --git a/RatingBuster/RatingBuster-Locale-esES.lua b/RatingBuster/RatingBuster-Locale-esES.lua new file mode 100644 index 0000000..bb8d03d --- /dev/null +++ b/RatingBuster/RatingBuster-Locale-esES.lua @@ -0,0 +1,699 @@ +--[[ +Name: RatingBuster esES locale +Revision: $Revision: 294 $ +Translated by: +- carahuevo@Curse +- kaiemg +]] + +local L = LibStub("AceLocale-3.0"):NewLocale("RatingBuster", "esES") +if not L then return end +-- This file is coded in UTF-8 +-- If you don't have a editor that can save in UTF-8, I recommend Ultraedit +---- +-- To translate AceLocale strings, replace true with the translation string +-- Before: L["Show Item ID"] = true, +-- After: L["Show Item ID"] = "顯示物品編號", +--------------- +-- Waterfall -- +--------------- +L["RatingBuster Options"] = "Opciones RatingBuster" +L["Waterfall-1.0 is required to access the GUI."] = "Se requiere Waterfall para acceder a la GUI." +L["Enabled"] = "Activado" +L["Suspend/resume this addon"] = "Parar/Continuar este accesorio" +--------------------------- +-- Slash Command Options -- +--------------------------- +--L["General Settings"] = true +--L["Profiles"] = true +-- /rb optionswin +L["Options Window"] = "Ventana opciones" +L["Shows the Options Window"] = "Muestra la ventana de opciones" +-- /rb statmod +L["Enable Stat Mods"] = "Habilitar Stat Mods" +L["Enable support for Stat Mods"] = "Habilita el soporte para Stat Mods" +-- /rb avoidancedr +L["Enable Avoidance Diminishing Returns"] = "Habilita evitacion de rendimientos decrecientes" +L["Dodge, Parry, Hit Avoidance values will be calculated using the avoidance deminishing return formula with your current stats"] = "Rendimientos decrecientes" +-- /rb itemid +L["Show ItemID"] = "Mostrar ItemID" +L["Show the ItemID in tooltips"] = "Mostrar ItemID en los tooltips" +-- /rb itemlevel +L["Show ItemLevel"] = "Mostrar NivelItem" +L["Show the ItemLevel in tooltips"] = "Muestra el NivelItem en los tooltips" +-- /rb usereqlv +L["Use Required Level"] = "Usar nivel requerido" +L["Calculate using the required level if you are below the required level"] = "Calcular apartir del nivel requerido si estas por debajo" +-- /rb setlevel +L["Set Level"] = "Establecer nivel" +L["Set the level used in calculations (0 = your level)"] = "Establece el nivel usado en los caculos (0=tu nivel)" +------------------------------------------------------------------------------- +-- /rb rating +L["Rating"] = "Indices" +L["Options for Rating display"] = "Opciones de visualizacion de indices" +-- /rb rating show +L["Show Rating Conversions"] = "Mostrar conversion de indices" +L["Show Rating conversions in tooltips"] = "Mostrar conversion de indices en tooltips" +-- /rb rating spell +--L["Show Spell Hit/Haste"] = true +--L["Show Spell Hit/Haste from Hit/Haste Rating"] = true +-- /rb rating physical +--L["Show Physical Hit/Haste"] = true +--L["Show Physical Hit/Haste from Hit/Haste Rating"] = true +-- /rb rating detail +L["Show Detailed Conversions Text"] = "Mostrar texto detallado conversiones" +L["Show detailed text for Resilience and Expertise conversions"] = "Mostrar texto detallado de conversiones de Temple y Pericia" +-- /rb rating exp -- 2.3.0 +L["Expertise Breakdown"] = "Desglose Pericia" +L["Convert Expertise into Dodge Neglect and Parry Neglect"] = "Convierte Pericia en fallo Esquivar y fallo Parar" +--------------------------------------------------------------------------- +-- /rb rating color +L["Change Text Color"] = "Cambiar color texto" +L["Changes the color of added text"] = "Cambia el color del texto anadido" +-- /rb rating color pick +L["Pick Color"] = "Coge color" +L["Pick a color"] = "Coge un color" +-- /rb rating color enable +L["Enable Color"] = "Habilitar color" +L["Enable colored text"] = "Habilitar texto coloreado" +--------------------------------------------------------------------------------------- +-- /rb stat +L["Stat Breakdown"] = "Desglose Estadisticas" +L["Changes the display of base stats"] = "Cambia la visualizacion de las estad. base" +-- /rb stat show +L["Show Base Stat Conversions"] = "Mostrar conversiones estad. base" +L["Show base stat conversions in tooltips"] = "Muestra las conversiones de estad. base en los tooltip" +----------------------------------------------------------------------------------------- +-- /rb stat str +L["Strength"] = "Fuerza" +L["Changes the display of Strength"] = "Cambia la visualizacion de Fuerza" +-- /rb stat str ap +L["Show Attack Power"] = "Motrar Poder Ataque" +L["Show Attack Power from Strength"] = "Motrar Poder Ataque de Fuerza" +-- /rb stat str block +L["Show Block Value"] = "Mostrar Valor Bloqueo" +L["Show Block Value from Strength"] = "Muestra el Valor Bloqueo de Fuerza" +-- /rb stat str dmg +L["Show Spell Damage"] = "Mostrar Dano Hech" +L["Show Spell Damage from Strength"] = "Muestra el Dano de Hechizo de Fuerza" +-- /rb stat str heal +L["Show Healing"] = "Mostrar Sanacion" +L["Show Healing from Strength"] = "Muestra la Sanacion de Fuerza" +-- /rb stat str parry +L["Show Parry"] = "Mostrar Parada" +L["Show Parry from Strength"] = "Muestra Parada de Fuerza" +--------------------------------------------------------------------------- + -- /rb stat agi +L["Agility"] = "Agilidad" +L["Changes the display of Agility"] = "Cambia la visualizacion de Agilidad" +-- /rb stat agi crit +L["Show Crit"] = "Mostrar Crit" +L["Show Crit chance from Agility"] = "Muestra la prob. de critico de Agilidad" +-- /rb stat agi dodge +L["Show Dodge"] = "Mostrar Esquivar" +L["Show Dodge chance from Agility"] = "Muestra la prob. de Esquivar de Agilidad" +-- /rb stat agi ap +L["Show Attack Power"] = "Mostrar Poder Ataque" +L["Show Attack Power from Agility"] = "Muestra Poder de Ataque de Agilidad" +-- /rb stat agi rap +L["Show Ranged Attack Power"] = "Mostrar Poder Ataque Dist" +L["Show Ranged Attack Power from Agility"] = "Muestra Poder de Ataque a distancia de Agilidad" +-- /rb stat agi armor +L["Show Armor"] = "Mostrar Armadura" +L["Show Armor from Agility"] = "Muestra la Armadura de Agilidad" +-- /rb stat agi heal +L["Show Healing"] = "Mostrar Sanacion" +L["Show Healing from Agility"] = "Muestra Sanacion de Agilidad" +---------------------------------------------------------------------------- +-- /rb stat sta +L["Stamina"] = "Aguante" +L["Changes the display of Stamina"] = "Cambia la visualizacion de Aguante" +-- /rb stat sta hp +L["Show Health"] = "Mostrar Salud" +L["Show Health from Stamina"] = "Muestra la Salud de Aguante" +-- /rb stat sta dmg +L["Show Spell Damage"] = "Mostrar Dano Hech" +L["Show Spell Damage from Stamina"] = "Muestra el Dano de Hechizo de Aguante" +-- /rb stat sta heal +L["Show Healing"] = "Mostrar Sanacion" +L["Show Healing from Stamina"] = "Muestra sanacion de Aguante" +-- /rb stat sta ap +L["Show Attack Power"] = "Mostrar Poder de Ataque" +L["Show Attack Power from Stamina"] = "Muestra Poder de Ataque de Aguante" +--------------------------------------------------------------------------- +-- /rb stat int +L["Intellect"] = "Intelecto" +L["Changes the display of Intellect"] = "Cambia la visualizacion de Intelecto" +-- /rb stat int spellcrit +L["Show Spell Crit"] = "Mostrar Crit Hech" +L["Show Spell Crit chance from Intellect"] = "Muestra la prob. de Crit. de Hechizo de Intelecto" +-- /rb stat int mp +L["Show Mana"] = "Mostrar Mana" +L["Show Mana from Intellect"] = "Muestra el Mana de Intelecto" +-- /rb stat int dmg +L["Show Spell Damage"] = "Mostrar Dano Hech" +L["Show Spell Damage from Intellect"] = "Muestra el Dano de Hechizo de Intelecto" +-- /rb stat int heal +L["Show Healing"] = "Mostrar Sanacion" +L["Show Healing from Intellect"] = "Muestra la Sanacion de Intelecto" +-- /rb stat int mp5 +L["Show Mana Regen"] = "Mostrar Regen.Mana" +L["Show Mana Regen while casting from Intellect"] = "Muestra la Regen.Mana de Intelecto" +-- /rb stat int mp5nc +--L["Show Mana Regen while NOT casting"] = true +--L["Show Mana Regen while NOT casting from Intellect"] = true +-- /rb stat int rap +L["Show Ranged Attack Power"] = "Mostrar Poder Ataque Dist" +L["Show Ranged Attack Power from Intellect"] = "Muestra el Poder Ataque Dist de Intelecto" +-- /rb stat int armor +L["Show Armor"] = "Mostrar Armadura" +L["Show Armor from Intellect"] = "Muestra la Armadura de Intelecto" +-- /rb stat int ap +L["Show Attack Power"] = "Mostrar Poder de Ataque" +L["Show Attack Power from Intellect"] = "Muestra Poder de Ataque de Intelecto" +------------------------------------------------------------------------------------- +-- /rb stat spi +L["Spirit"] = "Espiritu" +L["Changes the display of Spirit"] = "Cambia la visualizacion de Espiritu" +-- /rb stat spi mp5 +L["Show Mana Regen"] = "Mostrar Regen.Mana" +L["Show Mana Regen while casting from Spirit"] = "Muestra la Regen.Mana de Espiritu" +-- /rb stat spi mp5nc +L["Show Mana Regen while NOT casting"] = "Mostrar Regen.Mana NO lanzando" +L["Show Mana Regen while NOT casting from Spirit"] = "Muestra la Regen.Mana NO lanzando de Espiritu" +-- /rb stat spi hp5 +L["Show Health Regen"] = "Mostrar Regen.Salud" +L["Show Health Regen from Spirit"] = "Muestra la Regen. de Salud de Espiritu" +-- /rb stat spi dmg +L["Show Spell Damage"] = "Mostrar Dano Hech" +L["Show Spell Damage from Spirit"] = "Muestra el Dano de Hechizos de Espiritu" +-- /rb stat spi heal +L["Show Healing"] = "Mostrar Sanacion" +L["Show Healing from Spirit"] = "Muestra la Sanacion de Espiritu" +---------------------------------------------------------------------------------------- +-- /rb sum +L["Stat Summary"] = "Resumen Estad" +L["Options for stat summary"] = "Opciones de Resumen Estad." +-- /rb sum show +L["Show Stat Summary"] = "Mostrar Resumen Estad" +L["Show stat summary in tooltips"] = "Muestra el Resumen de Estad. en los tooltips" +-- /rb sum ignore +L["Ignore Settings"] = "Ignorar opciones" +L["Ignore stuff when calculating the stat summary"] = "Ignorar los datos cuando se calcule el resumen de estad." +-- /rb sum ignore unused +--L["Ignore Undesirable Items"] = true +--L["Hide stat summary for undesirable items"] = true +-- /rb sum ignore quality +--L["Minimum Item Quality"] = true +--L["Show stat summary only for selected quality items and up"] = true +-- /rb sum ignore armor +--L["Armor Types"] = true +--L["Select armor types you want to ignore"] = true +-- /rb sum ignore armor cloth +--L["Ignore Cloth"] = true +--L["Hide stat summary for all cloth armor"] = true +-- /rb sum ignore armor leather +--L["Ignore Leather"] = true +--L["Hide stat summary for all leather armor"] = true +-- /rb sum ignore armor mail +--L["Ignore Mail"] = true +--L["Hide stat summary for all mail armor"] = true +-- /rb sum ignore armor plate +--L["Ignore Plate"] = true +--L["Hide stat summary for all plate armor"] = true +-- /rb sum ignore equipped +L["Ignore Equipped Items"] = "Ignorar items equipados" +L["Hide stat summary for equipped items"] = "Ocultar resumen estad. para los items equipados" +-- /rb sum ignore enchant +L["Ignore Enchants"] = "Ignorar encantamientos" +L["Ignore enchants on items when calculating the stat summary"] = "Ignorar encantamientos en items cuando se calcule el resumen de estad." +-- /rb sum ignore gem +L["Ignore Gems"] = "Ignorar gemas" +L["Ignore gems on items when calculating the stat summary"] = "Ignorar gemas en items cuando se calcule el resumen de estad." +-- /rb sum diffstyle +L["Display Style For Diff Value"] = "Mostrar estilo para el valor de diferencia" +L["Display diff values in the main tooltip or only in compare tooltips"] = "Mostrar diferencia valores en el tooltip principal o solo en los de comparacion" +-- /rb sum space +L["Add Empty Line"] = "Anadir linea vacia" +L["Add a empty line before or after stat summary"] = "Anade una linea vacia antes o despues del resumen" +-- /rb sum space before +L["Add Before Summary"] = "Anadir antes del resumen" +L["Add a empty line before stat summary"] = "Anade una linea vacia antes del resumen" +-- /rb sum space after +L["Add After Summary"] = "Anadir despues del resumen" +L["Add a empty line after stat summary"] = "Anade una linea vacia despues del resumen" +-- /rb sum icon +L["Show Icon"] = "Mostrar icono" +L["Show the sigma icon before summary listing"] = "Muestra el icono de sumatorio antes del listado resumen" +-- /rb sum title +L["Show Title Text"] = "Mostrar texto titulo" +L["Show the title text before summary listing"] = "Muestra el titulo antes del listado resumen" +-- /rb sum showzerostat +L["Show Zero Value Stats"] = "Mostrar estad. valor cero" +L["Show zero value stats in summary for consistancy"] = "Muestra las estad. de valor cero por consistencia" +-- /rb sum calcsum +L["Calculate Stat Sum"] = "Calcula suma de estad." +L["Calculate the total stats for the item"] = "Calcula el total de las estad. para el item" +-- /rb sum calcdiff +L["Calculate Stat Diff"] = "Calcular dif. estad." +L["Calculate the stat difference for the item and equipped items"] = "Calcula la diferencia para el item y los items equipados" +-- /rb sum sort +L["Sort StatSummary Alphabetically"] = "Ordenar estad. alfabeticamente" +L["Enable to sort StatSummary alphabetically, disable to sort according to stat type(basic, physical, spell, tank)"] = "Ordena alfabeticamente el resumen, deshabilita para ordenar de acuerdo a la estad. (basica, fisica, hechizo, tanque)" +-- /rb sum avoidhasblock +L["Include Block Chance In Avoidance Summary"] = "Incluir prob. de bloqueo en resumen de Eludir" +L["Enable to include block chance in Avoidance summary, Disable for only dodge, parry, miss"] = "Incluye prob. de bloqueo en resumen de Eludir, Deshabilita para solo esquivar, parar y fallar" +---------------------------------------------------------------------------------------- +-- /rb sum basic +L["Stat - Basic"] = "Estad. - Basica" +L["Choose basic stats for summary"] = "Escoge las estad. basicas para el resumen" +-- /rb sum basic hp +L["Sum Health"] = "Suma salud" +L["Health <- Health, Stamina"] = "Salud <- Salud, Aguante" +-- /rb sum basic mp +L["Sum Mana"] = "Suma Mana" +L["Mana <- Mana, Intellect"] = "Mana <- Mana, Intelecto" +-- /rb sum basic mp5 +L["Sum Mana Regen"] = "Suma Mana regenerado" +L["Mana Regen <- Mana Regen, Spirit"] = "Suma Mana reg <- Mana Regen, Espiritu" +-- /rb sum basic mp5nc +L["Sum Mana Regen while not casting"] = "Res. Regen. mana mientras no se lanza" +L["Mana Regen while not casting <- Spirit"] = "Regen. mana mientras no se lanza <- Espiritu" +-- /rb sum basic hp5 +L["Sum Health Regen"] = "Res. Regen. salud" +L["Health Regen <- Health Regen"] = "Regen. salud <- Regen. salud" +-- /rb sum basic hp5oc +L["Sum Health Regen when out of combat"] = "Res. Regen. salud fuera de combate" +L["Health Regen when out of combat <- Spirit"] = "Regen. salud fuera de combate <- Espiritu" +-- /rb sum basic str +L["Sum Strength"] = "Res. Fuerza" +L["Strength Summary"] = "Resumen Fuerza" +-- /rb sum basic agi +L["Sum Agility"] = "Res. Agilidad" +L["Agility Summary"] = "Resumen Agilidad" +-- /rb sum basic sta +L["Sum Stamina"] = "Res. Aguante" +L["Stamina Summary"] = "Resumen Aguante" +-- /rb sum basic int +L["Sum Intellect"] = "Res. Intelecto" +L["Intellect Summary"] = "Resumen Intelecto" +-- /rb sum basic spi +L["Sum Spirit"] = "Res. Espiritu" +L["Spirit Summary"] = "Resumen Espiritu" +-- /rb sum basic mastery +--L["Sum Mastery"] = "" +--L["Mastery Summary"] = "" +-- /rb sum basic masteryrating +--L["Sum Mastery Rating"] = "" +--L["Mastery Rating Summary"] = "" +---------------------------------------------------------------------------------------- +-- /rb sum physical +L["Stat - Physical"] = "Datos - Fisicas" +L["Choose physical damage stats for summary"] = "Escoge datos de dano fisico para resumen" +-- /rb sum physical ap +L["Sum Attack Power"] = "Res. Poder Ataque" +L["Attack Power <- Attack Power, Strength, Agility"] = "Poder Ataque <- Poder Ataque, Fuerza, Agilidad" +-- /rb sum physical rap +L["Sum Ranged Attack Power"] = "Res. P.Ataque Distancia" +L["Ranged Attack Power <- Ranged Attack Power, Intellect, Attack Power, Strength, Agility"] = "P.Ataque Distancia <- P.Ataque Distancia, Intelecto, P.Ataque, Fuerza, Agilidad" +-- /rb sum physical fap +L["Sum Feral Attack Power"] = "Res. P.Ataque feral" +L["Feral Attack Power <- Feral Attack Power, Attack Power, Strength, Agility"] = "P.Ataque feral <- P.Ataque feral, P.Ataque, Fuerza, Agilidad" +-- /rb sum physical hit +L["Sum Hit Chance"] = "Res. prob. Golpe" +--L["Hit Chance <- Hit Rating"] = "prob. Golpe <- Indice Golpe, Indice pericia" +-- /rb sum physical hitrating +L["Sum Hit Rating"] = "Res. Indice Golpe" +L["Hit Rating Summary"] = "Resumen Indice Golpe" +-- /rb sum physical crit +L["Sum Crit Chance"] = "Res. Prob. Crit." +--L["Crit Chance <- Crit Rating, Agility"] = "Prob.Crit <- Crit, Agilidad, Indice Pericia" +-- /rb sum physical critrating +L["Sum Crit Rating"] = "Res. Indice Critico" +L["Crit Rating Summary"] = "Resumen Indice Critico" +-- /rb sum physical haste +L["Sum Haste"] = "Res. Celeridad" +L["Haste <- Haste Rating"] = "Resumen Celeridad" +-- /rb sum physical hasterating +L["Sum Haste Rating"] = "Res. Indice Celeridad" +L["Haste Rating Summary"] = "Resumen Indice Celeridad" +-- /rb sum physical rangedhit +L["Sum Ranged Hit Chance"] = "Res. Prob. Golpe a Distancia" +-- --L["Ranged Hit Chance <- Hit Rating, Ranged Hit Rating"] = true +-- /rb sum physical rangedhitrating +L["Sum Ranged Hit Rating"] = "Res. Indice Golpe a Distancia" +-- L["Ranged Hit Rating Summary"] = true +-- /rb sum physical rangedcrit +L["Sum Ranged Crit Chance"] = "Res. Prob. Critico a Distancia" +-- --L["Ranged Crit Chance <- Crit Rating, Agility, Ranged Crit Rating"] = true +-- /rb sum physical rangedcritrating +-- L["Sum Ranged Crit Rating"] = true +-- L["Ranged Crit Rating Summary"] = true +-- /rb sum physical rangedhaste +-- L["Sum Ranged Haste"] = true +-- L["Ranged Haste <- Haste Rating, Ranged Haste Rating"] = true +-- /rb sum physical rangedhasterating +-- L["Sum Ranged Haste Rating"] = true +-- L["Ranged Haste Rating Summary"] = true +-- /rb sum physical maxdamage +L["Sum Weapon Max Damage"] = "Res. Max Dano Arma" +L["Weapon Max Damage Summary"] = "Resumen de Maximo Dano Arma" +-- /rb sum physical weapondps +--L["Sum Weapon DPS"] = true +--L["Weapon DPS Summary"] = true +-- /rb sum physical wpn +L["Sum Weapon Skill"] = "Res. Habilidad Arma" +L["Weapon Skill <- Weapon Skill Rating"] = "Habilidad Arma <- Indice Habilidad Arma" +-- /rb sum physical exp -- 2.3.0 +L["Sum Expertise"] = "Res. Pericia" +L["Expertise <- Expertise Rating"] = "Pericia <- Indice Pericia" +-- /rb sum physical exprating +--L["Sum Expertise Rating"] = true +--L["Expertise Rating Summary"] = true +---------------------------------------------------------------------------------------- +-- /rb sum spell +L["Stat - Spell"] = "Datos - Hechizo" +L["Choose spell damage and healing stats for summary"] = "Escoge datos de dano y sanacion de hechizo para resumen" +-- /rb sum spell dmg +L["Sum Spell Damage"] = "Res. Dano Hech." +L["Spell Damage <- Spell Damage, Intellect, Spirit, Stamina"] = "Dano Hech. <- Dano Hech., Intelecto, Espiritu, Aguante" +-- /rb sum spell dmgholy +L["Sum Holy Spell Damage"] = "Res. Dano Hech. Sagrado" +L["Holy Spell Damage <- Holy Spell Damage, Spell Damage, Intellect, Spirit"] = "Dano Hech. Sagrado <- Dano Hech. Sagrado, Dano Hech., Intelecto, Espiritu" +-- /rb sum spell dmgarcane +L["Sum Arcane Spell Damage"] = "Res. Dano Hech. Arcano" +L["Arcane Spell Damage <- Arcane Spell Damage, Spell Damage, Intellect"] = "Dano Hech. Arcano <- Dano Hech. Arcano, Dano Hech., Intelecto" +-- /rb sum spell dmgfire +L["Sum Fire Spell Damage"] = "Res. Dano Hech. Fuego" +L["Fire Spell Damage <- Fire Spell Damage, Spell Damage, Intellect, Stamina"] = "Dano Hech. Arcano <- Dano Hech. Arcano, Dano Hech., Intelecto, Aguante" +-- /rb sum spell dmgnature +L["Sum Nature Spell Damage"] = "Res. Dano Hech. Naturaleza" +L["Nature Spell Damage <- Nature Spell Damage, Spell Damage, Intellect"] = "Dano Hech. Naturaleza <- Dano Hech. Naturaleza, Dano Hech., Intelecto" +-- /rb sum spell dmgfrost +L["Sum Frost Spell Damage"] = "Res. Dano Hech. Frio" +L["Frost Spell Damage <- Frost Spell Damage, Spell Damage, Intellect"] = "Dano Hech. Frio <- Dano Hech. Frio, Dano Hech., Intelecto" +-- /rb sum spell dmgshadow +L["Sum Shadow Spell Damage"] = "Res. Dano Hech. Sombras" +L["Shadow Spell Damage <- Shadow Spell Damage, Spell Damage, Intellect, Spirit, Stamina"] = "Dano Hech. Sombras <- Dano Hech. Sombras, Dano Hech., Intelecto, Espiritu, Aguante" +-- /rb sum spell heal +L["Sum Healing"] = "Res. Sanacion" +L["Healing <- Healing, Intellect, Spirit, Agility, Strength"] = "Sanacion <- Sanacion, Intelecto, Espiritu, Agilidad, Fuerza" +-- /rb sum spell crit +L["Sum Spell Crit Chance"] = "Res. prob. Critico Hech." +L["Spell Crit Chance <- Spell Crit Rating, Intellect"] = "prob. Critico Hech. <- Indice Critico Hech., Intelecto" +-- /rb sum spell hit +L["Sum Spell Hit Chance"] = "Res. prob. Golpe Hech." +L["Spell Hit Chance <- Spell Hit Rating"] = "prob. Golpe Hech. <- Indice Golpe Hech." +-- /rb sum spell haste +L["Sum Spell Haste"] = "Res. velocidad Hech." +L["Spell Haste <- Spell Haste Rating"] = "Velocidad Hech. <- Indice Velocidad Hech." +-- /rb sum spell pen +L["Sum Penetration"] = "Res. Penetracion" +L["Spell Penetration Summary"] = "Resument Penetracion Hechizo" +-- /rb sum spell hitspellrating +L["Sum Spell Hit Rating"] = "Res. Golpe Hech." +L["Spell Hit Rating Summary"] = "Resumen Golpe Hech." +-- /rb sum spell critspellrating +L["Sum Spell Crit Rating"] = "Res. Indice Critico Hech." +L["Spell Crit Rating Summary"] = "Resumen Indice Critico Hech." +-- /rb sum spell hastespellrating +L["Sum Spell Haste Rating"] = "Res. Indice Velocidad Hech." +L["Spell Haste Rating Summary"] = "Resumen Indice Velocidad Hech." +---------------------------------------------------------------------------------------- +-- /rb sum tank +L["Stat - Tank"] = "Datos - Tanque" +L["Choose tank stats for summary"] = "Escoge datos de tanque para resumen" +-- /rb sum tank armor +L["Sum Armor"] = "Res. Armadura" +--L["Armor <- Armor from items and bonuses"] = "Armadura <- Armadura de items, Armadura de bonus, Agilidad, Intelecto" +-- /rb sum tank dodge +L["Sum Dodge Chance"] = "Res. prob. Esquivar" +--L["Dodge Chance <- Dodge Rating, Agility"] = "Prob. Esquivar <- Indice Esquivar, Agilidad, Indice Defensa" +-- /rb sum tank parry +L["Sum Parry Chance"] = "Res. prob. Parar" +--L["Parry Chance <- Parry Rating"] = "Prob. Parar <- Indice Parar, Indice Defensa" +-- /rb sum tank block +L["Sum Block Chance"] = "Res. prob Bloqueo" +--L["Block Chance <- Block Rating"] = "Prob. Bloqueo <- Indice Bloqueo, Indice Defensa" +-- /rb sum tank neglectdodge +L["Sum Dodge Neglect"] = "Res. fallo Esquivar" +--L["Dodge Neglect <- Expertise"] = "Fallo Esquivar <- Pericia, Indice habilidad arma" +-- /rb sum tank neglectparry +L["Sum Parry Neglect"] = "Res. fallo Parar" +--L["Parry Neglect <- Expertise"] = "Fallo Parar <- Pericia, Indice habilidad arma" +-- /rb sum tank resarcane +L["Sum Arcane Resistance"] = "Res. Resist. Arcana" +L["Arcane Resistance Summary"] = "Resumen Resistencia Arcana" +-- /rb sum tank resfire +L["Sum Fire Resistance"] = "Res. Resist. Fuego" +L["Fire Resistance Summary"] = "Resumen Resistencia Fuego" +-- /rb sum tank resnature +L["Sum Nature Resistance"] = "Res. Resist. Naturaleza" +L["Nature Resistance Summary"] = "Resumen Resistencia Naturaleza" +-- /rb sum tank resfrost +L["Sum Frost Resistance"] = "Res. Resist. Frio" +L["Frost Resistance Summary"] = "Resumen Resistencia Frio" +-- /rb sum tank resshadow +L["Sum Shadow Resistance"] = "Res. Resist. Sombras" +L["Shadow Resistance Summary"] = "Resumen Resistencia Sombras" +-- /rb sum tank dodgerating +L["Sum Dodge Rating"] = "Res. Indice Esquivar" +L["Dodge Rating Summary"] = "Resumen Indice Esquivar" +-- /rb sum tank parryrating +L["Sum Parry Rating"] = "Res. Indice Parar" +L["Parry Rating Summary"] = "Resumen Indice Parar" +-- /rb sum tank blockrating +L["Sum Block Rating"] = "Res. Indice Bloquear" +L["Block Rating Summary"] = "Resumen Indice Bloquear" +-- /rb sum tank res +L["Sum Resilience"] = "Res. Temple" +L["Resilience Summary"] = "Resumen Temple" +-- /rb sum tank tp +L["Sum TankPoints"] = "Res. Ptos. Tanque" +L["TankPoints <- Health, Total Reduction"] = "Ptos. Tanque <- Salud, Total Reduccion" +-- /rb sum tank tr +L["Sum Total Reduction"] = "Res. Total Reduccion" +--L["Total Reduction <- Armor, Dodge, Parry, Block, MobMiss, MobCrit, MobCrush, DamageTakenMods"] = "Total Reduccion <- Armadura, Esquivar, Parar, Bloquear, Valor bloqueo, Defensa, Temple, FalloEnemigo, CriticoEnemigo, AplastamientoEnemigo, Modifics.DanoRecibido" +-- /rb sum tank avoid +L["Sum Avoidance"] = "Res. Elusion" +L["Avoidance <- Dodge, Parry, MobMiss, Block(Optional)"] = "Elusion <- Esquivar, Parar, FalloEnemigo, Bloqueo(Opcional)" +---------------------------------------------------------------------------------------- +-- /rb sum gemset +-- L["Gem Set"] = true +-- L["Select a gem set to configure"] = true +-- L["Default Gem Set 1"] = true +-- L["Default Gem Set 2"] = true +-- L["Default Gem Set 3"] = true +-- /rb sum gem +L["Auto fill empty gem slots"] = "Rellena automaticamente los huecos de gemas" +-- /rb sum gem red +L["Red Socket"] = EMPTY_SOCKET_RED +--L["ItemID or Link of the gem you would like to auto fill"] = true +--L[""] = true +--L["|cffffff7f%s|r is now set to |cffffff7f[%s]|r"] = true +--L["Queried server for Gem: %s. Try again in 5 secs."] = true +-- /rb sum gem yellow +L["Yellow Socket"] = EMPTY_SOCKET_YELLOW +-- /rb sum gem blue +L["Blue Socket"] = EMPTY_SOCKET_BLUE +-- /rb sum gem meta +L["Meta Socket"] = EMPTY_SOCKET_META +-- /rb sum gem2 +--L["Second set of default gems which can be toggled with a modifier key"] = true +--L["Can't use the same modifier as Gem Set 3"] = true +-- /rb sum gem2 key +--L["Toggle Key"] = true +--L["Use this key to toggle alternate gems"] = true +-- /rb sum gem3 +--L["Third set of default gems which can be toggled with a modifier key"] = true +--L["Can't use the same modifier as Gem Set 2"] = true + +----------------------- +-- Item Level and ID -- +----------------------- +L["ItemLevel: "] = "NivelItem" +L["ItemID: "] = "IDItem" +----------------------- +-- Matching Patterns -- +----------------------- +-- Items to check -- +-------------------- +-- [Potent Ornate Topaz] +-- +6 Spell Damage, +5 Spell Crit Rating +-------------------- +-- ZG enchant +-- +10 Defense Rating/+10 Stamina/+15 Block Value +-------------------- +-- [Glinting Flam Spessarite] +-- +3 Hit Rating and +3 Agility +-------------------- +-- ItemID: 22589 +-- [Atiesh, Greatstaff of the Guardian] warlock version +-- Equip: Increases the spell critical strike rating of all party members within 30 yards by 28. +-------------------- +-- [Brilliant Wizard Oil] +-- Use: While applied to target weapon it increases spell damage by up to 36 and increases spell critical strike rating by 14 . Lasts for 30 minutes. +---------------------------------------------------------------------------------------------------- +-- I redesigned the tooltip scanner using a more locale friendly, 2 pass matching matching algorithm. +-- +-- The first pass searches for the rating number, the patterns are read from L["numberPatterns"] here, +-- " by (%d+)" will match strings like: "Increases defense rating by 16." +-- "%+(%d+)" will match strings like: "+10 Defense Rating" +-- You can add additional patterns if needed, its not limited to 2 patterns. +-- The separators are a table of strings used to break up a line into multiple lines what will be parsed seperately. +-- For example "+3 Hit Rating, +5 Spell Crit Rating" will be split into "+3 Hit Rating" and " +5 Spell Crit Rating" +-- +-- The second pass searches for the rating name, the names are read from L["statList"] here, +-- It will look through the table in order, so you can put common strings at the begining to speed up the search, +-- and longer strings should be listed first, like "spell critical strike" should be listed before "critical strike", +-- this way "spell critical strike" does get matched by "critical strike". +-- Strings need to be in lower case letters, because string.lower is called on lookup +-- +-- IMPORTANT: there may not exist a one-to-one correspondence, meaning you can't just translate this file, +-- but will need to go in game and find out what needs to be put in here. +-- For example, in english I found 3 different strings that maps to CR_CRIT_MELEE: "critical strike", "critical hit" and "crit". +-- You will need to find out every string that represents CR_CRIT_MELEE, and so on. +-- In other languages there may be 5 different strings that should all map to CR_CRIT_MELEE. +-- so please check in game that you have all strings, and not translate directly off this table. +-- +-- Tip1: When doing localizations, I recommend you set debugging to true in RatingBuster.lua +-- Find RatingBuster:SetDebugging(false) and change it to RatingBuster:SetDebugging(true) +-- or you can type /rb debug to enable it in game +-- +-- Tip2: The strings are passed into string.find, so you should escape the magic characters ^$()%.[]*+-? with a % +L["numberPatterns"] = { + {pattern = " (%d+)", addInfo = "AfterNumber",}, + {pattern = "([%+%-]%d+)", addInfo = "AfterStat",}, + {pattern = "Otorga.-(%d+)", addInfo = "AfterNumber",}, -- for "grant you xx stat" type pattern, ex: Quel'Serrar, Assassination Armor set + {pattern = "Aumenta.-(%d+) p.", addInfo = "AfterNumber",}, -- for "add xx stat" type pattern, ex: Adamantite Sharpening Stone + {pattern = "Mejora.-(%d+) p.", addInfo = "AfterNumber",}, -- for "add xx stat" type pattern, ex: Adamantite Sharpening Stone + {pattern = "(%d+)([^%d%%|]+)", addInfo = "AfterStat",}, -- [????????] +6?????5?? +} +L["separators"] = { + "/", " y ", ",", "%. ", " durante ", "&" +} +--[[ Rating ID +CR_WEAPON_SKILL = 1; +CR_DEFENSE_SKILL = 2; +CR_DODGE = 3; +CR_PARRY = 4; +CR_BLOCK = 5; +CR_HIT_MELEE = 6; +CR_HIT_RANGED = 7; +CR_HIT_SPELL = 8; +CR_CRIT_MELEE = 9; +CR_CRIT_RANGED = 10; +CR_CRIT_SPELL = 11; +CR_HIT_TAKEN_MELEE = 12; +CR_HIT_TAKEN_RANGED = 13; +CR_HIT_TAKEN_SPELL = 14; +CR_CRIT_TAKEN_MELEE = 15; +CR_CRIT_TAKEN_RANGED = 16; +CR_CRIT_TAKEN_SPELL = 17; +CR_HASTE_MELEE = 18; +CR_HASTE_RANGED = 19; +CR_HASTE_SPELL = 20; +CR_WEAPON_SKILL_MAINHAND = 21; +CR_WEAPON_SKILL_OFFHAND = 22; +CR_WEAPON_SKILL_RANGED = 23; +CR_EXPERTISE = 24; +-- +SPELL_STAT1_NAME = "Strength" +SPELL_STAT2_NAME = "Agility" +SPELL_STAT3_NAME = "Stamina" +SPELL_STAT4_NAME = "Intellect" +SPELL_STAT5_NAME = "Spirit" +--]] +L["statList"] = { + {pattern = string.lower(SPELL_STAT1_NAME), id = SPELL_STAT1_NAME}, -- Strength + {pattern = string.lower(SPELL_STAT2_NAME), id = SPELL_STAT2_NAME}, -- Agility + {pattern = string.lower(SPELL_STAT3_NAME), id = SPELL_STAT3_NAME}, -- Stamina + {pattern = string.lower(SPELL_STAT4_NAME), id = SPELL_STAT4_NAME}, -- Intellect + {pattern = string.lower(SPELL_STAT5_NAME), id = SPELL_STAT5_NAME}, -- Spirit + {pattern = "tu \195\173ndice de defensa", id = CR_DEFENSE_SKILL}, + {pattern = "tu \195\173ndice de esquivar", id = CR_DODGE}, + {pattern = "tu \195\173ndice de bloqueo", id = CR_BLOCK}, -- block enchant: "+10 Shield Block Rating" + {pattern = "tu \195\173ndice de parada", id = CR_PARRY}, + + {pattern = "tu \195\173ndice de golpe cr\195\173tico", id = CR_CRIT_SPELL}, + {pattern = "tu\195\173ndice de golpe cr\195\173tico", id = CR_CRIT_RANGED}, + {pattern = "tu \195\173ndice de golpe cr\195\173tico", id = CR_CRIT_MELEE}, + --{pattern = "tu \195\173ndice de golpe", id = CR_CRIT_MELEE}, + + {pattern = "tu \195\173ndice de golpe", id = CR_HIT_SPELL}, + {pattern = "tu \195\173ndice de golpe a distancia", id = CR_HIT_RANGED}, + {pattern = "tu \195\173ndice de golpe cuerpo a cuerpo", id = CR_HIT_MELEE}, + {pattern = "tu \195\173ndice de golpe", id = CR_HIT_MELEE}, + + {pattern = "tu \195\173ndice de temple", id = CR_CRIT_TAKEN_MELEE}, -- resilience is implicitly a rating + + {pattern = "tu \195\173ndice de celeridad", id = CR_HASTE_SPELL}, + {pattern = "tu \195\173ndice de celeridad a distancia", id = CR_HASTE_RANGED}, + {pattern = "tu \195\173ndice de celeridad con cuerpo a cuerpo", id = CR_HASTE_MELEE}, + {pattern = "tu \195\173ndice de celeridad", id = CR_HASTE_MELEE}, + {pattern = "Aumenta el \195\173ndice de celeridad de los miembros del grupo cercanos hasta", id = CR_HASTE_MELEE}, -- [Drums of Battle] + + {pattern = "tu \195\173ndice de habilidad", id = CR_WEAPON_SKILL}, + {pattern = "tu \195\173ndice de pericia", id = CR_EXPERTISE}, + + {pattern = "tu \195\173ndice de evasion de golpes cuerpo a cuerpo", id = CR_HIT_TAKEN_MELEE}, + {pattern = "tu \195\173ndice de evasion", id = CR_HIT_TAKEN_MELEE}, + {pattern = "tu índice de penetración de armadurap", id = CR_ARMOR_PENETRATION}, + {pattern = string.lower(ARMOR), id = ARMOR}, + --[[ + {pattern = "\195\173ndice de habilidad con dagas", id = CR_WEAPON_SKILL}, + {pattern = "\195\173ndice de habilidad con espadas", id = CR_WEAPON_SKILL}, + {pattern = "\195\173ndice de habilidad con espadas de dos manos", id = CR_WEAPON_SKILL}, + {pattern = "\195\173ndice de habilidad con hachas", id = CR_WEAPON_SKILL}, + {pattern = "\195\173ndice de habilidad con arcos", id = CR_WEAPON_SKILL}, + {pattern = "\195\173ndice de habilidad con ballesta", id = CR_WEAPON_SKILL}, + {pattern = "\195\173ndice de habilidad con armas de fuego", id = CR_WEAPON_SKILL}, + {pattern = "\195\173ndice de habilidad en combate feral", id = CR_WEAPON_SKILL}, + {pattern = "tu \195\173ndice de habilidad con mazas", id = CR_WEAPON_SKILL}, + {pattern = "\195\173ndice de habilidad con armas de asta", id = CR_WEAPON_SKILL}, + {pattern = "\195\173ndice de habilidad con bastones", id = CR_WEAPON_SKILL}, + {pattern = "\195\173ndice de habilidad con hachas de dos manos", id = CR_WEAPON_SKILL}, + {pattern = "\195\173ndice de habilidad con mazas de dos manos", id = CR_WEAPON_SKILL}, + {pattern = "\195\173ndice de habilidad sin armas", id = CR_WEAPON_SKILL}, + --]] +} +------------------------- +-- Added info patterns -- +------------------------- +-- $value will be replaced with the number +-- EX: "$value% Crit" -> "+1.34% Crit" +-- EX: "Crit $value%" -> "Crit +1.34%" +L["$value% Crit"] = "$value% Crit" +L["$value% Spell Crit"] = "$value% Crit hechizos" +L["$value% Dodge"] = "$value% Esquivar" +L["$value HP"] = "$value Vida" +L["$value MP"] = "$value Mana" +L["$value AP"] = "$value P.At" +L["$value RAP"] = "$value P.At Dist" +L["$value Dmg"] = "$value Dano" +L["$value Heal"] = "$value Sanacion" +L["$value Armor"] = "$value Armadura" +L["$value Block"] = "$value Bloqueo" +L["$value MP5"] = "$value Mana/5sec" +L["$value MP5(NC)"] = "$value Mana/5sec(SL)" +L["$value HP5"] = "$value Vida/5sec" +L["$value to be Dodged/Parried"] = "$value Esquivado/Parado" +L["$value to be Crit"] = "$value recibir Crit" +L["$value Crit Dmg Taken"] = "$value Dano crit recib" +L["$value DOT Dmg Taken"] = "$value Dano por tiempo recib" +L["$value% Parry"] = "$value Parada" +-- for hit rating showing both physical and spell conversions +-- (+1.21%, S+0.98%) +-- (+1.21%, +0.98% S) +L["$value Spell"] = "$value Hech." + +------------------ +-- Stat Summary -- +------------------ +L["Stat Summary"] = "Resumen estad." + + +local MX = LibStub("AceLocale-3.0"):NewLocale("RatingBuster", "esMX") +for k, v in pairs(L) do + MX[k] = v +end \ No newline at end of file diff --git a/RatingBuster/RatingBuster-Locale-frFR.lua b/RatingBuster/RatingBuster-Locale-frFR.lua new file mode 100644 index 0000000..b1a9a4d --- /dev/null +++ b/RatingBuster/RatingBuster-Locale-frFR.lua @@ -0,0 +1,660 @@ +--[[ +Name: RatingBuster frFR locale (incomplete) +Revision: $Revision: 294 $ +Translated by: +- Tixu@Curse, Silaor and renchap +]] + +local L = LibStub("AceLocale-3.0"):NewLocale("RatingBuster", "frFR") +if not L then return end +-- This file is coded in UTF-8 +-- If you don't have a editor that can save in UTF-8, I recommend NotePad++ or Ultraedit +---- +-- To translate AceLocale strings, replace true with the translation string +-- Before: L["Show Item ID"] = true, +-- After: L["Show Item ID"] = "顯示物品編號", +--------------- +-- Waterfall -- +--------------- +L["RatingBuster Options"] = "Options de RatingBuster" +L["Waterfall-1.0 is required to access the GUI."] = "Waterfall-1.0 est nécessaire pour accéder au GUI." +L["Enabled"] = "Activé" +L["Suspend/resume this addon"] = "Active ou non cet addon." +--------------------------- +-- Slash Command Options -- +--------------------------- +L["Always"] = "Toujours" +L["ALT Key"] = "Touche ALT" +L["CTRL Key"] = "Touche CTRL" +L["SHIFT Key"] = "Touche MAJ" +L["Never"] = "Jamais" +L["General Settings"] = "Paramètres généraux" +L["Profiles"] = "Profiles" +-- /rb win +L["Options Window"] = "Options de la fenêtre" +L["Shows the Options Window"] = "Affiche la fenêtre des options" +-- /rb hidebzcomp +L["Hide Blizzard Item Comparisons"] = "Masquer la comparaison d'objet de Blizzard" +--L["Disable Blizzard stat change summary when using the built-in comparison tooltip"] = true -- à traduire +-- /rb statmod +L["Enable Stat Mods"] = "Activer les Stat Mods" +L["Enable support for Stat Mods"] = "Activer le support pour Stat Mods" +-- /rb avoidancedr +--L["Enable Avoidance Diminishing Returns"] = true -- à traduire +--L["Dodge, Parry, Hit Avoidance values will be calculated using the avoidance deminishing return formula with your current stats"] = true -- à traduire +-- /rb itemid +L["Show ItemID"] = "Afficher l'ID de l'objet" +L["Show the ItemID in tooltips"] = "Affiche l'ID d'un objet dans l'infobulle." +-- /rb itemlevel +L["Show ItemLevel"] = "Afficher le niveau de l'objet" +L["Show the ItemLevel in tooltips"] = "Affiche le niveau de l'objet dans l'infobulle." +-- /rb usereqlv +L["Use Required Level"] = "Utiliser le niveau requis" +L["Calculate using the required level if you are below the required level"] = "Effectue les calculs en utilisant le niveau requis par l'objet si il n'est pas atteint." +-- /rb level +L["Set Level"] = "Définir le niveau" +L["Set the level used in calculations (0 = your level)"] = "Définir le niveau utilisé dans les calculs (0 = votre niveau)." +--------------------------------------------------------------------------- +-- /rb rating +L["Rating"] = "Score" +L["Options for Rating display"] = "Options pour l'affichage des scores" +-- /rb rating show +L["Show Rating Conversions"] = "Afficher la conversion des scores" +L["Show Rating conversions in tooltips"] = "Affiche dans l'infobulle les gains apportés par le score." +-- /rb rating spell +--L["Show Spell Hit/Haste"] = true +--L["Show Spell Hit/Haste from Hit/Haste Rating"] = true +-- /rb rating physical +--L["Show Physical Hit/Haste"] = true +--L["Show Physical Hit/Haste from Hit/Haste Rating"] = true +-- /rb rating detail +--L["Show Detailed Conversions Text"] = true -- à traduire +--L["Show detailed text for Resilience and Expertise conversions"] = true -- à traduire +--L["Defense Breakdown"] = true -- à traduire +--L["Convert Defense into Crit Avoidance, Hit Avoidance, Dodge, Parry and Block"] = true +--L["Weapon Skill Breakdown"] = true -- à traduire +--L["Convert Weapon Skill into Crit, Hit, Dodge Neglect, Parry Neglect and Block Neglect"] = true -- à traduire +-- /rb rating exp +--L["Expertise Breakdown"] = true -- à traduire +--L["Convert Expertise into Dodge Neglect and Parry Neglect"] = true -- à traduire +--------------------------------------------------------------------------- +-- /rb rating color +L["Change Text Color"] = "Modifier la couleur du texte" +--L["Changes the color of added text"] = true -- à traduire +-- /rb rating color pick +L["Pick Color"] = "Sélectionner une couleur" +L["Pick a color"] = "Choisissez une couleur" +-- /rb rating color enable +L["Enable Color"] = true +L["Enable colored text"] = true +--------------------------------------------------------------------------- +-- /rb stat +--L["Stat Breakdown"] = true -- à traduire +L["Changes the display of base stats"] = "Modifie l'affichage des caractéristiques de base." +-- /rb stat show +L["Show Base Stat Conversions"] = "Afficher les conversions pour les statistiques de base" +L["Show base stat conversions in tooltips"] = "Affiche les conversions pour les statistiques de base dans l'infobulle." +--------------------------------------------------------------------------- +-- /rb stat str +L["Strength"] = "Force" +L["Changes the display of Strength"] = "Modifie l'affichage de la force." +-- /rb stat str ap +L["Show Attack Power"] = "Afficher la puissance d'attaque" +L["Show Attack Power from Strength"] = "Affiche la puissance d'attaque apporté par la force." +-- /rb stat str block +L["Show Block Value"] = "Afficher le bloquage" +L["Show Block Value from Strength"] = "Affiche le bloquage apporté par la force." +-- /rb stat str dmg +L["Show Spell Damage"] = "Afficher les dégats des sorts" +L["Show Spell Damage from Strength"] = "Affiche le bonus de dégats des sorts apporté par la force." +-- /rb stat str heal +L["Show Healing"] = "Afficher les soins" +L["Show Healing from Strength"] = "Affiche le bonus aux soins apporté par la force." +-- /rb stat str parry +L["Show Parry"] = "Afficher la parade" +L["Show Parry from Strength"] = "Affiche la parade apporté par la force." +--------------------------------------------------------------------------- +-- /rb stat agi +L["Agility"] = "Agilité" +L["Changes the display of Agility"] = "Modifie l'affichage de l'agilité" +-- /rb stat agi crit +L["Show Crit"] = "Afficher le critique" +L["Show Crit chance from Agility"] = "Affiche le pourcentage de critique apporté par l'agilité." +-- /rb stat agi dodge +L["Show Dodge"] = "Afficher l'esquive" +L["Show Dodge chance from Agility"] = "Affiche le pourcentage d'esquive apporté par l'agilité." +-- /rb stat agi ap +L["Show Attack Power"] = "Afficher la puissance d'attaque" +L["Show Attack Power from Agility"] = "Affiche la puissance d'attaque apporté par l'agilité." +-- /rb stat agi rap +L["Show Ranged Attack Power"] = "Afficher la puissance d'attaque à distance" +L["Show Ranged Attack Power from Agility"] = "Affiche la puissance d'attaque à distance apporté par l'agilité." +-- /rb stat agi armor +L["Show Armor"] = "Afficher l'armure" +L["Show Armor from Agility"] = "Afficher l'armure apporté par l'agilité" +-- /rb stat agi heal +L["Show Healing"] = "Afficher les soins" +L["Show Healing from Agility"] = "Affiche la parade apporté par l'agilité." +--------------------------------------------------------------------------- +-- /rb stat sta +L["Stamina"] = "Endurance" +L["Changes the display of Stamina"] = "Modifie l'affichage de l'endurance" +-- /rb stat sta hp +L["Show Health"] = "Afficher les points de vies" +L["Show Health from Stamina"] = "Affiche les points de vies apporté par l'endurance." +-- /rb stat sta dmg +L["Show Spell Damage"] = "Afficher les dégats des sorts" +L["Show Spell Damage from Stamina"] = "Affiche le bonus de dégats des sorts apporté par l'endurance." +-- /rb stat sta heal +L["Show Healing"] = "Afficher les soins" +L["Show Healing from Stamina"] = "Affiche les soins apporté par l'endurance." +-- /rb stat sta ap +L["Show Attack Power"] = "Afficher la puissance d'attaque" +L["Show Attack Power from Stamina"] = "Affiche la puissance d'attaque apporté par l'endurance." +--------------------------------------------------------------------------- +-- /rb stat int +L["Intellect"] = "Intelligence" +L["Changes the display of Intellect"] = "Modifie l'affichage de l'intelligence" +-- /rb stat int spellcrit +L["Show Spell Crit"] = "Afficher le critique des sorts" +L["Show Spell Crit chance from Intellect"] = "Affiche le critique des sorts apporté par l'intelligence." +-- /rb stat int mp +L["Show Mana"] = "Afficher la mana" +L["Show Mana from Intellect"] = "Affiche la mana apporté par l'intelligence." +-- /rb stat int dmg +L["Show Spell Damage"] = "Afficher les dégats des sorts" +L["Show Spell Damage from Intellect"] = "Afficher les dégats des sorts apporté par l'intelligence." +-- /rb stat int heal +L["Show Healing"] = "Afficher les soins" +L["Show Healing from Intellect"] = "Affiche les soins apporté par l'intelligence." +-- /rb stat int mp5 +L["Show Mana Regen"] = "Afficher la mana/5sec" +L["Show Mana Regen while casting from Intellect"] = "Affiche la mana/5sec apporté par l'intelligence." +-- /rb stat int mp5nc +L["Show Mana Regen while NOT casting"] = "Afficher la mana/5sec hors cast" +L["Show Mana Regen while NOT casting from Intellect"] = "Affiche la mana/sec hors cast apporté par l'intelligence." +-- /rb stat int rap +L["Show Ranged Attack Power"] = "Afficher la puissance d'attaque à distance" +L["Show Ranged Attack Power from Intellect"] = "Affiche la puissance d'attaque à distance apporté par l'intelligence." +-- /rb stat int armor +L["Show Armor"] = "Afficher l'armure" +L["Show Armor from Intellect"] = "Affiche l'armure apporté par l'intelligence." +-- /rb stat int ap +L["Show Attack Power"] = "Afficher la puissance d'attaque" +L["Show Attack Power from Intellect"] = "Affiche la puissance d'attaque apporté par l'intelligence." +--------------------------------------------------------------------------- +-- /rb stat spi +L["Spirit"] = "Esprit" +L["Changes the display of Spirit"] = "Modifie l'affichage de l'esprit" +-- /rb stat spi mp5 +L["Show Mana Regen"] = "Afficher la mana/5sec" +L["Show Mana Regen while casting from Spirit"] = "Affiche la mana/5sec apporté par l'esprit." +-- /rb stat spi mp5nc +L["Show Mana Regen while NOT casting"] = "Afficher la mana/5sec hors cast" +L["Show Mana Regen while NOT casting from Spirit"] = "Affiche la mana/sec hors cast apporté par l'esprit." +-- /rb stat spi hp5 +L["Show Health Regen"] = "Afficher la vie/5sec" +L["Show Health Regen from Spirit"] = "Affiche la vie/5sec apporté par l'esprit." +-- /rb stat spi dmg +L["Show Spell Damage"] = "Afficher les dégats des sorts" +L["Show Spell Damage from Spirit"] = "Afficher les dégats des sorts apporté par l'esprit." +-- /rb stat spi heal +L["Show Healing"] = "Afficher les soins" +L["Show Healing from Spirit"] = "Affiche les soins apporté par l'esprit." +-- /rb stat spi spellcrit +L["Show Spell Crit"] = "Afficher le critique des sorts" +L["Show Spell Crit chance from Spirit"] = "Affiche le critique des sorts apporté par l'esprit." +--------------------------------------------------------------------------- +-- /rb stat armor +L["Armor"] = "Armure" +L["Changes the display of Armor"] = "Modifie l'affichage de l'armure" +-- /rb stat armor ap +L["Show Attack Power"] = "Afficher la puissance d'attaque" +L["Show Attack Power from Armor"] = "Affiche la puissance d'attaque apporté par l'armure" +--------------------------------------------------------------------------- +-- /rb sum +L["Stat Summary"] = true +L["Options for stat summary"] = true +-- /rb sum show +L["Show Stat Summary"] = true +L["Show stat summary in tooltips"] = true +-- /rb sum ignore +L["Ignore Settings"] = true +L["Ignore stuff when calculating the stat summary"] = true +-- /rb sum ignore unused +L["Ignore Undesirable Items"] = true +L["Hide stat summary for undesirable items"] = true +-- /rb sum ignore quality +L["Minimum Item Quality"] = true +L["Show stat summary only for selected quality items and up"] = true +-- /rb sum ignore armor +L["Armor Types"] = true +L["Select armor types you want to ignore"] = true +-- /rb sum ignore armor cloth +L["Ignore Cloth"] = true +L["Hide stat summary for all cloth armor"] = true +-- /rb sum ignore armor leather +L["Ignore Leather"] = true +L["Hide stat summary for all leather armor"] = true +-- /rb sum ignore armor mail +L["Ignore Mail"] = true +L["Hide stat summary for all mail armor"] = true +-- /rb sum ignore armor plate +L["Ignore Plate"] = true +L["Hide stat summary for all plate armor"] = true +-- /rb sum ignore equipped +L["Ignore Equipped Items"] = true +L["Hide stat summary for equipped items"] = true +-- /rb sum ignore enchant +L["Ignore Enchants"] = true +L["Ignore enchants on items when calculating the stat summary"] = true +-- /rb sum ignore gem +L["Ignore Gems"] = true +L["Ignore gems on items when calculating the stat summary"] = true +-- /rb sum ignore prismaticSocket +L["Ignore Prismatic Sockets"] = true +L["Ignore gems in prismatic sockets when calculating the stat summary"] = true +-- /rb sum diffstyle +L["Display Style For Diff Value"] = true +L["Display diff values in the main tooltip or only in compare tooltips"] = true +-- /rb sum space +L["Add Empty Line"] = true +L["Add a empty line before or after stat summary"] = true +-- /rb sum space before +L["Add Before Summary"] = true +L["Add a empty line before stat summary"] = true +-- /rb sum space after +L["Add After Summary"] = true +L["Add a empty line after stat summary"] = true +-- /rb sum icon +L["Show Icon"] = true +L["Show the sigma icon before summary listing"] = true +-- /rb sum title +L["Show Title Text"] = true +L["Show the title text before summary listing"] = true +-- /rb sum showzerostat +L["Show Zero Value Stats"] = true +L["Show zero value stats in summary for consistancy"] = true +-- /rb sum calcsum +L["Calculate Stat Sum"] = true +L["Calculate the total stats for the item"] = true +-- /rb sum calcdiff +L["Calculate Stat Diff"] = true +L["Calculate the stat difference for the item and equipped items"] = true +-- /rb sum sort +L["Sort StatSummary Alphabetically"] = true +L["Enable to sort StatSummary alphabetically, disable to sort according to stat type(basic, physical, spell, tank)"] = true +-- /rb sum avoidhasblock +L["Include Block Chance In Avoidance Summary"] = true +L["Enable to include block chance in Avoidance summary, Disable for only dodge, parry, miss"] = true +--------------------------------------------------------------------------- +-- /rb sum basic +L["Stat - Basic"] = "Stat - Basic" +L["Choose basic stats for summary"] = "Choisissez les statistiques de base pour le résumé." +-- /rb sum basic hp +L["Sum Health"] = "Cumul Vie" +L["Health <- Health, Stamina"] = "Vie <- Vie, Endu" +-- /rb sum stat mp +L["Sum Mana"] = "Cumul Mana" +L["Mana <- Mana, Intellect"] = "Mana <- Mana, Intel" +-- /rb sum stat ap +L["Sum Attack Power"] = "Cumul PA" +L["Attack Power <- Attack Power, Strength, Agility"] = "PA <- PA, Force, Agi" +-- /rb sum basic mp5 +L["Sum Mana Regen"] = "Cumul Regen Mana" +L["Mana Regen <- Mana Regen, Spirit"] = "Regen Mana <- Regen Mana, Esprit" +-- /rb sum stat rap +L["Sum Ranged Attack Power"] = "Cumul PA Dist" +L["Ranged Attack Power <- Ranged Attack Power, Intellect, Attack Power, Strength, Agility"] = "PA Dist <- PA Dist, Intel, PA, Force, Agi" +-- /rb sum stat fap +L["Sum Feral Attack Power"] = "Cumul PA Farouche" +L["Feral Attack Power <- Feral Attack Power, Attack Power, Strength, Agility"] = "PA Farouche <- PA Farouche, PA, Force, Agi" +-- /rb sum stat dmg +L["Sum Spell Damage"] = "Cumul Dégats des Sorts" +L["Spell Damage <- Spell Damage, Intellect, Spirit, Stamina"] = "Dégats des Sorts <- Dégats des Sorts, Intel, Esprit, Endu" +-- /rb sum stat dmgholy +L["Sum Holy Spell Damage"] = "Cumul DS Sacré" +L["Holy Spell Damage <- Holy Spell Damage, Spell Damage, Intellect, Spirit"] = "DS Sacré <- DS Sacré, DS, Intel, Esprit" +-- /rb sum stat dmgarcane +L["Sum Arcane Spell Damage"] = "Cumul DS Arcane" +L["Arcane Spell Damage <- Arcane Spell Damage, Spell Damage, Intellect"] = "DS Arcane <- DS Arcane, DS, Intel" +-- /rb sum stat dmgfire +L["Sum Fire Spell Damage"] = "Cumul DS Feu" +L["Fire Spell Damage <- Fire Spell Damage, Spell Damage, Intellect, Stamina"] = "DS Feu <- DS Feu, DS, Intel, Endu" +-- /rb sum stat dmgnature +L["Sum Nature Spell Damage"] = "Cumul DS Nature" +L["Nature Spell Damage <- Nature Spell Damage, Spell Damage, Intellect"] = "DS Nature <- DS Nature, DS, Intel" +-- /rb sum stat dmgfrost +L["Sum Frost Spell Damage"] = "Cumul DS Givre" +L["Frost Spell Damage <- Frost Spell Damage, Spell Damage, Intellect"] = "DS Givre <- DS Givre, DS, Intel" +-- /rb sum stat dmgshadow +L["Sum Shadow Spell Damage"] = "Cumul DS Ombre" +L["Shadow Spell Damage <- Shadow Spell Damage, Spell Damage, Intellect, Spirit, Stamina"] = "DS Ombre <- DS Ombre, DS, Intel, Esprit, Endu" +-- /rb sum stat heal +L["Sum Healing"] = "Cumul Soins" +L["Healing <- Healing, Intellect, Spirit, Agility, Strength"] = "Soins <- Soins, Intel, Esprit, Agi, Force" +-- /rb sum stat hit +L["Sum Hit Chance"] = "Cumul Toucher" +--L["Hit Chance <- Hit Rating"] = "Toucher <- Toucher, Score Arme" +-- /rb sum stat hitspell +L["Sum Spell Hit Chance"] = "Cumul Toucher des Sorts" +L["Spell Hit Chance <- Spell Hit Rating"] = "Toucher des Sorts <- Toucher des Sorts" +-- /rb sum stat crit +L["Sum Crit Chance"] = "Cumul Crit" +--L["Crit Chance <- Crit Rating, Agility"] = "Crit <- %Crit, Agi, Comp Arme" +-- /rb sum stat critspell +L["Sum Spell Crit Chance"] = "Cumul Crit Sorts" +L["Spell Crit Chance <- Spell Crit Rating, Intellect"] = "Crit Sorts <- %Crit Sorts, Intel" +-- /rb sum stat mp5 +L["Sum Mana Regen"] = "Cumul Regen Mana" +L["Mana Regen <- Mana Regen, Spirit"] = "Regen Mana <- Regen Mana, Esprit" +-- /rb sum stat mp5nc +L["Sum Mana Regen while not casting"] = "Cumul Regen Mana HI" +L["Mana Regen while not casting <- Spirit"] = "Regen Mana HI <- Esprit" +-- /rb sum stat hp5 +L["Sum Health Regen"] = "Cumul Regen Vie" +L["Health Regen <- Health Regen"] = "Regen Vie <- Regen Vie" +-- /rb sum stat hp5oc +L["Sum Health Regen when out of combat"] = "Cumul Regen Vie HC" +L["Health Regen when out of combat <- Spirit"] = "Regen Vie HC <- Esprit" +-- /rb sum stat armor +L["Sum Armor"] = "Cumul Armure" +--L["Armor <- Armor from items and bonuses"] = "Armure <- Armure Objets, Armure Bonus, Agi, Intel" +-- /rb sum stat blockvalue +-- /rb sum stat dodge +L["Sum Dodge Chance"] = "Cumul Esquive" +--L["Dodge Chance <- Dodge Rating, Agility"] = "Esquive <- Score Esquive, Agi, Score Def" +-- /rb sum stat parry +L["Sum Parry Chance"] = "Cumul Parade" +--L["Parry Chance <- Parry Rating"] = "Parade <- Score Parade, Score Def" +-- /rb sum stat block +L["Sum Block Chance"] = "Cumul Bloquage" +--L["Block Chance <- Block Rating"] = "Bloquage <- Score Bloquage, Score Def" +-- /rb sum stat avoidhit +-- /rb sum stat avoidcrit +-- /rb sum stat neglectdodge +L["Sum Dodge Neglect"] = "Cumul Ignore Esquive" +--L["Dodge Neglect <- Weapon Skill Rating"] = "Ignore Esquive <- Score Arme" +-- /rb sum stat neglectparry +L["Sum Parry Neglect"] = "Cumul Ignore Parade" +--L["Parry Neglect <- Weapon Skill Rating"] = "Ignore Parade <- Score Arme" +-- /rb sum stat neglectblock +-- /rb sum stat resarcane +L["Sum Arcane Resistance"] = "Cumul RA" +L["Arcane Resistance Summary"] = "Résumé de la RA" +-- /rb sum stat resfire +L["Sum Fire Resistance"] = "Cumul RF" +L["Fire Resistance Summary"] = "Résumé de la Rf" +-- /rb sum stat resnature +L["Sum Nature Resistance"] = "Cumul RN" +L["Nature Resistance Summary"] = "Résumé de la RN" +-- /rb sum stat resfrost +L["Sum Frost Resistance"] = "Cumul RG" +L["Frost Resistance Summary"] = "Résumé de la RG" +-- /rb sum stat resshadow +L["Sum Shadow Resistance"] = "Cumul RO" +L["Shadow Resistance Summary"] = "Résumé de la RO" +-- /rb sum stat maxdamage +L["Sum Weapon Max Damage"] = "Cumul Dommage Arme Max" +L["Weapon Max Damage Summary"] = "Résumé du Dommage ax de l'Arme" +-- /rb sum stat weapondps +--L["Sum Weapon DPS"] = true +--L["Weapon DPS Summary"] = true +-- /rb sum statcomp +--L["Stat - Composite"] = "Stats - Composées" +--L["Choose composite stats for summary"] = "Choisir les Stats composées du résumé" +-- /rb sum statcomp str +L["Sum Strength"] = "Cumul Force" +L["Strength Summary"] = "Résumé de la Force" +-- /rb sum statcomp agi +L["Sum Agility"] = "Cumul Agi" +L["Agility Summary"] = "Résumé de l'Agilité" +-- /rb sum statcomp sta +L["Sum Stamina"] = "Cumul Endu" +L["Stamina Summary"] = "Résumé de l'Endurance" +-- /rb sum statcomp int +L["Sum Intellect"] = "Cumul Int" +L["Intellect Summary"] = "Résumé de l'Intelligence" +-- /rb sum statcomp spi +L["Sum Spirit"] = "Cumul Esprit" +L["Spirit Summary"] = "Résumé de l'Esprit" +-- /rb sum statcomp def +L["Defense <- Defense Rating"] = "Def <- Score def" +-- /rb sum statcomp wpn +L["Sum Weapon Skill"] = "Cumul Comp Arme" +L["Weapon Skill <- Weapon Skill Rating"] = "Comp Arme <- Score Arme" +-- /rb sum physical exprating +--L["Sum Expertise Rating"] = true +--L["Expertise Rating Summary"] = true +-- /rb sum basic mastery +--L["Sum Mastery"] = "" +--L["Mastery Summary"] = "" +-- /rb sum basic masteryrating +--L["Sum Mastery Rating"] = "" +--L["Mastery Rating Summary"] = "" +--------------------------------------------------------------------------- +-- /rb sum gemset +L["Gem Set"] = "Set de gemme" +L["Select a gem set to configure"] = "Selectionnez un set de gemme à configurer." +L["Default Gem Set 1"] = "Set de gemme 1" +L["Default Gem Set 2"] = "Set de gemme 2" +L["Default Gem Set 3"] = "Set de gemme 3" +-- /rb sum gem +L["Auto fill empty gem slots"] = "Remplissage automatique des gemmes vides" +-- /rb sum gem red +L["Red Socket"] = EMPTY_SOCKET_RED +--L["ItemID or Link of the gem you would like to auto fill"] = true +L[""] = "" +--L["|cffffff7f%s|r is now set to |cffffff7f[%s]|r"] = true +--L["Invalid input: %s. ItemID or ItemLink required."] = true +--L["Queried server for Gem: %s. Try again in 5 secs."] = true +-- /rb sum gem yellow +L["Yellow Socket"] = EMPTY_SOCKET_YELLOW +-- /rb sum gem blue +L["Blue Socket"] = EMPTY_SOCKET_BLUE +-- /rb sum gem meta +L["Meta Socket"] = EMPTY_SOCKET_META +-- /rb sum gem2 +--L["Second set of default gems which can be toggled with a modifier key"] = true +--L["Can't use the same modifier as Gem Set 3"] = true +-- /rb sum gem2 key +--L["Toggle Key"] = true +--L["Use this key to toggle alternate gems"] = true +-- /rb sum gem3 +--L["Third set of default gems which can be toggled with a modifier key"] = true +--L["Can't use the same modifier as Gem Set 2"] = true + +----------------------- +-- Item Level and ID -- +----------------------- +L["ItemLevel: "] = "Niveau d'objet :" +L["ItemID: "] = "ID de l'objet :" +----------------------- +-- Matching Patterns -- +----------------------- +-- Items to check -- +-------------------- +-- [Potent Ornate Topaz] +-- +6 Spell Damage, +5 Spell Crit Rating +-------------------- +-- ZG enchant +-- +10 Defense Rating/+10 Stamina/+15 Block Value +-------------------- +-- [Glinting Flam Spessarite] +-- +3 Hit Rating and +3 Agility +-------------------- +-- ItemID: 22589 +-- [Atiesh, Greatstaff of the Guardian] warlock version +-- Equip: Increases the spell critical strike rating of all party members within 30 yards by 28. +-------------------- +-- [Brilliant Wizard Oil] +-- Use: While applied to target weapon it increases spell damage by up to 36 and increases spell critical strike rating by 14 . Lasts for 30 minutes. +---------------------------------------------------------------------------------------------------- +-- I redesigned the tooltip scanner using a more locale friendly, 2 pass matching matching algorithm. +-- +-- The first pass searches for the rating number, the patterns are read from L["numberPatterns"] here, +-- " by (%d+)" will match strings like: "Increases defense rating by 16." +-- "%+(%d+)" will match strings like: "+10 Defense Rating" +-- You can add additional patterns if needed, its not limited to 2 patterns. +-- The separators are a table of strings used to break up a line into multiple lines what will be parsed seperately. +-- For example "+3 Hit Rating, +5 Spell Crit Rating" will be split into "+3 Hit Rating" and " +5 Spell Crit Rating" +-- +-- The second pass searches for the rating name, the names are read from L["statList"] here, +-- It will look through the table in order, so you can put common strings at the begining to speed up the search, +-- and longer strings should be listed first, like "spell critical strike" should be listed before "critical strike", +-- this way "spell critical strike" does get matched by "critical strike". +-- Strings need to be in lower case letters, because string.lower is called on lookup +-- +-- IMPORTANT: there may not exist a one-to-one correspondence, meaning you can't just translate this file, +-- but will need to go in game and find out what needs to be put in here. +-- For example, in english I found 3 different strings that maps to CR_CRIT_MELEE: "critical strike", "critical hit" and "crit". +-- You will need to find out every string that represents CR_CRIT_MELEE, and so on. +-- In other languages there may be 5 different strings that should all map to CR_CRIT_MELEE. +-- so please check in game that you have all strings, and not translate directly off this table. +-- +-- Tip1: When doing localizations, I recommend you set debugging to true in RatingBuster.lua +-- Find RatingBuster:SetDebugging(false) and change it to RatingBuster:SetDebugging(true) +-- or you can type /rb debug to enable it in game +-- +-- Tip2: The strings are passed into string.find, so you should escape the magic characters ^$()%.[]*+-? with a % +L["numberPatterns"] = { + {pattern = " de (%d+)", addInfo = "AfterNumber",}, + {pattern = "([%+%-]%d+)[^%%]", addInfo = "AfterStat",}, + --{pattern = "grant.-(%d+)", addInfo = "AfterNumber",}, -- for "grant you xx stat" type pattern, ex: Quel'Serrar ID:18348, Assassination Armor set + --{pattern = "add.-(%d+)", addInfo = "AfterNumber",}, -- for "add xx stat" type pattern, ex: Adamantite Sharpening Stone ID:23529 + -- Added [^%%] so that it doesn't match strings like "Increases healing by up to 10% of your total Intellect." [Whitemend Pants] ID:24261 + -- Added [^|] so that it doesn't match enchant strings (JewelTips) + {pattern = "(%d+)([^%d%%|]+)", addInfo = "AfterStat",}, -- [發光的暗影卓奈石] +6法術傷害及5耐力 +} +L["separators"] = { + "/", " et ", ",", "%. ", " pour ", "&", ":", + -- Fix for [Mirror of Truth] + -- Equip: Chance on melee and ranged critical strike to increase your attack power by 1000 for 10 secs. + -- 1000 was falsely detected detected as ranged critical strike + "augmente votre", +} +--[[ Rating ID +CR_WEAPON_SKILL = 1; +CR_DEFENSE_SKILL = 2; +CR_DODGE = 3; +CR_PARRY = 4; +CR_BLOCK = 5; +CR_HIT_MELEE = 6; +CR_HIT_RANGED = 7; +CR_HIT_SPELL = 8; +CR_CRIT_MELEE = 9; +CR_CRIT_RANGED = 10; +CR_CRIT_SPELL = 11; +CR_HIT_TAKEN_MELEE = 12; +CR_HIT_TAKEN_RANGED = 13; +CR_HIT_TAKEN_SPELL = 14; +CR_CRIT_TAKEN_MELEE = 15; +CR_CRIT_TAKEN_RANGED = 16; +CR_CRIT_TAKEN_SPELL = 17; +CR_HASTE_MELEE = 18; +CR_HASTE_RANGED = 19; +CR_HASTE_SPELL = 20; +CR_WEAPON_SKILL_MAINHAND = 21; +CR_WEAPON_SKILL_OFFHAND = 22; +CR_WEAPON_SKILL_RANGED = 23; +CR_EXPERTISE = 24; +-- +SPELL_STAT1_NAME = "Strength" +SPELL_STAT2_NAME = "Agility" +SPELL_STAT3_NAME = "Stamina" +SPELL_STAT4_NAME = "Intellect" +SPELL_STAT5_NAME = "Spirit" +--]] +L["statList"] = { + {pattern = string.lower(SPELL_STAT1_NAME), id = SPELL_STAT1_NAME}, -- Strength + {pattern = string.lower(SPELL_STAT2_NAME), id = SPELL_STAT2_NAME}, -- Agility + {pattern = string.lower(SPELL_STAT3_NAME), id = SPELL_STAT3_NAME}, -- Stamina + {pattern = string.lower(SPELL_STAT4_NAME), id = SPELL_STAT4_NAME}, -- Intellect + {pattern = string.lower(SPELL_STAT5_NAME), id = SPELL_STAT5_NAME}, -- Spirit + {pattern = "score de défense", id = CR_DEFENSE_SKILL}, + {pattern = "score d'esquive", id = CR_DODGE}, + {pattern = "score de blocage", id = CR_BLOCK}, -- block enchant: "+10 Shield Block Rating" + {pattern = "score de parade", id = CR_PARRY}, + + {pattern = "score de critique des sorts", id = CR_CRIT_SPELL}, + {pattern = "spell critical hit rating", id = CR_CRIT_SPELL}, + {pattern = "spell critical rating", id = CR_CRIT_SPELL}, + {pattern = "spell crit rating", id = CR_CRIT_SPELL}, + {pattern = "ranged critical strike rating", id = CR_CRIT_RANGED}, + {pattern = "ranged critical strike", id = CR_CRIT_RANGED}, -- [Heartseeker Scope] + {pattern = "ranged critical hit rating", id = CR_CRIT_RANGED}, + {pattern = "ranged critical rating", id = CR_CRIT_RANGED}, + {pattern = "ranged crit rating", id = CR_CRIT_RANGED}, + {pattern = "critical strike rating", id = CR_CRIT_MELEE}, + {pattern = "critical hit rating", id = CR_CRIT_MELEE}, + {pattern = "critical rating", id = CR_CRIT_MELEE}, + {pattern = "crit rating", id = CR_CRIT_MELEE}, + + {pattern = "spell hit rating", id = CR_HIT_SPELL}, + {pattern = "ranged hit rating", id = CR_HIT_RANGED}, + {pattern = "hit rating", id = CR_HIT_MELEE}, + + {pattern = "resilience", id = CR_CRIT_TAKEN_MELEE}, -- resilience is implicitly a rating + + {pattern = "spell haste rating", id = CR_HASTE_SPELL}, + {pattern = "ranged haste rating", id = CR_HASTE_RANGED}, + {pattern = "haste rating", id = CR_HASTE_MELEE}, + {pattern = "speed rating", id = CR_HASTE_MELEE}, -- [Drums of Battle] + + {pattern = "skill rating", id = CR_WEAPON_SKILL}, + {pattern = "expertise rating", id = CR_EXPERTISE}, + + {pattern = "hit avoidance rating", id = CR_HIT_TAKEN_MELEE}, + {pattern = "armor penetration rating", id = CR_ARMOR_PENETRATION}, + {pattern = string.lower(ARMOR), id = ARMOR}, + --[[ + {pattern = "dagger skill rating", id = CR_WEAPON_SKILL}, + {pattern = "sword skill rating", id = CR_WEAPON_SKILL}, + {pattern = "two%-handed swords skill rating", id = CR_WEAPON_SKILL}, + {pattern = "axe skill rating", id = CR_WEAPON_SKILL}, + {pattern = "bow skill rating", id = CR_WEAPON_SKILL}, + {pattern = "crossbow skill rating", id = CR_WEAPON_SKILL}, + {pattern = "gun skill rating", id = CR_WEAPON_SKILL}, + {pattern = "feral combat skill rating", id = CR_WEAPON_SKILL}, + {pattern = "mace skill rating", id = CR_WEAPON_SKILL}, + {pattern = "polearm skill rating", id = CR_WEAPON_SKILL}, + {pattern = "staff skill rating", id = CR_WEAPON_SKILL}, + {pattern = "two%-handed axes skill rating", id = CR_WEAPON_SKILL}, + {pattern = "two%-handed maces skill rating", id = CR_WEAPON_SKILL}, + {pattern = "fist weapons skill rating", id = CR_WEAPON_SKILL}, + --]] +} +------------------------- +-- Added info patterns -- +------------------------- +-- $value will be replaced with the number +-- EX: "$value% Crit" -> "+1.34% Crit" +-- EX: "Crit $value%" -> "Crit +1.34%" +--L["$value% Crit"] = true +L["$value% Spell Crit"] = "$value% Crit sorts" +L["$value% Dodge"] = "$value% Esquive" +L["$value HP"] = "$value% PV" +L["$value MP"] = "$value% PM" +L["$value AP"] = "$value% PA" +L["$value RAP"] = "$value% PA dist" +L["$value Dmg"] = "$value% Dégats" +L["$value Heal"] = "$value% Soins" +L["$value Armor"] = "$value% Armure" +L["$value Block"] = "$value% Blocage" +L["$value MP5"] = "$value% Mana/5sec" +L["$value MP5(NC)"] = "$value% Mana/5sec(NC)" +L["$value HP5"] = "$value% Vie/5sec" +L["$value to be Dodged/Parried"] = "$value% qui sont esquivés/parés" +L["$value to be Crit"] = "$value% qui sont crit" +L["$value Crit Dmg Taken"] = "$value% Crit dommage reçu" +L["$value DOT Dmg Taken"] = "$value% DOT dommage reçu" +L["$value% Parry"] = "$value% parer" +-- for hit rating showing both physical and spell conversions +-- (+1.21%, S+0.98%) +-- (+1.21%, +0.98% S) +L["$value Spell"] = "$value% Sort" + +------------------ +-- Stat Summary -- +------------------ +L["Stat Summary"] = "Résumé des stats" \ No newline at end of file diff --git a/RatingBuster/RatingBuster-Locale-koKR.lua b/RatingBuster/RatingBuster-Locale-koKR.lua new file mode 100644 index 0000000..8256941 --- /dev/null +++ b/RatingBuster/RatingBuster-Locale-koKR.lua @@ -0,0 +1,728 @@ +--[[ +Name: RatingBuster koKR locale +Revision: $Revision: 294 $ +Translated by: +- Slowhand, 7destiny, kcgcom, fenlis +]] + +local L = LibStub("AceLocale-3.0"):NewLocale("RatingBuster", "koKR") +if not L then return end +-- This file is coded in UTF-8 +-- If you don't have a editor that can save in UTF-8, I recommend Ultraedit +---- +-- To translate AceLocale strings, replace true with the translation string +-- Before: L["Show Item ID"] = true, +-- After: L["Show Item ID"] = "아이템 ID 표시", +--------------- +-- Waterfall -- +--------------- +L["RatingBuster Options"] = "RatingBuster 설정" +L["Waterfall-1.0 is required to access the GUI."] = "GUI를 표시하려면 Waterfall-1.0 라이브러리가 필요합니다!" +L["Enabled"] = "사용" +L["Suspend/resume this addon"] = "이 애드온 중지/다시 시작" +--------------------------- +-- Slash Command Options -- +--------------------------- +L["Always"] = "항상" +L["ALT Key"] = "ALT 키" +L["CTRL Key"] = "CTRL 키" +L["SHIFT Key"] = "SHIFT 키" +L["Never"] = "표시 안함" +L["General Settings"] = "일반 설정" +L["Profiles"] = "프로필" +-- /rb win +L["Options Window"] = "설정창" +L["Shows the Options Window"] = "설정창을 보여줍니다." +-- /rb hidebzcomp +L["Hide Blizzard Item Comparisons"] = "기본 아이템 비교 숨김" +L["Disable Blizzard stat change summary when using the built-in comparison tooltip"] = "툴팁에 블리자드의 기본 아이템 비교를 숨깁니다." +-- /rb statmod +L["Enable Stat Mods"] = "기본 능력치에 가중치 적용" +L["Enable support for Stat Mods"] = "기본 능력치에 특성이나 버프, 태세(형상, 폼)등에 의한 가중치를 적용합니다." +-- /rb avoidancedr +L["Enable Avoidance Diminishing Returns"] = "방어행동 점감 효과 사용" +L["Dodge, Parry, Hit Avoidance values will be calculated using the avoidance deminishing return formula with your current stats"] = "회피, 무기 막기, 빗맞힘 수치를 현재 능력치에서 점감 효과를 적용하여 계산합니다." +-- /rb itemid +L["Show ItemID"] = "아이템 ID 표시" +L["Show the ItemID in tooltips"] = "툴팁에 아이템 ID를 표시합니다." +-- /rb itemlevel +L["Show ItemLevel"] = "아이템 레벨 표시" +L["Show the ItemLevel in tooltips"] = "툴팁에 아이템 레벨을 표시합니다." +-- /rb usereqlv +L["Use Required Level"] = "최소 요구 레벨 사용" +L["Calculate using the required level if you are below the required level"] = "레벨이 낮아 사용하지 못하는 경우 최소 요구 레벨에 따라 계산합니다." +-- /rb level +L["Set Level"] = "레벨 설정" +L["Set the level used in calculations (0 = your level)"] = "계산에 적용할 레벨을 설정합니다. (0 = 자신의 레벨)" +--------------------------------------------------------------------------- +-- /rb rating +L["Rating"] = "전투 숙련도" +L["Options for Rating display"] = "전투 숙련도 표시에 대한 설정입니다." +-- /rb rating show +L["Show Rating Conversions"] = "전투 숙련도 계산 표시" +L["Show Rating conversions in tooltips"] = "툴팁에 전투 숙련도를 전투 능력치로 계산하여 표시합니다." +-- /rb rating spell +L["Show Spell Hit/Haste"] = "주문 적중/가속 표시" +L["Show Spell Hit/Haste from Hit/Haste Rating"] = "주문의 적중/가속을 표시합니다." +-- /rb rating physical +L["Show Physical Hit/Haste"] = "물리 적중/가속 표시" +L["Show Physical Hit/Haste from Hit/Haste Rating"] = "물리 적중/가속을 표시합니다." +-- /rb rating detail +L["Show Detailed Conversions Text"] = "세부적인 전투 숙련도 계산 표시" +L["Show detailed text for Resilience and Expertise conversions"] = "탄력도와 숙련을 세부적인 전투 능력치로 계산해서 표시합니다." +-- /rb rating exp +L["Expertise Breakdown"] = "숙련 세분화" +L["Convert Expertise into Dodge Neglect and Parry Neglect"] = "숙련을 회피 무시와 무기 막기 무시로 계산해서 표시합니다." +--------------------------------------------------------------------------- +-- /rb rating color +L["Change Text Color"] = "글자 색상 변경" +L["Changes the color of added text"] = "추가된 글자의 색상을 변경합니다." +-- /rb rating color pick +L["Pick Color"] = "색상" +L["Pick a color"] = "색상을 선택합니다." +-- /rb rating color enable +L["Enable Color"] = "색상 사용" +L["Enable colored text"] = "글자에 색상을 적용합니다." +--------------------------------------------------------------------------- +-- /rb stat +L["Stat Breakdown"] = "능력치" +L["Changes the display of base stats"] = "기본 능력치의 표시 방법을 변경합니다." +-- /rb stat show +L["Show Base Stat Conversions"] = "기본 능력치 계산 표시" +L["Show base stat conversions in tooltips"] = "툴팁에 기본 능력치를 전투 능력치로 계산하여 표시합니다." +--------------------------------------------------------------------------- +-- /rb stat str +L["Strength"] = "힘" +L["Changes the display of Strength"] = "힘의 표시 방법을 변경합니다." +-- /rb stat str ap +L["Show Attack Power"] = "전투력 표시" +L["Show Attack Power from Strength"] = "힘에 의한 전투력을 표시합니다." +-- /rb stat str block +L["Show Block Value"] = "피해 방어량 표시" +L["Show Block Value from Strength"] = "힘에 의한 피해 방어량을 표시합니다." +-- /rb stat str dmg +L["Show Spell Damage"] = "주문 공격력 표시" +L["Show Spell Damage from Strength"] = "힘에 의한 주문 공격력을 표시합니다." +-- /rb stat str heal +L["Show Healing"] = "치유량 표시" +L["Show Healing from Strength"] = "힘에 의한 치유량을 표시합니다." +-- /rb stat str parry +L["Show Parry"] = "무기 막기" +L["Show Parry from Strength"] = "힘에 의한 무기 막기를 표시합니다." +--------------------------------------------------------------------------- +-- /rb stat agi +L["Agility"] = "민첩성" +L["Changes the display of Agility"] = "민첩성의 표시 방법을 변경합니다." +-- /rb stat agi crit +L["Show Crit"] = "치명타 표시" +L["Show Crit chance from Agility"] = "민첩성에 의한 치명타 확률을 표시합니다." +-- /rb stat agi dodge +L["Show Dodge"] = "회피 표시" +L["Show Dodge chance from Agility"] = "민첩성에 의한 회피율을 표시합니다." +-- /rb stat agi ap +L["Show Attack Power"] = "전투력 표시" +L["Show Attack Power from Agility"] = "민첩성에 의한 전투력을 표시합니다." +-- /rb stat agi rap +L["Show Ranged Attack Power"] = "원거리 전투력 표시" +L["Show Ranged Attack Power from Agility"] = "민첩성에 의한 원거리 전투력을 표시합니다." +-- /rb stat agi armor +L["Show Armor"] = "방어도 표시" +L["Show Armor from Agility"] = "민첩성에 의한 방어도를 표시합니다." +-- /rb stat agi heal +L["Show Healing"] = "치유량 표시" +L["Show Healing from Agility"] = "민첩성에 의한 치유량을 표시합니다." +--------------------------------------------------------------------------- +-- /rb stat sta +L["Stamina"] = "체력" +L["Changes the display of Stamina"] = "체력의 표시 방법을 변경합니다." +-- /rb stat sta hp +L["Show Health"] = "생명력 표시" +L["Show Health from Stamina"] = "체력에 의한 생명력을 표시합니다." +-- /rb stat sta dmg +L["Show Spell Damage"] = "주문 공격력 표시" +L["Show Spell Damage from Stamina"] = "체력에 의한 주문 공격력을 표시합니다." +-- /rb stat sta heal +L["Show Healing"] = "치유량 표시" +L["Show Healing from Stamina"] = "체력에 의한 치유량을 표시합니다." +-- /rb stat sta ap +L["Show Attack Power"] = "전투력 표시" +L["Show Attack Power from Stamina"] = "체력에 의한 전투력을 표시합니다." +--------------------------------------------------------------------------- +-- /rb stat int +L["Intellect"] = "지능" +L["Changes the display of Intellect"] = "지능 표시방법을 변경합니다." +-- /rb stat int spellcrit +L["Show Spell Crit"] = "주문 극대화 표시" +L["Show Spell Crit chance from Intellect"] = "지능에 의한 주문 극대화율 표시" +-- /rb stat int mp +L["Show Mana"] = "마나 표시" +L["Show Mana from Intellect"] = "지능에 의한 마나량을 표시합니다." +-- /rb stat int dmg +L["Show Spell Damage"] = "주문 공격력 표시" +L["Show Spell Damage from Intellect"] = "지능에 의한 주문 공격력을 표시합니다." +-- /rb stat int heal +L["Show Healing"] = "치유량 표시" +L["Show Healing from Intellect"] = "지능에 의한 치유량을 표시합니다." +-- /rb stat int mp5 +L["Show Mana Regen"] = "마나 회복 표시" +L["Show Mana Regen while casting from Intellect"] = "지능에 의한 시전중 마나 회복량을 표시합니다." +-- /rb stat int mp5nc +L["Show Mana Regen while NOT casting"] = "비시전중 마나 회복 표시" +L["Show Mana Regen while NOT casting from Intellect"] = "지능에 의한 비시전중 마나 회복량을 표시합니다." +-- /rb stat int rap +L["Show Ranged Attack Power"] = "원거리 전투력 표시" +L["Show Ranged Attack Power from Intellect"] = "지능에 의한 원거리 전투력을 표시합니다." +-- /rb stat int armor +L["Show Armor"] = "방어도 표시" +L["Show Armor from Intellect"] = "지능에 의한 방어도를 표시합니다." +-- /rb stat int ap +L["Show Attack Power"] = "전투력 표시" +L["Show Attack Power from Intellect"] = "지능에 의한 전투력을 표시합니다." +--------------------------------------------------------------------------- +-- /rb stat spi +L["Spirit"] = "정신력" +L["Changes the display of Spirit"] = "정신력의 표시방법을 변경합니다." +-- /rb stat spi mp5 +L["Show Mana Regen"] = "마나 회복 표시" +L["Show Mana Regen while casting from Spirit"] = "정신력에 의한 시전중 마나 회복량을 표시합니다." +-- /rb stat spi mp5nc +L["Show Mana Regen while NOT casting"] = "비시전중 마나 회복 표시" +L["Show Mana Regen while NOT casting from Spirit"] = "정신력에 의한 비시전중 마나 회복량을 표시합니다." +-- /rb stat spi hp5 +L["Show Health Regen"] = "생명력 회복 표시" +L["Show Health Regen from Spirit"] = "정신력에 의한 (비전투중) 생명력 회복량을 표시합니다." +-- /rb stat spi dmg +L["Show Spell Damage"] = "주문 공격력 표시" +L["Show Spell Damage from Spirit"] = "정신력에 의한 주문 공격력을 표시합니다." +-- /rb stat spi heal +L["Show Healing"] = "치유량 표시" +L["Show Healing from Spirit"] = "정신력에 의한 치유량을 표시합니다." +-- /rb stat spi spellcrit +L["Show Spell Crit"] = "주문 극대화 표시" +L["Show Spell Crit chance from Spirit"] = "정신력에 의한 주문 극대화를 표시합니다." +--------------------------------------------------------------------------- +-- /rb stat armor +L["Armor"] = "방어도" +L["Changes the display of Armor"] = "방어도의 표시방법을 변경합니다." +-- /rb stat armor ap +L["Show Attack Power"] = "전투력 표시" +L["Show Attack Power from Armor"] = "방어도에 의한 전투력을 표시합니다." +--------------------------------------------------------------------------- +-- /rb sum +L["Stat Summary"] = "능력치 요약" +L["Options for stat summary"] = "능력치 요약에 대한 설정입니다." +-- /rb sum show +L["Show Stat Summary"] = "능력치 요약 표시" +L["Show stat summary in tooltips"] = "툴팁에 능력치 요약을 표시합니다." +-- /rb sum ignore +L["Ignore Settings"] = "제외 설정" +L["Ignore stuff when calculating the stat summary"] = "능력치 요약 계산에서 제외시킬 항목들을 설정합니다." +-- /rb sum ignore unused +L["Ignore Undesirable Items"] = "원하지 않는 아이템 제외" +L["Hide stat summary for undesirable items"] = "원하지 않는 아이템의 능력치를 숨깁니다." +-- /rb sum ignore quality +L["Minimum Item Quality"] = "최소 아이템 품질" +L["Show stat summary only for selected quality items and up"] = "선택한 품질 아이템의 이상인 능력치를 표시합니다." +-- /rb sum ignore armor +L["Armor Types"] = "방어구 유형" +L["Select armor types you want to ignore"] = "제외를 원하는 방어구 유형을 선택합니다." +-- /rb sum ignore armor cloth +L["Ignore Cloth"] = "제외 - 천" +L["Hide stat summary for all cloth armor"] = "모든 천 방어구의 능력치를 숨깁니다." +-- /rb sum ignore armor leather +L["Ignore Leather"] = "제외 - 가죽" +L["Hide stat summary for all leather armor"] = "모든 가죽 방어구의 능력치를 숨깁니다." +-- /rb sum ignore armor mail +L["Ignore Mail"] = "제외 - 사슬" +L["Hide stat summary for all mail armor"] = "모든 사슬 방어구의 능력치를 숨깁니다." +-- /rb sum ignore armor plate +L["Ignore Plate"] = "제외 - 판금" +L["Hide stat summary for all plate armor"] = "모든 판금 방어구의 능력치를 숨깁니다." +-- /rb sum ignore equipped +L["Ignore Equipped Items"] = "착용 아이템 제외" +L["Hide stat summary for equipped items"] = "능력치 요약 계산에 착용한 아이템은 포함시키지 않습니다." +-- /rb sum ignore enchant +L["Ignore Enchants"] = "마법부여 제외" +L["Ignore enchants on items when calculating the stat summary"] = "능력치 요약 계산에 아이템에 부여한 마법부여를 포함시키지 않습니다." +-- /rb sum ignore gem +L["Ignore Gems"] = "보석 제외" +L["Ignore gems on items when calculating the stat summary"] = "능력치 요약 계산에 아이템에 장착한 보석을 포함시키지 않습니다." +-- /rb sum ignore prismaticSocket +L["Ignore Prismatic Sockets"] = "다색 보석 홈 제외" +L["Ignore gems in prismatic sockets when calculating the stat summary"] = "능력치 요약 계산에 다색 보석 홈을 포함시키지 않습니다." +-- /rb sum diffstyle +L["Display Style For Diff Value"] = "차이값 표시 방식" +L["Display diff values in the main tooltip or only in compare tooltips"] = "기본 툴팁 또는 비교 툴팁에 차이나는 수치를 표시합니다." +-- /rb sum space +L["Add Empty Line"] = "구분선 추가" +L["Add a empty line before or after stat summary"] = "능력치 요약 앞/뒤에 구분선을 추가합니다." +-- /rb sum space before +L["Add Before Summary"] = "요약 앞에 추가" +L["Add a empty line before stat summary"] = "능력치 요약 앞에 구분선을 추가합니다." +-- /rb sum space after +L["Add After Summary"] = "요약 뒤에 추가" +L["Add a empty line after stat summary"] = "능력치 요약 뒤에 구분선을 추가합니다." +-- /rb sum icon +L["Show Icon"] = "아이콘 표시" +L["Show the sigma icon before summary listing"] = "요약 목록 앞에 시그마 아이콘을 표시합니다." +-- /rb sum title +L["Show Title Text"] = "제목 표시" +L["Show the title text before summary listing"] = "요약 목록 앞에 제목을 표시합니다." +-- /rb sum showzerostat +L["Show Zero Value Stats"] = "제로 능력치 표시" +L["Show zero value stats in summary for consistancy"] = "통일되게 보이도록 대한 요약에 제로값의 능력치를 표시합니다." +-- /rb sum calcsum +L["Calculate Stat Sum"] = "능력치 합계 계산" +L["Calculate the total stats for the item"] = "아이템에 대한 총 능력치를 계산합니다." +-- /rb sum calcdiff +L["Calculate Stat Diff"] = "능력치 차이 계산" +L["Calculate the stat difference for the item and equipped items"] = "선택한 아이템과 착용한 아이템의 능력치 차이를 계산합니다." +-- /rb sum sort +L["Sort StatSummary Alphabetically"] = "능력치 요약 정렬" +L["Enable to sort StatSummary alphabetically, disable to sort according to stat type(basic, physical, spell, tank)"] = "능력치 요약을 알파벳순으로 정렬합니다, 능력치별로 정렬하려면 비활성화하세요.(기본, 물리, 주문, 방어)" +-- /rb sum avoidhasblock +L["Include Block Chance In Avoidance Summary"] = "방어행동 (Avoidance) 요약에 방패 막기 포함" +L["Enable to include block chance in Avoidance summary, Disable for only dodge, parry, miss"] = "방어행동 (Avoidance) 요약에 방패박기를 포함시킵니다. 회피, 무기 막기, 빗맞힘만 포함시키려면 비활성화하세요." +--------------------------------------------------------------------------- +-- /rb sum basic +L["Stat - Basic"] = "능력치 - 기본" +L["Choose basic stats for summary"] = "기본 능력치를 선택합니다." +-- /rb sum basic hp +L["Sum Health"] = "생명력 합계" +L["Health <- Health, Stamina"] = "생명력 <- 생명력, 체력" +-- /rb sum basic mp +L["Sum Mana"] = "마나 합계" +L["Mana <- Mana, Intellect"] = "마나 < 마나, 지능" +-- /rb sum basic mp5 +L["Sum Mana Regen"] = "마나 회복 합계" +L["Mana Regen <- Mana Regen, Spirit"] = "마나 회복 <- 마나 회복, 정신력" +-- /rb sum basic mp5nc +L["Sum Mana Regen while not casting"] = "비시전중 마나 회복" +L["Mana Regen while not casting <- Spirit"] = "비시전중 마나 회복 <- 정신력" +-- /rb sum basic hp5 +L["Sum Health Regen"] = "생명력 회복 합계" +L["Health Regen <- Health Regen"] = "생명력 회복 <- 생명력 회복" +-- /rb sum basic hp5oc +L["Sum Health Regen when out of combat"] = "비전투중 생명력 회복" +L["Health Regen when out of combat <- Spirit"] = "비전투중 생명력 회복 <- 정신력" +-- /rb sum basic str +L["Sum Strength"] = "힘 합계" +L["Strength Summary"] = "힘 요약" +-- /rb sum basic agi +L["Sum Agility"] = "민첩성 합계" +L["Agility Summary"] = "민첩성 요약" +-- /rb sum basic sta +L["Sum Stamina"] = "체력 합계" +L["Stamina Summary"] = "체력 요약" +-- /rb sum basic int +L["Sum Intellect"] = "지능 합계" +L["Intellect Summary"] = "지능 요약" +-- /rb sum basic spi +L["Sum Spirit"] = "정신력 합계" +L["Spirit Summary"] = "정신력 요약" +-- /rb sum basic mastery +--L["Sum Mastery"] = "" +--L["Mastery Summary"] = "" +-- /rb sum basic masteryrating +--L["Sum Mastery Rating"] = "" +--L["Mastery Rating Summary"] = "" +--------------------------------------------------------------------------- +-- /rb sum physical +L["Stat - Physical"] = "능력치 - 물리" +L["Choose physical damage stats for summary"] = "물리 공격력 능력치를 선택합니다." +-- /rb sum physical ap +L["Sum Attack Power"] = "전투력 합계" +L["Attack Power <- Attack Power, Strength, Agility"] = "전투력 <- 전투력, 힘, 민첩성" +-- /rb sum physical rap +L["Sum Ranged Attack Power"] = "원거리 전투력 합계" +L["Ranged Attack Power <- Ranged Attack Power, Intellect, Attack Power, Strength, Agility"] = "원거리 전투력 <- 원거리 전투력, 지능, 전투력, 힘, 민첩성" +-- /rb sum physical fap +L["Sum Feral Attack Power"] = "야성 전투력 합계" +L["Feral Attack Power <- Feral Attack Power, Attack Power, Strength, Agility"] = "야성 전투력 <- 야성 전투력, 전투력, 힘, 민첩성" +-- /rb sum physical hit +L["Sum Hit Chance"] = "적중률 합계" +--L["Hit Chance <- Hit Rating"] = "적중률 <- 적중도, 무기 숙련도" +-- /rb sum physical hitrating +L["Sum Hit Rating"] = "적중도 합계" +L["Hit Rating Summary"] = "적중도 요약" +-- /rb sum physical crit +L["Sum Crit Chance"] = "치명타율 합계" +--L["Crit Chance <- Crit Rating, Agility"] = "치명타율 <- 치명타 적중도, 민첩성, 무기 숙련도" +-- /rb sum physical critrating +L["Sum Crit Rating"] = "치명타 적중도 합계" +L["Crit Rating Summary"] = "치명타 적중도 요약" +-- /rb sum physical haste +L["Sum Haste"] = "가속율 합계" +L["Haste <- Haste Rating"] = "가속율 <- 공격 가속도" +-- /rb sum physical hasterating +L["Sum Haste Rating"] = "공격 가속도 합계" +L["Haste Rating Summary"] = "공격 가속도 요약" +-- /rb sum physical rangedhit +L["Sum Ranged Hit Chance"] = "원거리 적중률 합계" +--L["Ranged Hit Chance <- Hit Rating, Ranged Hit Rating"] = "원거리 적중률 <- 적중도, 무기 숙련도, 원거리 적중도" +-- /rb sum physical rangedhitrating +L["Sum Ranged Hit Rating"] = "원거리 적중도 합계" +L["Ranged Hit Rating Summary"] = "원거리 적중도 요약" +-- /rb sum physical rangedcrit +L["Sum Ranged Crit Chance"] = "원거리 치명타율 합계" +--L["Ranged Crit Chance <- Crit Rating, Agility, Ranged Crit Rating"] = "원거리 치명타율 <- 치명타 적중도, 민첩성, 무기 숙련도, 치명타 적중도" +-- /rb sum physical rangedcritrating +L["Sum Ranged Crit Rating"] = "원거리 치명타 적중도 합계" +L["Ranged Crit Rating Summary"] = "원거리 치명타 적중도 요약" +-- /rb sum physical rangedhaste +L["Sum Ranged Haste"] = "원거리 공격 가속율 합계" +L["Ranged Haste <- Haste Rating, Ranged Haste Rating"] = "원거리 공격 가속율 <- 공격 가속도, 원거리 가속율" +-- /rb sum physical rangedhasterating +L["Sum Ranged Haste Rating"] = "원거리 공격 가속도 합계" +L["Ranged Haste Rating Summary"] = "원거리 공격 가속도 요약" +-- /rb sum physical maxdamage +L["Sum Weapon Max Damage"] = "무기 최대 공격력 합계" +L["Weapon Max Damage Summary"] = "무기 최대 공격력 요약" +-- /rb sum physical weapondps +--L["Sum Weapon DPS"] = true +--L["Weapon DPS Summary"] = true +-- /rb sum physical wpn +L["Sum Weapon Skill"] = "무기 숙련 합계" +L["Weapon Skill <- Weapon Skill Rating"] = "무기 숙련 <- 무기 숙련도" +-- /rb sum physical exp +L["Sum Expertise"] = "숙련 합계" +L["Expertise <- Expertise Rating"] = "숙련 <- 숙련도" +-- /rb sum physical exprating +--L["Sum Expertise Rating"] = true +--L["Expertise Rating Summary"] = true +--------------------------------------------------------------------------- +-- /rb sum spell +L["Stat - Spell"] = "능력치 - 주문" +L["Choose spell damage and healing stats for summary"] = "주문 공격력과 치유량 능력치를 선택합니다." +-- /rb sum spell dmg +L["Sum Spell Damage"] = "주문 공격력 합계" +L["Spell Damage <- Spell Damage, Intellect, Spirit, Stamina"] = "주문 공격력 <- 주문 공격력, 지능, 정신력, 체력" +-- /rb sum spell dmgholy +L["Sum Holy Spell Damage"] = "신성 주문 공격력 합계" +L["Holy Spell Damage <- Holy Spell Damage, Spell Damage, Intellect, Spirit"] = "신성 주문 공격력 <- 신성 주문 공격력, 주문 공격력, 지능, 정신력" +-- /rb sum spell dmgarcane +L["Sum Arcane Spell Damage"] = "비전 주문 공격력 합계" +L["Arcane Spell Damage <- Arcane Spell Damage, Spell Damage, Intellect"] = "비전 주문 공격력 <- 비전 주문 공격력, 주문 공격력, 지능" +-- /rb sum spell dmgfire +L["Sum Fire Spell Damage"] = "화염 주문 공격력 합계" +L["Fire Spell Damage <- Fire Spell Damage, Spell Damage, Intellect, Stamina"] = "화염 주문 공격력 <- 화염 주문 공격력, 주문 공격력, 지능, 체력" +-- /rb sum spell dmgnature +L["Sum Nature Spell Damage"] = "자연 주문 공격력 합계" +L["Nature Spell Damage <- Nature Spell Damage, Spell Damage, Intellect"] = "자연 주문 공격력 <- 자연 주문 공격력, 주문 공격력, 지능" +-- /rb sum spell dmgfrost +L["Sum Frost Spell Damage"] = "냉기 주문 공격력 합계" +L["Frost Spell Damage <- Frost Spell Damage, Spell Damage, Intellect"] = "냉기 주문 공격력 <- 냉기 주문 공격력, 주문 공격력, 지능" +-- /rb sum spell dmgshadow +L["Sum Shadow Spell Damage"] = "암흑 주문 공격력 합계" +L["Shadow Spell Damage <- Shadow Spell Damage, Spell Damage, Intellect, Spirit, Stamina"] = "암흑 주문 공격력 <- 암흑 주문 공격력, 주문 공격력, 지능, 정신력, 체력" +-- /rb sum spell heal +L["Sum Healing"] = "치유량 합계" +L["Healing <- Healing, Intellect, Spirit, Agility, Strength"] = "치유량 <- 치유량, 지능, 정신력, 민첩성, 힘" +-- /rb sum spell crit +L["Sum Spell Crit Chance"] = "주문 극대화율 합계" +L["Spell Crit Chance <- Spell Crit Rating, Intellect"] = "주문 극대화율 <- 주문 극대화 적중도, 지능" +-- /rb sum spell hit +L["Sum Spell Hit Chance"] = "주문 적중율 합계" +L["Spell Hit Chance <- Spell Hit Rating"] = "주문 적중율 <- 주문 적중도" +-- /rb sum spell haste +L["Sum Spell Haste"] = "주문 가속 합계" +L["Spell Haste <- Spell Haste Rating"] = "주문 가속 <- 주문 가속도" +-- /rb sum spell pen +L["Sum Penetration"] = "주문 관통력 합계" +L["Spell Penetration Summary"] = "주문 관통력 요약" +-- /rb sum spell hitrating +L["Sum Spell Hit Rating"] = "주문 적중도 합계" +L["Spell Hit Rating Summary"] = "주문 적중도 요약" +-- /rb sum spell critrating +L["Sum Spell Crit Rating"] = "주문 극대화 적중도 합계" +L["Spell Crit Rating Summary"] = "주문 극대화 적중도 요약" +-- /rb sum spell hasterating +L["Sum Spell Haste Rating"] = "주문 가속도" +L["Spell Haste Rating Summary"] = "주문 가속도 요약" +--------------------------------------------------------------------------- +-- /rb sum tank +L["Stat - Tank"] = "능력치 - 방어" +L["Choose tank stats for summary"] = "방어 능력치를 선택합니다." +-- /rb sum tank armor +L["Sum Armor"] = "방어도 합계" +--L["Armor <- Armor from items and bonuses"] = "방어도 <- 아이템 방어도, 방어도 보너스, 민첩성, 지능" +-- /rb sum tank dodge +L["Sum Dodge Chance"] = "회피율 합계" +--L["Dodge Chance <- Dodge Rating, Agility"] = "회피율 <- 회피 숙련도, 민첩성, 방어 숙련도" +-- /rb sum tank parry +L["Sum Parry Chance"] = "무기 막기 확률 합계" +--L["Parry Chance <- Parry Rating"] = "무기 막기 확률 <- 무기 막기 숙련도, 방어 숙련도" +-- /rb sum tank block +L["Sum Block Chance"] = "방패 막기 확률 합계" +--L["Block Chance <- Block Rating"] = "방패 막기 확률 <- 방패 막기 숙련도, 방어 숙련도" +-- /rb sum tank neglectdodge +L["Sum Dodge Neglect"] = "회피 무시 합계" +--L["Dodge Neglect <- Expertise"] = "회피 무시 <- 숙련도, 무기 숙련도" +-- /rb sum tank neglectparry +L["Sum Parry Neglect"] = "무기 막기 무시 합계" +--L["Parry Neglect <- Expertise"] = "무기 막기 무시 <- 숙련도, 무기 숙련도" +-- /rb sum tank resarcane +L["Sum Arcane Resistance"] = "비전 저항력 합계" +L["Arcane Resistance Summary"] = "비전 저항력 요약" +-- /rb sum tank resfire +L["Sum Fire Resistance"] = "화염 저항력 합계" +L["Fire Resistance Summary"] = "화염 저항력 요약" +-- /rb sum tank resnature +L["Sum Nature Resistance"] = "자연 저항력 합계" +L["Nature Resistance Summary"] = "자연 저항력 요약" +-- /rb sum tank resfrost +L["Sum Frost Resistance"] = "냉기 저항력 합계" +L["Frost Resistance Summary"] = "냉기 저항력 요약" +-- /rb sum tank resshadow +L["Sum Shadow Resistance"] = "암흑 저항력 합계" +L["Shadow Resistance Summary"] = "암흑 저항력 요약" +-- /rb sum tank dodgerating +L["Sum Dodge Rating"] = "회피 숙련도 합계" +L["Dodge Rating Summary"] = "회피 숙련도 요약" +-- /rb sum tank parryrating +L["Sum Parry Rating"] = "무기 막기 합계" +L["Parry Rating Summary"] = "무기 막기 숙련도 요약" +-- /rb sum tank blockrating +L["Sum Block Rating"] = "방패 막기 숙련도 합계" +L["Block Rating Summary"] = "방어 막기 숙련도 요약" +-- /rb sum tank res +L["Sum Resilience"] = "탄력 합계" +L["Resilience Summary"] = "탄력 요약" +-- /rb sum tank tp +L["Sum TankPoints"] = "탱킹 점수 (TankPoint) 합계" +L["TankPoints <- Health, Total Reduction"] = "탱킹 점수 (TankPoint) <- 생명력, 총 피해감소" +-- /rb sum tank tr +L["Sum Total Reduction"] = "총 피해감소 합계" +--L["Total Reduction <- Armor, Dodge, Parry, Block, MobMiss, MobCrit, MobCrush, DamageTakenMods"] = "총 피해감소 <- 방어도, 회피, 무기 막기, 방패 막기, 피해 방어량, 방어 숙련, 탄력, 빗맞힘(자신), 치명타 감소, 몹강타, 피해감소 효과" +-- /rb sum tank avoid +L["Sum Avoidance"] = "총 방어행동 합계" +L["Avoidance <- Dodge, Parry, MobMiss, Block(Optional)"] = "방어행동 (Avoidance) <- 회피, 무기 막기, 빗맞힘, 방패 막기(선택적)" +--------------------------------------------------------------------------- +-- /rb sum gemset +L["Gem Set"] = "보석 설정" +L["Select a gem set to configure"] = "보석 설정의 구성을 선택합니다." +L["Default Gem Set 1"] = "기본 보석 설정 1" +L["Default Gem Set 2"] = "기본 보석 설정 2" +L["Default Gem Set 3"] = "기본 보석 설정 3" +-- /rb sum gem +L["Auto fill empty gem slots"] = "빈 보석 슬롯을 자동으로 채웁니다." +-- /rb sum gem red +L["Red Socket"] = EMPTY_SOCKET_RED +L["ItemID or Link of the gem you would like to auto fill"] = "자동으로 채우고 싶은 보석의 아이템ID & 링크를 입력하세요." +L[""] = "<아이템ID|링크>" +L["|cffffff7f%s|r is now set to |cffffff7f[%s]|r"] = "현재 |cffffff7f%s|r에 |cffffff7f[%s]|r 설정" +L["Invalid input: %s. ItemID or ItemLink required."] = "잘못된 입력값 : %s. 아이템ID 나 아이템 링크가 필요합니다." +L["Queried server for Gem: %s. Try again in 5 secs."] = "서버에 보석 조회중: %s. 5초 후 다시하세요." +-- /rb sum gem yellow +L["Yellow Socket"] = EMPTY_SOCKET_YELLOW +-- /rb sum gem blue +L["Blue Socket"] = EMPTY_SOCKET_BLUE +-- /rb sum gem meta +L["Meta Socket"] = EMPTY_SOCKET_META +-- /rb sum gem2 +L["Second set of default gems which can be toggled with a modifier key"] = true +L["Can't use the same modifier as Gem Set 3"] = true +-- /rb sum gem2 key +L["Toggle Key"] = "전환 키" +L["Use this key to toggle alternate gems"] = "대체 보석으로 전환하는데 사용할 키" +-- /rb sum gem3 +L["Third set of default gems which can be toggled with a modifier key"] = true +L["Can't use the same modifier as Gem Set 2"] = true + + +----------------------- +-- Item Level and ID -- +----------------------- +L["ItemLevel: "] = "아이템레벨: " +L["ItemID: "] = "아이템ID: " +----------------------- +-- Matching Patterns -- +----------------------- +-- Items to check -- +-------------------- +-- [Potent Ornate Topaz] +-- +6 Spell Damage, +5 Spell Crit Rating +-------------------- +-- ZG enchant +-- +10 Defense Rating/+10 Stamina/+15 Block Value +-------------------- +-- [Glinting Flam Spessarite] +-- +3 Hit Rating and +3 Agility +-------------------- +-- ItemID: 22589 +-- [Atiesh, Greatstaff of the Guardian] warlock version +-- Equip: Increases the spell critical strike rating of all party members within 30 yards by 28. +-------------------- +-- [Brilliant Wizard Oil] +-- Use: While applied to target weapon it increases spell damage by up to 36 and increases spell critical strike rating by 14 . Lasts for 30 minutes. +---------------------------------------------------------------------------------------------------- +-- I redesigned the tooltip scanner using a more locale friendly, 2 pass matching matching algorithm. +-- +-- The first pass searches for the rating number, the patterns are read from L["numberPatterns"] here, +-- " by (%d+)" will match strings like: "Increases defense rating by 16." +-- "%+(%d+)" will match strings like: "+10 Defense Rating" +-- You can add additional patterns if needed, its not limited to 2 patterns. +-- The separators are a table of strings used to break up a line into multiple lines what will be parsed seperately. +-- For example "+3 Hit Rating, +5 Spell Crit Rating" will be split into "+3 Hit Rating" and " +5 Spell Crit Rating" +-- +-- The second pass searches for the rating name, the names are read from L["statList"] here, +-- It will look through the table in order, so you can put common strings at the begining to speed up the search, +-- and longer strings should be listed first, like "spell critical strike" should be listed before "critical strike", +-- this way "spell critical strike" does get matched by "critical strike". +-- Strings need to be in lower case letters, because string.lower is called on lookup +-- +-- IMPORTANT: there may not exist a one-to-one correspondence, meaning you can't just translate this file, +-- but will need to go in game and find out what needs to be put in here. +-- For example, in english I found 3 different strings that maps to CR_CRIT_MELEE: "critical strike", "critical hit" and "crit". +-- You will need to find out every string that represents CR_CRIT_MELEE, and so on. +-- In other languages there may be 5 different strings that should all map to CR_CRIT_MELEE. +-- so please check in game that you have all strings, and not translate directly off this table. +-- +-- Tip1: When doing localizations, I recommend you set debugging to true in RatingBuster.lua +-- Find RatingBuster:SetDebugging(false) and change it to RatingBuster:SetDebugging(true) +-- or you can type /rb debug to enable it in game +-- +-- Tip2: The strings are passed into string.find, so you should escape the magic characters ^$()%.[]*+-? with a % +L["numberPatterns"] = { + {pattern = "(%d+)만큼", addInfo = "AfterNumber",}, + {pattern = "([%+%-]%d+)", addInfo = "AfterNumber",}, + --{pattern = "grant.-(%d+)", addInfo = "AfterNumber",}, -- for "grant you xx stat" type pattern, ex: Quel'Serrar, Assassination Armor set + --{pattern = "add.-(%d+)", addInfo = "AfterNumber",}, -- for "add xx stat" type pattern, ex: Adamantite Sharpening Stone + -- Added [^%%] so that it doesn't match strings like "Increases healing by up to 10% of your total Intellect." [Whitemend Pants] ID:24261 + -- Added [^|] so that it doesn't match enchant strings (JewelTips) + {pattern = "(%d+)([^%d%%|]+)", addInfo = "AfterStat",}, -- [發光的暗影卓奈石] +6法術傷害及5耐力 +} +L["separators"] = { + "/", " and ", ",", "%. ", " for ", "&", ":", + -- Fix for [Mirror of Truth] + -- Equip: Chance on melee and ranged critical strike to increase your attack power by 1000 for 10 secs. + -- 1000 was falsely detected detected as ranged critical strike + "increase your", +} +--[[ Rating ID +CR_WEAPON_SKILL = 1; +CR_DEFENSE_SKILL = 2; +CR_DODGE = 3; +CR_PARRY = 4; +CR_BLOCK = 5; +CR_HIT_MELEE = 6; +CR_HIT_RANGED = 7; +CR_HIT_SPELL = 8; +CR_CRIT_MELEE = 9; +CR_CRIT_RANGED = 10; +CR_CRIT_SPELL = 11; +CR_HIT_TAKEN_MELEE = 12; +CR_HIT_TAKEN_RANGED = 13; +CR_HIT_TAKEN_SPELL = 14; +CR_CRIT_TAKEN_MELEE = 15; +CR_CRIT_TAKEN_RANGED = 16; +CR_CRIT_TAKEN_SPELL = 17; +CR_HASTE_MELEE = 18; +CR_HASTE_RANGED = 19; +CR_HASTE_SPELL = 20; +CR_WEAPON_SKILL_MAINHAND = 21; +CR_WEAPON_SKILL_OFFHAND = 22; +CR_WEAPON_SKILL_RANGED = 23; +CR_EXPERTISE = 24; +-- +SPELL_STAT1_NAME = "힘" +SPELL_STAT2_NAME = "민첩성" +SPELL_STAT3_NAME = "체력" +SPELL_STAT4_NAME = "지능" +SPELL_STAT5_NAME = "정신력" +--]] +L["statList"] = { + {pattern = string.lower(SPELL_STAT1_NAME), id = SPELL_STAT1_NAME}, -- Strength + {pattern = string.lower(SPELL_STAT2_NAME), id = SPELL_STAT2_NAME}, -- Agility + {pattern = string.lower(SPELL_STAT3_NAME), id = SPELL_STAT3_NAME}, -- Stamina + {pattern = string.lower(SPELL_STAT4_NAME), id = SPELL_STAT4_NAME}, -- Intellect + {pattern = string.lower(SPELL_STAT5_NAME), id = SPELL_STAT5_NAME}, -- Spirit + {pattern = "방어 숙련도", id = CR_DEFENSE_SKILL}, + {pattern = "회피 숙련도", id = CR_DODGE}, + {pattern = "방패 막기 숙련도", id = CR_BLOCK}, -- block enchant: "+10 Shield Block Rating" + {pattern = "무기 막기 숙련도", id = CR_PARRY}, + + {pattern = "주문 극대화 적중도", id = CR_CRIT_SPELL}, + {pattern = "주문의 극대화 적중도", id = CR_CRIT_SPELL}, +-- {pattern = "spell critical rating", id = CR_CRIT_SPELL}, +-- {pattern = "spell crit rating", id = CR_CRIT_SPELL}, + {pattern = "원거리 치명타 적중도", id = CR_CRIT_RANGED}, + {pattern = "원거리 치명타", id = CR_CRIT_RANGED}, -- [Heartseeker Scope] +-- {pattern = "ranged critical hit rating", id = CR_CRIT_RANGED}, +-- {pattern = "ranged critical rating", id = CR_CRIT_RANGED}, +-- {pattern = "ranged crit rating", id = CR_CRIT_RANGED}, + {pattern = "치명타 적중도", id = CR_CRIT_MELEE}, + {pattern = "근접 치명타 적중도", id = CR_CRIT_MELEE}, + {pattern = "critical rating", id = CR_CRIT_MELEE}, +-- {pattern = "crit rating", id = CR_CRIT_MELEE}, + + {pattern = "주문 적중도", id = CR_HIT_SPELL}, + {pattern = "원거리 적중도", id = CR_HIT_RANGED}, + {pattern = "적중도", id = CR_HIT_MELEE}, + + {pattern = "탄력도", id = CR_CRIT_TAKEN_MELEE}, -- resilience is implicitly a rating + + {pattern = "주문 가속도", id = CR_HASTE_SPELL}, + {pattern = "주문 시전 가속도", id = CR_HASTE_SPELL}, + {pattern = "원거리 공격 가속도", id = CR_HASTE_RANGED}, + {pattern = "공격 가속도", id = CR_HASTE_MELEE}, + {pattern = "가속도", id = CR_HASTE_MELEE}, -- [Drums of Battle] + + {pattern = "무기 숙련도", id = CR_WEAPON_SKILL}, + {pattern = "숙련도", id = CR_EXPERTISE}, + {pattern = "숙련", id = CR_EXPERTISE}, -- WotLK beta Gem + + {pattern = "근접 공격 회피", id = CR_HIT_TAKEN_MELEE}, + {pattern = "방어구 관통력", id = CR_ARMOR_PENETRATION}, --armor penetration rating + {pattern = string.lower(ARMOR), id = ARMOR}, + --[[ + {pattern = "dagger skill rating", id = CR_WEAPON_SKILL}, + {pattern = "sword skill rating", id = CR_WEAPON_SKILL}, + {pattern = "two%-handed swords skill rating", id = CR_WEAPON_SKILL}, + {pattern = "axe skill rating", id = CR_WEAPON_SKILL}, + {pattern = "bow skill rating", id = CR_WEAPON_SKILL}, + {pattern = "crossbow skill rating", id = CR_WEAPON_SKILL}, + {pattern = "gun skill rating", id = CR_WEAPON_SKILL}, + {pattern = "feral combat skill rating", id = CR_WEAPON_SKILL}, + {pattern = "mace skill rating", id = CR_WEAPON_SKILL}, + {pattern = "polearm skill rating", id = CR_WEAPON_SKILL}, + {pattern = "staff skill rating", id = CR_WEAPON_SKILL}, + {pattern = "two%-handed axes skill rating", id = CR_WEAPON_SKILL}, + {pattern = "two%-handed maces skill rating", id = CR_WEAPON_SKILL}, + {pattern = "fist weapons skill rating", id = CR_WEAPON_SKILL}, + --]] +} +------------------------- +-- Added info patterns -- +------------------------- +-- $value will be replaced with the number +-- EX: "$value% Crit" -> "+1.34% Crit" +-- EX: "Crit $value%" -> "Crit +1.34%" +L["$value% Crit"] = "치명타 $value%" +L["$value% Spell Crit"] = "극대화 $value%" +L["$value% Dodge"] = "회피 $value%" +L["$value HP"] = "생명력 $value" +L["$value MP"] = "마나 $value" +L["$value AP"] = "전투력 $value" +L["$value RAP"] = "원거리 $value" +L["$value Dmg"] = "주문력 $value" +L["$value Heal"] = "치유량 $value" +L["$value Armor"] = "방어도 $value" +L["$value Block"] = "방피량 $value" +L["$value MP5"] = "$value MP5" +L["$value MP5(NC)"] = "$value MP5(비시전)" +L["$value HP5"] = "$value HP5" +L["$value to be Dodged/Parried"] = "회피/막음 $value" +L["$value to be Crit"] = "치명타 적중 $value" +L["$value Crit Dmg Taken"] = "치명타 피해 $value" +L["$value DOT Dmg Taken"] = "DoT 피해 $value" +L["$value% Parry"] = "무막 $value%" +-- for hit rating showing both physical and spell conversions +-- (+1.21%, S+0.98%) +-- (+1.21%, +0.98% S) +L["$value Spell"] = "주문 $value" + +------------------ +-- Stat Summary -- +------------------ +L["Stat Summary"] = "능력치 요약" \ No newline at end of file diff --git a/RatingBuster/RatingBuster-Locale-ruRU.lua b/RatingBuster/RatingBuster-Locale-ruRU.lua new file mode 100644 index 0000000..c568d5b --- /dev/null +++ b/RatingBuster/RatingBuster-Locale-ruRU.lua @@ -0,0 +1,789 @@ +--[[ +Name: RatingBuster ruRU locale +Revision: $Revision: 294 $ +Translated by: +- Orsana \ StingerSoft \ Swix +]] + +local L = LibStub("AceLocale-3.0"):NewLocale("RatingBuster", "ruRU") +if not L then return end +-- This file is coded in UTF-8 +-- If you don't have a editor that can save in UTF-8, I recommend Ultraedit +---- +-- To translate AceLocale strings, replace true with the translation string +-- Before: L["Show Item ID"] = true, +-- After: L["Show Item ID"] = "Показывать ID", +--------------- +-- Waterfall -- +--------------- +L["RatingBuster Options"] = "Окно настроек" +L["Waterfall-1.0 is required to access the GUI."] = "Требуется Waterfall чтобы открыть настройки" +L["Enabled"] = "Включён" +L["Suspend/resume this addon"] = "Отключить/Запустить аддон" +--------------------------- +-- Slash Command Options -- +--------------------------- +L["Always"] = "Всегда" +L["ALT Key"] = "Клавиша ALT" +L["CTRL Key"] = "Клавиша CTRL" +L["SHIFT Key"] = "Клавиша SHIFT" +L["Never"] = "Никогда" +L["General Settings"] = "Основные настройки" +L["Profiles"] = "Профили" +-- /rb win +L["Options Window"] = "Окно настроек" +L["Shows the Options Window"] = "Показать окно настроек" +-- /rb hidebzcomp +L["Hide Blizzard Item Comparisons"] = "Скрыть сравнение от Blizzardа" +L["Disable Blizzard stat change summary when using the built-in comparison tooltip"] = "Отключить сравнение предметов Blizzard, если используется метод сравнения RatingBusterа" +-- /rb statmod +L["Enable Stat Mods"] = "Включить модуль статистики" +L["Enable support for Stat Mods"] = "Включает поддержку модуля статистики" +-- /rb avoidancedr +L["Enable Avoidance Diminishing Returns"] = "Включить убывания уклонений от удара" +L["Dodge, Parry, Hit Avoidance values will be calculated using the avoidance deminishing return formula with your current stats"] = "Значения уклонения, парирования, уклонений от удара при расчетах будет использоваться формула убывания (deminishing return) уклонений от удара по вашим текущим данным" +-- /rb itemid +L["Show ItemID"] = "Показывать ID предметов" +L["Show the ItemID in tooltips"] = "Показывать ID предметов в подсказке" +-- /rb itemlevel +L["Show ItemLevel"] = "Показывать уровень предмета" +L["Show the ItemLevel in tooltips"] = "Показывать уровень предмета в подсказке" +-- /rb usereqlv +L["Use Required Level"] = "Использовать необходимый уровень" +L["Calculate using the required level if you are below the required level"] = "Рассчитывать статы исходя из минимально необходимого для надевания предмета уровня, если вы ниже этого уровня" +-- /rb level +L["Set Level"] = "Задать уровень" +L["Set the level used in calculations (0 = your level)"] = "Задать уровень используемый в расчетах (0 - ваш уровень)" +--------------------------------------------------------------------------- +-- /rb rating +L["Rating"] = "Рейтинги" +L["Options for Rating display"] = "Настройки отображения рейтингов" +-- /rb rating show +L["Show Rating Conversions"] = "Конвертация рейтингов" +L["Show Rating conversions in tooltips"] = "Показывать конвертацию рейтингов в подсказке" +-- /rb rating spell +L["Show Spell Hit/Haste"] = "Меткость/скорость заклинаний" +L["Show Spell Hit/Haste from Hit/Haste Rating"] = "Показывать меткость/скорость заклинаний из рейтинга меткости/скорость" +-- /rb rating physical +L["Show Physical Hit/Haste"] = "Меткость/скорость физических атак" +L["Show Physical Hit/Haste from Hit/Haste Rating"] = "Показывать меткость/скорость физических атак из рейтинга меткости" +-- /rb rating detail +L["Show Detailed Conversions Text"] = "Детальная конвертация рейтингов" +L["Show detailed text for Resilience and Expertise conversions"] = "Показывать детальную конвертацию рейтингов мастерства и устойчивости" +-- /rb rating exp +L["Expertise Breakdown"] = "Разбивать уровень мастерства" +L["Convert Expertise into Dodge Neglect and Parry Neglect"] = "Разбивать уровень мастерства на игнорирование уклонения и парирования" +--------------------------------------------------------------------------- +-- /rb rating color +L["Change Text Color"] = "Изменить цвет текста" +L["Changes the color of added text"] = "Изменить цвет добавляемого текста" +-- /rb rating color pick +L["Pick Color"] = "Выбрать цвет" +L["Pick a color"] = "Выбрать цвет" +-- /rb rating color enable +L["Enable Color"] = "Включить цвет текста" +L["Enable colored text"] = "Включить цвет текста" +--------------------------------------------------------------------------- +-- /rb stat +L["Stat Breakdown"] = "Настройки статов" +L["Changes the display of base stats"] = "Показывать изменения базовых статов" +-- /rb stat show +L["Show Base Stat Conversions"] = "Показывать изменение базовых статов" +L["Show base stat conversions in tooltips"] = "Отображать изменение базовых статов" +--------------------------------------------------------------------------- +-- /rb stat str +L["Strength"] = "Сила" +L["Changes the display of Strength"] = "Показывать изменение силы" +-- /rb stat str ap +L["Show Attack Power"] = "Сила атаки" +L["Show Attack Power from Strength"] = "Показывать изменение силы атаки от силы" +-- /rb stat str block +L["Show Block Value"] = "Блокирование" +L["Show Block Value from Strength"] = "Показывать изменение блокирования от силы" +-- /rb stat str dmg +L["Show Spell Damage"] = "Урон от заклинаний" +L["Show Spell Damage from Strength"] = "Показывать изменение урона заклинаниями от силы" +-- /rb stat str heal +L["Show Healing"] = "Исцеление" +L["Show Healing from Strength"] = "Показывать изменение исцеления от силы" +-- /rb stat str parry +L["Show Parry"] = "Парирование" +L["Show Parry from Strength"] = "Показывать изменения парирования от силы" +--------------------------------------------------------------------------- +-- /rb stat agi +L["Agility"] = "Ловкость" +L["Changes the display of Agility"] = "Показывать изменения ловкости" +-- /rb stat agi crit +L["Show Crit"] = "Крит. удар" +L["Show Crit chance from Agility"] = "Показывать изменение крит. удара от ловкости" +-- /rb stat agi dodge +L["Show Dodge"] = "Уклонение" +L["Show Dodge chance from Agility"] = "Показывать изменение уклонения от ловкости" +-- /rb stat agi ap +L["Show Attack Power"] = "Сила атаки" +L["Show Attack Power from Agility"] = "Показывать изменение силы атаки от ловкости" +-- /rb stat agi rap +L["Show Ranged Attack Power"] = "Сила атаки дальнего боя" +L["Show Ranged Attack Power from Agility"] = "Показывать изменение силы атаки дальнего боя от ловкости" +-- /rb stat agi armor +L["Show Armor"] = "Броня" +L["Show Armor from Agility"] = "Показывать изменение брони от ловкости" +-- /rb stat agi heal +L["Show Healing"] = "Исцеление" +L["Show Healing from Agility"] = "Показывать изменение исцеления от ловкости" +--------------------------------------------------------------------------- +-- /rb stat sta +L["Stamina"] = "Выносливость" +L["Changes the display of Stamina"] = "Показывать изменение выносливости" +-- /rb stat sta hp +L["Show Health"] = "Здоровье" +L["Show Health from Stamina"] = "Показывать изменение здоровья от выносливости" +-- /rb stat sta dmg +L["Show Spell Damage"] = "Урон от заклинаний" +L["Show Spell Damage from Stamina"] = "Показывать изменение урона заклинаниями от выносливости" +-- /rb stat sta heal +L["Show Healing"] = "Исцеление" +L["Show Healing from Stamina"] = "Показывать изменение исцеления от выносливости" +-- /rb stat sta ap +L["Show Attack Power"] = "Силы атаки" +L["Show Attack Power from Stamina"] = "Показывать изменение силы атаки от выносливости" +--------------------------------------------------------------------------- +-- /rb stat int +L["Intellect"] = "Интеллект" +L["Changes the display of Intellect"] = "Показывать изменение интеллекта" +-- /rb stat int spellcrit +L["Show Spell Crit"] = "Крит. удар от заклинаний" +L["Show Spell Crit chance from Intellect"] = "Показывать изменение крит. удара заклинаний от интеллекта" +-- /rb stat int mp +L["Show Mana"] = "Мана" +L["Show Mana from Intellect"] = "Показывать изменение маны от интеллекта" +-- /rb stat int dmg +L["Show Spell Damage"] = "Урон от заклинаний" +L["Show Spell Damage from Intellect"] = "Показывать изменение урона заклинаний от интеллекта" +-- /rb stat int heal +L["Show Healing"] = "Исцеление" +L["Show Healing from Intellect"] = "Показывать изменение исцеления от интеллекта" +-- /rb stat int mp5 +L["Show Mana Regen"] = "Восполнение маны" +L["Show Mana Regen while casting from Intellect"] = "Показывать изменение восполнения маны от интеллекта" +-- /rb stat int mp5nc +L["Show Mana Regen while NOT casting"] = "Изменение восполнения маны(вне каста)" +L["Show Mana Regen while NOT casting from Intellect"] = "Показывать изменение восполнения маны от интеллекта (вне каста)" +-- /rb stat int rap +L["Show Ranged Attack Power"] = "Сила атаки дальнего боя" +L["Show Ranged Attack Power from Intellect"] = "Показывать изменение силы атаки дальнего боя от интеллекта" +-- /rb stat int armor +L["Show Armor"] = "Броня" +L["Show Armor from Intellect"] = "Показывать изменение брони от интеллекта" +-- /rb stat int ap +L["Show Attack Power"] = "Силы атаки" +L["Show Attack Power from Intellect"] = "Показывать изменение силы атаки от интеллекта" +--------------------------------------------------------------------------- +-- /rb stat spi +L["Spirit"] = "Дух" +L["Changes the display of Spirit"] = "Показывать изменение духа" +-- /rb stat spi mp5 +L["Show Mana Regen"] = "Восполнение маны" +L["Show Mana Regen while casting from Spirit"] = "Показывать изменение восполнения маны от духа" +-- /rb stat spi mp5nc +L["Show Mana Regen while NOT casting"] = "Показывать изменение восполнения маны (вне каста)" +L["Show Mana Regen while NOT casting from Spirit"] = "Показывать изменение восполнения маны от духа (вне каста)" +-- /rb stat spi hp5 +L["Show Health Regen"] = "Восполнение здаровья" +L["Show Health Regen from Spirit"] = "Показывать изменение восполнения здоровья от духа" +-- /rb stat spi dmg +L["Show Spell Damage"] = "Урон от заклинаний" +L["Show Spell Damage from Spirit"] = "Показывать изменение урона заклинаний от духа" +-- /rb stat spi heal +L["Show Healing"] = "Исцеление" +L["Show Healing from Spirit"] = "Показывать изменение исцеления от духа" +-- /rb stat spi spellcrit +L["Show Spell Crit"] = "Крит. удар заклинаний" +L["Show Spell Crit chance from Spirit"] = "Показывать изменение вероятности критического удара заклинаниями от духа" +--------------------------------------------------------------------------- +-- /rb stat armor +L["Armor"] = "Броня" +L["Changes the display of Armor"] = "Показывать изменение брони" +-- /rb stat armor ap +L["Show Attack Power"] = "Силы атаки" +L["Show Attack Power from Armor"] = "Показывать изменение силы атаки от брони" +--------------------------------------------------------------------------- +-- /rb sum +L["Stat Summary"] = "Настройки итогов" +L["Options for stat summary"] = "Итоги по статам" +-- /rb sum show +L["Show Stat Summary"] = "Показывать суммарные изменения" +L["Show stat summary in tooltips"] = "Показывать суммарные изменения" +-- /rb sum ignore +L["Ignore Settings"] = "Настройки игнорирования" +L["Ignore stuff when calculating the stat summary"] = " Настройка игнорирования при расчете итога" +-- /rb sum ignore unused +L["Ignore Undesirable Items"] = "Игнорирование неподходящих предметов" +L["Hide stat summary for undesirable items"] = "Скрыть итоги по статам для неподходящих предметов" +-- /rb sum ignore quality +L["Minimum Item Quality"] = "Мин. качество предмета" +L["Show stat summary only for selected quality items and up"] = "Показывать итоги по статам только для выбранного качества предметов и выше" +-- /rb sum ignore armor +L["Armor Types"] = "Тип брони" +L["Select armor types you want to ignore"] = "Выберите тип брони, который будет игнорироваться" +-- /rb sum ignore armor cloth +L["Ignore Cloth"] = "Игнорировать ткань" +L["Hide stat summary for all cloth armor"] = "Скрыть итоги по статам для всех доспехов из ткани" +-- /rb sum ignore armor leather +L["Ignore Leather"] = "Игнорированть кожу" +L["Hide stat summary for all leather armor"] = "Скрыть итоги по статам для всех доспехов из кожы" +-- /rb sum ignore armor mail +L["Ignore Mail"] = "Игнорированть кальчугу" +L["Hide stat summary for all mail armor"] = "Скрыть итоги по статам для всех доспехов из кальчуги" +-- /rb sum ignore armor plate +L["Ignore Plate"] = "Игнорированть латы" +L["Hide stat summary for all plate armor"] = "Скрыть итоги по статам для всех доспехов из лат" +-- /rb sum ignore equipped +L["Ignore Equipped Items"] = "Не показывать для надетых вещей" +L["Hide stat summary for equipped items"] = "Не показывать для надетых вещей" +-- /rb sum ignore enchant +L["Ignore Enchants"] = "Игнорировать чары" +L["Ignore enchants on items when calculating the stat summary"] = "Игнорировать чары при расчете итога" +-- /rb sum ignore gem +L["Ignore Gems"] = "Игнорировать самоцветы" +L["Ignore gems on items when calculating the stat summary"] = "Игнорировать самоцветы при расчете итога" +-- /rb sum ignore prismaticSocket +L["Ignore Prismatic Sockets"] = "Игнорировать радужные гнёзда" +L["Ignore gems in prismatic sockets when calculating the stat summary"] = "Игнорировать гнезда для радужного самоцвета при расчете итога" +-- /rb sum diffstyle +L["Display Style For Diff Value"] = "Стиль отображения отличия значений" +L["Display diff values in the main tooltip or only in compare tooltips"] = "Отображения различных значений в главной подсказке или только в сравнительных подсказках" +-- /rb sum space +L["Add Empty Line"] = "Добавить пустую линию" +L["Add a empty line before or after stat summary"] = "Добавить пустую линию перед или после итогов" +-- /rb sum space before +L["Add Before Summary"] = "Добавить линию до итога" +L["Add a empty line before stat summary"] = "Добавить линию до итога" +-- /rb sum space after +L["Add After Summary"] = "Добавить линию после итога" +L["Add a empty line after stat summary"] = "Добавить линию после итога" +-- /rb sum icon +L["Show Icon"] = "Добавить иконку" +L["Show the sigma icon before summary listing"] = "Добавит иконку до списка итога" +-- /rb sum title +L["Show Title Text"] = "Показывать заголовок" +L["Show the title text before summary listing"] = "Показывать заголовок до списка итога" +-- /rb sum showzerostat +L["Show Zero Value Stats"] = "Показывать нулевые статы" +L["Show zero value stats in summary for consistancy"] = "Показывать нулевые статы" +-- /rb sum calcsum +L["Calculate Stat Sum"] = "Рассчитать сумму стат" +L["Calculate the total stats for the item"] = "Рассчитать все статы для предмета" +-- /rb sum calcdiff +L["Calculate Stat Diff"] = "Рассчитывать разницу в статах" +L["Calculate the stat difference for the item and equipped items"] = "Рассчитывать разницу в статах с надетой вещью" +-- /rb sum sort +L["Sort StatSummary Alphabetically"] = "Сортировать статы в алфавитном порядке" +L["Enable to sort StatSummary alphabetically, disable to sort according to stat type(basic, physical, spell, tank)"] = "Если включено - то по алфавиту, если выключено, то по смыслу (базовые, физические, заклинания, танковые)" +-- /rb sum avoidhasblock +L["Include Block Chance In Avoidance Summary"] = "Включать вероятность блока в итоге избежаний" +L["Enable to include block chance in Avoidance summary, Disable for only dodge, parry, miss"] = "Включать вероятность блока в итоге избежаний, отключение только для уклона, парирования, промоха" +--------------------------------------------------------------------------- +-- /rb sum basic +L["Stat - Basic"] = "Статы - базовые" +L["Choose basic stats for summary"] = "Выбор базовых статов для подсчета" +-- /rb sum basic hp +L["Sum Health"] = "Сумма здоровья" +L["Health <- Health, Stamina"] = "Здоровье <- Здоровье, Выносливость" +-- /rb sum basic mp +L["Sum Mana"] = "Сумма маны" +L["Mana <- Mana, Intellect"] = "Мана <- Мана, Интеллект" +-- /rb sum basic mp5 +L["Sum Mana Regen"] = "Сумма восстановления маны" +L["Mana Regen <- Mana Regen, Spirit"] = "Восстановление маны <- Восстановления маны, Дух" +-- /rb sum basic mp5nc +L["Sum Mana Regen while not casting"] = "Сумма восстановления маны вне применения" +L["Mana Regen while not casting <- Spirit"] = "Сумма восстановления маны вне применения <- Дух" +-- /rb sum basic hp5 +L["Sum Health Regen"] = "Сумма восстановления здоровья" +L["Health Regen <- Health Regen"] = "Восстановление здоровья <- Восстановление здоровья" +-- /rb sum basic hp5oc +L["Sum Health Regen when out of combat"] = "Сумма восстановления здоровья вне применения" +L["Health Regen when out of combat <- Spirit"] = "Сумма восстановления здоровья вне применения <- Дух" +-- /rb sum basic str +L["Sum Strength"] = "Сумма силы" +L["Strength Summary"] = "Суммировать силу" +-- /rb sum basic agi +L["Sum Agility"] = "Сумма ловкости" +L["Agility Summary"] = "Суммировать ловкость" +-- /rb sum basic sta +L["Sum Stamina"] = "Сумма выносливости" +L["Stamina Summary"] = "Суммировать выносливость" +-- /rb sum basic int +L["Sum Intellect"] = "Сумма интеллекта" +L["Intellect Summary"] = "Суммировать интеллект" +-- /rb sum basic spi +L["Sum Spirit"] = "Сумма духа" +L["Spirit Summary"] = "Суммировать дух" +-- /rb sum basic mastery +--L["Sum Mastery"] = "" +--L["Mastery Summary"] = "" +-- /rb sum basic masteryrating +--L["Sum Mastery Rating"] = "" +--L["Mastery Rating Summary"] = "" +--------------------------------------------------------------------------- +-- /rb sum physical +L["Stat - Physical"] = "Статы - физические" +L["Choose physical damage stats for summary"] = "Выбор статов физического урона для подсчета" +-- /rb sum physical ap +L["Sum Attack Power"] = "Сумма силы атаки" +L["Attack Power <- Attack Power, Strength, Agility"] = "Сила атаки <- Сила атаки, Сила, Ловкость" +-- /rb sum physical rap +L["Sum Ranged Attack Power"] = "Сумма силы атаки дальнего боя" +L["Ranged Attack Power <- Ranged Attack Power, Intellect, Attack Power, Strength, Agility"] = "Сила атаки дальнего боя <- Сила атаки дальнего боя, Интеллект, Сила атаки, Сила, Ловкость" +-- /rb sum physical fap +L["Sum Feral Attack Power"] = "Сумма силы атаки в облике зверя" +L["Feral Attack Power <- Feral Attack Power, Attack Power, Strength, Agility"] = "Силы атаки в облике зверя <- Сила атаки в облике зверя, Сила атаки, Сила, Ловкость" +-- /rb sum physical hit +L["Sum Hit Chance"] = "Сумма вероятности поподания" +--L["Hit Chance <- Hit Rating"] = "Вероятности поподания <- Рейтинг меткости, Рейтинг владения оружием" +-- /rb sum physical hitrating +L["Sum Hit Rating"] = "Сумма рейтинга меткости" +L["Hit Rating Summary"] = "Суммировать рейтинг меткости" +-- /rb sum physical crit +L["Sum Crit Chance"] = "Сумма вероятности крит удара" +--L["Crit Chance <- Crit Rating, Agility"] = "Вероятности крит удара <- Рейтинг крит удара, Ловкость, Рейтинг владения оружием" +-- /rb sum physical critrating +L["Sum Crit Rating"] = "Сумма рейтинга крита" +L["Crit Rating Summary"] = "Суммировать рейтинг крит удара" +-- /rb sum physical haste +L["Sum Haste"] = "Сумма скорости" +L["Haste <- Haste Rating"] = "Скорость <- Рейтинг скорости" +-- /rb sum physical hasterating +L["Sum Haste Rating"] = "Сумма рейтинга скорости" +L["Haste Rating Summary"] = "Суммировать рейтинг скорости" +-- /rb sum physical rangedhit +L["Sum Ranged Hit Chance"] = "Сумма вероятности поподания в дальнем бою" +--L["Ranged Hit Chance <- Hit Rating, Ranged Hit Rating"] = "Вероятность поподания в дальнем бою <- Рейтинг меткости, Рейтинг владения оружием, Рейтинг меткости дальнего боя" +-- /rb sum physical rangedhitrating +L["Sum Ranged Hit Rating"] = "Сумма рейтинга меткости дальнего боя" +L["Ranged Hit Rating Summary"] = "Суммировать рейтинг меткости дальнего боя" +-- /rb sum physical rangedcrit +L["Sum Ranged Crit Chance"] = "Сумма вероятности крита в дальнем бою" +--L["Ranged Crit Chance <- Crit Rating, Agility, Ranged Crit Rating"] = "Вероятность крита в дальнем бою <- Рейтинг крита, Ловкость, Рейтинг владения оружием, Рейтинга крит удара дальнего боя" +-- /rb sum physical rangedcritrating +L["Sum Ranged Crit Rating"] = "Сумма рейтинга крит удара дальнего боя" +L["Ranged Crit Rating Summary"] = "Суммировать рейтинг критического удара в дальнем бою" +-- /rb sum physical rangedhaste +L["Sum Ranged Haste"] = "Сумма скорости дальнего боя" +L["Ranged Haste <- Haste Rating, Ranged Haste Rating"] = "Скорости дальнего боя <- Рейтинг скорости, Рейтинг скорости дальнего боя" +-- /rb sum physical rangedhasterating +L["Sum Ranged Haste Rating"] = "Сумма рейтинга скорости дальнего боя" +L["Ranged Haste Rating Summary"] = "Суммировать рейтинг скорости дальнего боя" +-- /rb sum physical maxdamage +L["Sum Weapon Max Damage"] = "Сумма макс урона оружия" +L["Weapon Max Damage Summary"] = "Суммировать макс урон уружия" +-- /rb sum physical weapondps +L["Sum Weapon DPS"] = "Сумма УВС оружия" +L["Weapon DPS Summary"] = "Суммировать урон в секунду от оружия" +-- /rb sum physical wpn +L["Sum Weapon Skill"] = "Сумма оружейного навык" +L["Weapon Skill <- Weapon Skill Rating"] = "Оружейный навык <- Рейтинг владения оружием" +-- /rb sum physical exp +L["Sum Expertise"] = "Сумма мастерства" +L["Expertise <- Expertise Rating"] = "Мастерство <- рейтинг мастерства" +-- /rb sum physical exprating +L["Sum Expertise Rating"] = "Сумма рейтинга мастерства" +L["Expertise Rating Summary"] = "Суммировать рейтинг мастерства" +--------------------------------------------------------------------------- +-- /rb sum spell +L["Stat - Spell"] = "Статы - заклинания" +L["Choose spell damage and healing stats for summary"] = "Выбор статов исцеления и урона заклинаниями для посчета" +-- /rb sum spell dmg +L["Sum Spell Damage"] = "Сумма урона заклинаниями" +L["Spell Damage <- Spell Damage, Intellect, Spirit, Stamina"] = "Урон заклинаниями <- Урон заклинаниями, Интеллект, Дух, Выносливость" +-- /rb sum spell dmgholy +L["Sum Holy Spell Damage"] = "Сумма урона светлой магией" +L["Holy Spell Damage <- Holy Spell Damage, Spell Damage, Intellect, Spirit"] = "Урон светлой магии <- Урон светлой магией, Урон заклинаниями, Интеллект, Дух" +-- /rb sum spell dmgarcane +L["Sum Arcane Spell Damage"] = "Сумма урона тайной магией" +L["Arcane Spell Damage <- Arcane Spell Damage, Spell Damage, Intellect"] = "Урон тайной магией <- Урон тайной магией, Урон заклинаниями, Интеллект" +-- /rb sum spell dmgfire +L["Sum Fire Spell Damage"] = "Сумма урона магией огня" +L["Fire Spell Damage <- Fire Spell Damage, Spell Damage, Intellect, Stamina"] = "Урон магией огня <- Урон магией огня, Урон заклинаниями, Интеллект, Выносливость" +-- /rb sum spell dmgnature +L["Sum Nature Spell Damage"] = "Сумма урона силами природы" +L["Nature Spell Damage <- Nature Spell Damage, Spell Damage, Intellect"] = "Урон силами природы <- Урон силами природы, Урон заклинаниями, Интеллект" +-- /rb sum spell dmgfrost +L["Sum Frost Spell Damage"] = "Сумма урона магией льда" +L["Frost Spell Damage <- Frost Spell Damage, Spell Damage, Intellect"] = "Урон магией льда <- Урон магией льда, Урон заклинаниями, Интеллект" +-- /rb sum spell dmgshadow +L["Sum Shadow Spell Damage"] = "Сумма урона темной магией" +L["Shadow Spell Damage <- Shadow Spell Damage, Spell Damage, Intellect, Spirit, Stamina"] = "Урон темной магией <- Урон темной магией, Урон заклинаниями, Интеллект, Дух, Выносливость" +-- /rb sum spell heal +L["Sum Healing"] = "Сумма исцеления" +L["Healing <- Healing, Intellect, Spirit, Agility, Strength"] = "Исцеление <- Исцеление, Интеллект, Дух, Ловкость, Сила" +-- /rb sum spell crit +L["Sum Spell Crit Chance"] = "Сумма вероятности крита заклинания" +L["Spell Crit Chance <- Spell Crit Rating, Intellect"] = "Вероятность крита заклинания <- Рейтинг крита удара заклинаниями, Интеллект" +-- /rb sum spell hit +L["Sum Spell Hit Chance"] = "Сумма вероятности поподания заклинаний" +L["Spell Hit Chance <- Spell Hit Rating"] = "Вероятность поподания заклинаний <- Рйтинг меткости заклинаний" +-- /rb sum spell haste +L["Sum Spell Haste"] = "Сумма скорости заклинаний" +L["Spell Haste <- Spell Haste Rating"] = "Скорость заклинаний <- Рейтинг скорости заклинаний" +-- /rb sum spell pen +L["Sum Penetration"] = "Сумма проникающей способности" +L["Spell Penetration Summary"] = "Суммировать проникающую способность заклинаний" +-- /rb sum spell hitrating +L["Sum Spell Hit Rating"] = "Сумма рейтинга меткости заклинаний" +L["Spell Hit Rating Summary"] = "Суммировать рейтинг меткости заклинаний" +-- /rb sum spell critrating +L["Sum Spell Crit Rating"] = "Сумма рейтинга крит удара заклинаниями" +L["Spell Crit Rating Summary"] = "Суммировать рейтинг крит удара заклинаниями" +-- /rb sum spell hasterating +L["Sum Spell Haste Rating"] = "Сумма рейтинга скорости заклинаний" +L["Spell Haste Rating Summary"] = "Суммировать рейтинг скорости заклинаний" +--------------------------------------------------------------------------- +-- /rb sum tank +L["Stat - Tank"] = "Статы - танкования" +L["Choose tank stats for summary"] = "Выбор статов танкования для подсчета" +-- /rb sum tank armor +L["Sum Armor"] = "Сумма брони" +--L["Armor <- Armor from items and bonuses"] = "Броня <- Броня с одежды, Броня от бонусов, Ловкость, Интеллект" +-- /rb sum tank dodge +L["Sum Dodge Chance"] = "Сумма вероятности уклонения" +--L["Dodge Chance <- Dodge Rating, Agility"] = "Вероятность уклонения <- рейтинг уклонения, ловкость, рейтинг защиты" +-- /rb sum tank parry +L["Sum Parry Chance"] = "Сумма вероятности парирования" +--L["Parry Chance <- Parry Rating"] = "Вероятность парирования <- рейтинг парирования, рейтинг защиты" +-- /rb sum tank block +L["Sum Block Chance"] = "Сумма вероятности блокирования" +--L["Block Chance <- Block Rating"] = "Вероятность блокирования <- рейтинг блокирования, рейтинг защиты" +-- /rb sum tank neglectdodge +L["Sum Dodge Neglect"] = "Сумма игнорирования уклонения" +--L["Dodge Neglect <- Expertise"] = "Игнорирование уклонения <- Мастерство, Рейтинг владения оружием" +-- /rb sum tank neglectparry +L["Sum Parry Neglect"] = "Сумма игнорирования парирования" +--L["Parry Neglect <- Expertise"] = "Игнорирование парирования <- Мастерство, Рейтинг владения оружием" +-- /rb sum tank resarcane +L["Sum Arcane Resistance"] = "Сумма защиты от тайной магии" +L["Arcane Resistance Summary"] = "Суммировать сопротивление тайной магии" +-- /rb sum tank resfire +L["Sum Fire Resistance"] = "Сумма защиты от огня" +L["Fire Resistance Summary"] = "Суммировать сопротивление огню" +-- /rb sum tank resnature +L["Sum Nature Resistance"] = "Сумма защиты от магии природы" +L["Nature Resistance Summary"] = "Суммировать сопротивление силам природы" +-- /rb sum tank resfrost +L["Sum Frost Resistance"] = "Сумма защиты от магии льда" +L["Frost Resistance Summary"] = "Суммировать сопротивление магии льда" +-- /rb sum tank resshadow +L["Sum Shadow Resistance"] = "Сумма защиты от темной магии" +L["Shadow Resistance Summary"] = "Суммировать сопротивление темной магии" +-- /rb sum tank dodgerating +L["Sum Dodge Rating"] = "Сумма рейтинга уклонения" +L["Dodge Rating Summary"] = "Суммировать рейтинг уклонения" +-- /rb sum tank parryrating +L["Sum Parry Rating"] = "Сумма рейтинга парирования" +L["Parry Rating Summary"] = "Суммировать рейтинг парирования" +-- /rb sum tank blockrating +L["Sum Block Rating"] = "Сумма рейтинга блока" +L["Block Rating Summary"] = "Суммировать рейтинг блока" +-- /rb sum tank res +L["Sum Resilience"] = "Сумма устойчивости" +L["Resilience Summary"] = "Суммировать устойчивость" +-- /rb sum tank tp +L["Sum TankPoints"] = "Самма TankPoints" +L["TankPoints <- Health, Total Reduction"] ="TankPoints <- Здоровье, Общее Cнижение" +-- /rb sum tank tr +L["Sum Total Reduction"] = "Самма общего снижения" +--L["Total Reduction <- Armor, Dodge, Parry, Block, MobMiss, MobCrit, MobCrush, DamageTakenMods"] = "Общее снижение <- Броня, Уклонение, Парирование, Блок, Значение блока, Защита, Устойчивость, ПромахСущества, КритСущества, MobCrush, DamageTakenMods" +-- /rb sum tank avoid +L["Sum Avoidance"] = "Сумма уклонения от удара" +L["Avoidance <- Dodge, Parry, MobMiss, Block(Optional)"] = "Уклонение от удара <- Уклонение, Парирование, ПромахСущества, Блок(дополнительный)" +--------------------------------------------------------------------------- +-- /rb sum gemset +L["Gem Set"] = "Набор самоцветов" +L["Select a gem set to configure"] = "Для настройки выберите набор самоцветов" +L["Default Gem Set 1"] = "Набор по умолчанию 1" +L["Default Gem Set 2"] = "Набор по умолчанию 2" +L["Default Gem Set 3"] = "Набор по умолчанию 3" +-- /rb sum gem +L["Auto fill empty gem slots"] = "Автозаполнение пустых слотов" +-- /rb sum gem red +L["Red Socket"] = EMPTY_SOCKET_RED +L["ItemID or Link of the gem you would like to auto fill"] = "ID предмета или ссылка на самоцвет, кторым вы хотите автозаполнять слоты" +L[""] = "" +L["|cffffff7f%s|r is now set to |cffffff7f[%s]|r"] = "|cffffff7f%s|r в настоящее время установлена на |cffffff7f[%s]|r" +L["Invalid input: %s. ItemID or ItemLink required."] = "Ошибочный ввод: %s. Требуется ID предмета либо ссылка." +L["Queried server for Gem: %s. Try again in 5 secs."] = "Запрос у сервера самоцвета: %s. Повторная попытка через 5 сек." +-- /rb sum gem yellow +L["Yellow Socket"] = EMPTY_SOCKET_YELLOW +-- /rb sum gem blue +L["Blue Socket"] = EMPTY_SOCKET_BLUE +-- /rb sum gem meta +L["Meta Socket"] = EMPTY_SOCKET_META +-- /rb sum gem2 +L["Second set of default gems which can be toggled with a modifier key"] = "Второй набор самоцветов по умолчанию который может быть переключен с помощью клавиш" +L["Can't use the same modifier as Gem Set 3"] = "Нельзя использовать теже клавиши что и у набора самоцветов 3" +-- /rb sum gem2 key +L["Toggle Key"] = "Клавиша переключения" +L["Use this key to toggle alternate gems"] = "Используйте данную клавишу для переключения альтернативных самоцветов" +-- /rb sum gem3 +L["Third set of default gems which can be toggled with a modifier key"] = "Третий набор самоцветов по умолчанию который может быть переключен с помощью клавиш" +L["Can't use the same modifier as Gem Set 2"] = "Нельзя использовать теже клавиши что и у набора самоцветов 2" + +----------------------- +-- Item Level and ID -- +----------------------- +L["ItemLevel: "] = "Уровень предмета: " +L["ItemID: "] = "ID предмета: " +----------------------- +-- Matching Patterns -- +----------------------- +-- Items to check -- +-------------------- +-- [Potent Ornate Topaz] +-- +6 Spell Damage, +5 Spell Crit Rating +-------------------- +-- ZG enchant +-- +10 Defense Rating/+10 Stamina/+15 Block Value +-------------------- +-- [Glinting Flam Spessarite] +-- +3 Hit Rating and +3 Agility +-------------------- +-- ItemID: 22589 +-- [Atiesh, Greatstaff of the Guardian] warlock version +-- Equip: Increases the spell critical strike rating of all party members within 30 yards by 28. +-------------------- +-- [Brilliant Wizard Oil] +-- Use: While applied to target weapon it increases spell damage by up to 36 and increases spell critical strike rating by 14 . Lasts for 30 minutes. +---------------------------------------------------------------------------------------------------- +-- I redesigned the tooltip scanner using a more locale friendly, 2 pass matching matching algorithm. +-- +-- The first pass searches for the rating number, the patterns are read from L["numberPatterns"] here, +-- " by (%d+)" will match strings like: "Increases defense rating by 16." +-- "%+(%d+)" will match strings like: "+10 Defense Rating" +-- You can add additional patterns if needed, its not limited to 2 patterns. +-- The separators are a table of strings used to break up a line into multiple lines what will be parsed seperately. +-- For example "+3 Hit Rating, +5 Spell Crit Rating" will be split into "+3 Hit Rating" and " +5 Spell Crit Rating" +-- +-- The second pass searches for the rating name, the names are read from L["statList"] here, +-- It will look through the table in order, so you can put common strings at the begining to speed up the search, +-- and longer strings should be listed first, like "spell critical strike" should be listed before "critical strike", +-- this way "spell critical strike" does get matched by "critical strike". +-- Strings need to be in lower case letters, because string.lower is called on lookup +-- +-- IMPORTANT: there may not exist a one-to-one correspondence, meaning you can't just translate this file, +-- but will need to go in game and find out what needs to be put in here. +-- For example, in english I found 3 different strings that maps to CR_CRIT_MELEE: "critical strike", "critical hit" and "crit". +-- You will need to find out every string that represents CR_CRIT_MELEE, and so on. +-- In other languages there may be 5 different strings that should all map to CR_CRIT_MELEE. +-- so please check in game that you have all strings, and not translate directly off this table. +-- +-- Tip1: When doing localizations, I recommend you set debugging to true in RatingBuster.lua +-- Find RatingBuster:SetDebugging(false) and change it to RatingBuster:SetDebugging(true) +-- or you can type /rb debug to enable it in game +-- +-- Tip2: The strings are passed into string.find, so you should escape the magic characters ^$()%.[]*+-? with a % +L["numberPatterns"] = { + {pattern = " на (%d+)", addInfo = "AfterNumber",}, + {pattern = "([%+%-]%d+)", addInfo = "AfterNumber",}, + {pattern = " увеличена на (%d+)", addInfo = "AfterNumber",}, + {pattern = "(%d+) к ", addInfo = "AfterNumber"}, -- тест + {pattern = "увеличение (%d+)", addInfo = "AfterNumber",}, -- for "grant you xx stat" type pattern, ex: Quel'Serrar, Assassination Armor set + {pattern = "дополнительно (%d+)", addInfo = "AfterNumber",}, -- for "add xx stat" type pattern, ex: Adamantite Sharpening Stone + -- Added [^%%] so that it doesn't match strings like "Increases healing by up to 10% of your total Intellect." [Whitemend Pants] ID: 24261 + -- Added [^|] so that it doesn't match enchant strings (JewelTips) + {pattern = "на (%d+)([^%d%%|]+)", addInfo = "AfterNumber",}, -- [發光的暗影卓奈石] +6法術傷害及5耐力 +} +L["separators"] = { + "/", " и ", ",", "%. ", " для ", "&", ":", + -- Fix for [Mirror of Truth] + -- Equip: Chance on melee and ranged critical strike to increase your attack power by 1000 for 10 secs. + -- 1000 was falsely detected detected as ranged critical strike + "повысить вашу", +} +--[[ Rating ID +CR_WEAPON_SKILL = 1; +CR_DEFENSE_SKILL = 2; +CR_DODGE = 3; +CR_PARRY = 4; +CR_BLOCK = 5; +CR_HIT_MELEE = 6; +CR_HIT_RANGED = 7; +CR_HIT_SPELL = 8; +CR_CRIT_MELEE = 9; +CR_CRIT_RANGED = 10; +CR_CRIT_SPELL = 11; +CR_HIT_TAKEN_MELEE = 12; +CR_HIT_TAKEN_RANGED = 13; +CR_HIT_TAKEN_SPELL = 14; +CR_CRIT_TAKEN_MELEE = 15; +CR_CRIT_TAKEN_RANGED = 16; +CR_CRIT_TAKEN_SPELL = 17; +CR_HASTE_MELEE = 18; +CR_HASTE_RANGED = 19; +CR_HASTE_SPELL = 20; +CR_WEAPON_SKILL_MAINHAND = 21; +CR_WEAPON_SKILL_OFFHAND = 22; +CR_WEAPON_SKILL_RANGED = 23; +CR_EXPERTISE = 24; +-- +SPELL_STAT1_NAME = "Strength" +SPELL_STAT2_NAME = "Agility" +SPELL_STAT3_NAME = "Stamina" +SPELL_STAT4_NAME = "Intellect" +SPELL_STAT5_NAME = "Spirit" +--]] +-- для русской локализации надо указывать все используемые склонения рейтингов (рейтинг, рейтинга, + -- рейтингу) т.к. иначе распознавание не работает. +-- + +L["statList"] = { + {pattern = string.lower("Силе атаки"), id = SPELL_STAT1115_NAME}, --чтобы Сила атаки и сила заклинаний не распознавалась как Сила + {pattern = string.lower("Сила атаки"), id = SPELL_STAT1115_NAME}, -- строки SPELL_STAT1115_NAME должны быть впереди + {pattern = string.lower("Силу атаки"), id = SPELL_STAT1115_NAME}, + {pattern = string.lower("Сила заклинаний"), id = SPELL_STAT1115_NAME}, + {pattern = string.lower("Силу заклинаний"), id = SPELL_STAT1115_NAME}, + {pattern = string.lower("Силе заклинаний"), id = SPELL_STAT1115_NAME}, -- конец левых строчек + + {pattern = string.lower(SPELL_STAT1_NAME), id = SPELL_STAT1_NAME}, -- Strength + {pattern = string.lower("Силе"), id = SPELL_STAT1_NAME}, + {pattern = string.lower(SPELL_STAT2_NAME), id = SPELL_STAT2_NAME}, -- Agility + {pattern = string.lower("Ловкости"), id = SPELL_STAT2_NAME}, + {pattern = string.lower(SPELL_STAT3_NAME), id = SPELL_STAT3_NAME}, -- Stamina + {pattern = string.lower("Выносливости"), id = SPELL_STAT3_NAME}, + {pattern = string.lower(SPELL_STAT4_NAME), id = SPELL_STAT4_NAME}, -- Intellect + {pattern = string.lower("Интеллекту"), id = SPELL_STAT4_NAME}, + {pattern = string.lower(SPELL_STAT5_NAME), id = SPELL_STAT5_NAME}, -- Spirit + {pattern = string.lower("Духу"), id = SPELL_STAT5_NAME}, + + {pattern = "рейтинг защиты", id = CR_DEFENSE_SKILL}, + {pattern = "рейтингу защиты", id = CR_DEFENSE_SKILL}, + {pattern = "рейтинга защиты", id = CR_DEFENSE_SKILL}, + {pattern = "рейтинг уклонения", id = CR_DODGE}, + {pattern = "рейтингу уклонения", id = CR_DODGE}, + {pattern = "рейтинга уклонения", id = CR_DODGE}, + {pattern = "рейтинг блокирования щитом", id = CR_BLOCK}, -- block enchant: "+10 Shield Block Rating" + {pattern = "рейтинга блокирования щитом", id = CR_BLOCK}, + {pattern = "рейтингу блокирования щитом", id = CR_BLOCK}, + {pattern = "увеличение рейтинга блокирования щита на", id = CR_BLOCK}, + {pattern = "рейтинг блока", id = CR_BLOCK}, + {pattern = "рейтинга блока", id = CR_BLOCK}, + {pattern = "рейтингу блока", id = CR_BLOCK}, + {pattern = "рейтинг парирования", id = CR_PARRY}, + {pattern = "рейтинга парирования", id = CR_PARRY}, + {pattern = "рейтингу парирования", id = CR_PARRY}, + + {pattern = "рейтинг критического удара %(заклинания%)", id = CR_CRIT_SPELL}, + {pattern = "рейтингу критического удара %(заклинания%)", id = CR_CRIT_SPELL}, + {pattern = "рейтинга критического удара %(заклинания%)", id = CR_CRIT_SPELL}, + {pattern = "рейтинга критического удара заклинаниями", id = CR_CRIT_SPELL}, + {pattern = "рейтингу критического удара заклинаниями", id = CR_CRIT_SPELL}, + {pattern = "рейтинг критического удара заклинаниями", id = CR_CRIT_SPELL}, + {pattern = "spell critical hit rating", id = CR_CRIT_SPELL}, + {pattern = "spell critical rating", id = CR_CRIT_SPELL}, + {pattern = "spell crit rating", id = CR_CRIT_SPELL}, + {pattern = "ranged critical strike rating", id = CR_CRIT_RANGED}, + {pattern = "к критическому удару в дальнем бою", id = CR_CRIT_RANGED}, -- [Heartseeker Scope] + {pattern = "ranged critical hit rating", id = CR_CRIT_RANGED}, + {pattern = "ranged critical rating", id = CR_CRIT_RANGED}, + {pattern = "ranged crit rating", id = CR_CRIT_RANGED}, + {pattern = "рейтинг критического удара", id = CR_CRIT_MELEE}, + {pattern = "рейтинг критического эффекта", id = CR_CRIT_MELEE}, + {pattern = "рейтингу критического удара", id = CR_CRIT_MELEE}, + {pattern = "рейтинга критического удара", id = CR_CRIT_MELEE}, + {pattern = "рейтинг крит. удара оруж. ближнего боя", id = CR_CRIT_MELEE}, + {pattern = "critical hit rating", id = CR_CRIT_MELEE}, + {pattern = "critical rating", id = CR_CRIT_MELEE}, + {pattern = "crit rating", id = CR_CRIT_MELEE}, + + {pattern = "рейтинг меткости %(заклинания%)", id = CR_HIT_SPELL}, + {pattern = "рейтингу меткости %(заклинания%)", id = CR_HIT_SPELL}, + {pattern = "рейтинга меткости %(заклинания%)", id = CR_HIT_SPELL}, + {pattern = "рейтингу меткости заклинаний", id = CR_HIT_SPELL}, + {pattern = "ranged hit rating", id = CR_HIT_RANGED}, + {pattern = "рейтинга нанесения удара ближнего боя", id = CR_HIT_MELEE}, + {pattern = "рейтинг меткости", id = CR_HIT_MELEE}, + {pattern = "рейтинга меткости", id = CR_HIT_MELEE}, + {pattern = "рейтингу меткости", id = CR_HIT_MELEE}, + + {pattern = "рейтинг устойчивости", id = CR_CRIT_TAKEN_MELEE}, -- resilience is implicitly a rating + {pattern = "рейтингу устойчивости", id = CR_CRIT_TAKEN_MELEE}, + {pattern = "рейтинга устойчивости", id = CR_CRIT_TAKEN_MELEE}, + + {pattern = "рейтинг скорости %(заклинания%)", id = CR_HASTE_SPELL}, + {pattern = "рейтингу скорости %(заклинания%)", id = CR_HASTE_SPELL}, + {pattern = "рейтинга скорости %(заклинания%)", id = CR_HASTE_SPELL}, + {pattern = "скорости наложения заклинаний", id = CR_HASTE_SPELL}, + {pattern = "скорость наложения заклинаний", id = CR_HASTE_SPELL}, + {pattern = "рейтинг скорости дальнего боя", id = CR_HASTE_RANGED}, + {pattern = "рейтингу скорости дальнего боя", id = CR_HASTE_RANGED}, + {pattern = "рейтинга скорости дальнего боя", id = CR_HASTE_RANGED}, + {pattern = "рейтинг скорости", id = CR_HASTE_MELEE}, + {pattern = "рейтингу скорости", id = CR_HASTE_MELEE}, + {pattern = "рейтинга скорости", id = CR_HASTE_MELEE}, + {pattern = "speed rating", id = CR_HASTE_MELEE}, -- [Drums of Battle] + + {pattern = "рейтинг владения", id = CR_WEAPON_SKILL}, + {pattern = "рейтингу владения", id = CR_WEAPON_SKILL}, + {pattern = "рейтинга владения", id = CR_WEAPON_SKILL}, + {pattern = "рейтинг мастерства", id = CR_EXPERTISE}, + {pattern = "рейтингу мастерства", id = CR_EXPERTISE}, + {pattern = "рейтинга мастерства", id = CR_EXPERTISE}, + + {pattern = "рейтинг уклонения от удара", id = CR_HIT_TAKEN_MELEE}, + {pattern = "Рейтингу уклонения от удара", id = CR_HIT_TAKEN_MELEE}, + {pattern = "рейтинга уклонения от удара", id = CR_HIT_TAKEN_MELEE}, + {pattern = "рейтинг пробивания брони", id = CR_ARMOR_PENETRATION}, + {pattern = "рейтингу пробивания брони", id = CR_ARMOR_PENETRATION}, + {pattern = "рейтинга пробивания брони", id = CR_ARMOR_PENETRATION}, + {pattern = string.lower(ARMOR), id = ARMOR}, + --[[ + {pattern = "dagger skill rating", id = CR_WEAPON_SKILL}, + {pattern = "sword skill rating", id = CR_WEAPON_SKILL}, + {pattern = "two%-handed swords skill rating", id = CR_WEAPON_SKILL}, + {pattern = "axe skill rating", id = CR_WEAPON_SKILL}, + {pattern = "bow skill rating", id = CR_WEAPON_SKILL}, + {pattern = "crossbow skill rating", id = CR_WEAPON_SKILL}, + {pattern = "gun skill rating", id = CR_WEAPON_SKILL}, + {pattern = "feral combat skill rating", id = CR_WEAPON_SKILL}, + {pattern = "mace skill rating", id = CR_WEAPON_SKILL}, + {pattern = "polearm skill rating", id = CR_WEAPON_SKILL}, + {pattern = "staff skill rating", id = CR_WEAPON_SKILL}, + {pattern = "two%-handed axes skill rating", id = CR_WEAPON_SKILL}, + {pattern = "two%-handed maces skill rating", id = CR_WEAPON_SKILL}, + {pattern = "fist weapons skill rating", id = CR_WEAPON_SKILL}, + --]] +} +------------------------- +-- Added info patterns -- +------------------------- +-- $value will be replaced with the number +-- EX: "$value% Crit" -> "+1.34% Crit" +-- EX: "Crit $value%" -> "Crit +1.34%" +L["$value% Crit"] = "$value% крит" +L["$value% Spell Crit"] = "$value% крит закл" +L["$value% Dodge"] = "$value% уклонение" +L["$value HP"] = "$value Здор" +L["$value MP"] = "$value Мана" +L["$value AP"] = "$value Сила атаки" +L["$value RAP"] = "$value САДБ" +L["$value Dmg"] = "$value урона" +L["$value Heal"] = "$value Исцеления" +L["$value Armor"] = "$value Броня" +L["$value Block"] = "$value% Блок" +L["$value MP5"] = "$value МП5сек" +L["$value MP5(NC)"] = "$value МП 5сек НК" +L["$value HP5"] = "$value Здор 5сек" +L["$value to be Dodged/Parried"] = "$value% уклон/парир" +L["$value to be Crit"] = "$value% крит" +L["$value Crit Dmg Taken"] = "$value крит урон" +L["$value DOT Dmg Taken"] = "$value сила дотов" +L["$value% Parry"] = "$value% парирование" +-- for hit rating showing both physical and spell conversions +-- (+1.21%, S+0.98%) +-- (+1.21%, +0.98% S) +L["$value Spell"] = "$value закл." + +------------------ +-- Stat Summary -- +------------------ +L["Stat Summary"] = "Итог по статам" \ No newline at end of file diff --git a/RatingBuster/RatingBuster-Locale-zhCN.lua b/RatingBuster/RatingBuster-Locale-zhCN.lua new file mode 100644 index 0000000..9e2bce4 --- /dev/null +++ b/RatingBuster/RatingBuster-Locale-zhCN.lua @@ -0,0 +1,695 @@ +--[[ +Name: RatingBuster zhCN locale +Revision: $Revision: 294 $ +Translated by: +- iceburn +- 急云@CWDG +]] + +local L = LibStub("AceLocale-3.0"):NewLocale("RatingBuster", "zhCN") +if not L then return end +-- This file is coded in UTF-8 +-- If you don't have a editor that can save in UTF-8, I recommend Ultraedit +---- +-- To translate AceLocale strings, replace true with the translation string +-- Before: L["Show Item ID"] = true, +-- After: L["Show Item ID"] = "显示物品编号", +--------------- +-- Waterfall -- +--------------- +L["RatingBuster Options"] = "RatingBuster选项" +L["Waterfall-1.0 is required to access the GUI."] = "这个GUI需要Waterfall库" +L["Enabled"] = "\229\144\175\231\148\168" +L["Suspend/resume this addon"] = "\230\154\130\229\129\156/\230\129\162\229\164\141 \230\173\164\230\143\146\228\187\182" +--------------------------- +-- Slash Command Options -- +--------------------------- +--L["General Settings"] = true +--L["Profiles"] = true +-- /rb win +L["Options Window"] = "选项窗口" +L["Shows the Options Window"] = "打开选项窗口" +-- /rb statmod +L["Enable Stat Mods"] = "属性加成" +L["Enable support for Stat Mods"] = "启用属性加成计算" +-- /rb avoidancedr +L["Enable Avoidance Diminishing Returns"] = "开启回避递减效应" +L["Dodge, Parry, Hit Avoidance values will be calculated using the avoidance deminishing return formula with your current stats"] = "你的闪避、招架、避免命中值会被计算在回避递减效应中" +-- /rb itemid +L["Show ItemID"] = "显示物品编号" +L["Show the ItemID in tooltips"] = "显示物品编号" +-- /rb itemlevel +L["Show ItemLevel"] = "显示物品等级" +L["Show the ItemLevel in tooltips"] = "显示物品等级" +-- /rb usereqlv +L["Use Required Level"] = "使用需要等级" +L["Calculate using the required level if you are below the required level"] = "如果你的等级低于需要等级则用需要等级来换算" +-- /rb level +L["Set Level"] = "设定换算等级" +L["Set the level used in calculations (0 = your level)"] = "设定换算等级 (0 = 你的目前的等级)" +--------------------------------------------------------------------------- +-- /rb rating +L["Rating"] = "属性等级" +L["Options for Rating display"] = "设定属性等级显示" +-- /rb rating show +L["Show Rating Conversions"] = "显示属性等级转换" +L["Show Rating conversions in tooltips"] = "在提示框架中显示属性等级转换结果" +-- /rb rating spell +L["Show Spell Hit/Haste"] = "显示法术命中/急速" +L["Show Spell Hit/Haste from Hit/Haste Rating"] = "显示命中/急速等级给的法术命中/急速加成" +-- /rb rating physical +L["Show Physical Hit/Haste"] = "显示物理命中" +L["Show Physical Hit/Haste from Hit/Haste Rating"] = "显示命中/急速等级给的物理命中/急速加成" +-- /rb rating detail +L["Show Detailed Conversions Text"] = "显示详细转换文本" +L["Show detailed text for Resilience and Expertise conversions"] = "显示详细的抗性和精准等级转换" +-- /rb rating exp +L["Expertise Breakdown"] = "精准效能" +L["Convert Expertise into Dodge Neglect and Parry Neglect"] = "转换精准等级为忽略躲闪和忽略招架" +--------------------------------------------------------------------------- +-- /rb rating color +L["Change Text Color"] = "设定文字颜色" +L["Changes the color of added text"] = "设定RB所增加的文字的颜色" +-- /rb rating color pick +L["Pick Color"] = "挑选颜色" +L["Pick a color"] = "挑选颜色" +-- /rb rating color enable +L["Enable Color"] = "启用文字颜色" +L["Enable colored text"] = "启用文字颜色" +--------------------------------------------------------------------------- +-- /rb stat +L["Stat Breakdown"] = "基本属性解析" +L["Changes the display of base stats"] = "设定基本属性的解析显示" +-- /rb stat show +L["Show Base Stat Conversions"] = "显示基本属性解析" +L["Show base stat conversions in tooltips"] = "在物品提示中显示基本属性解析" +--------------------------------------------------------------------------- +-- /rb stat str +L["Strength"] = "力量" +L["Changes the display of Strength"] = "自订力量解析项目" +-- /rb stat str ap +L["Show Attack Power"] = "显示近战攻击强度" +L["Show Attack Power from Strength"] = "显示力量给的近战攻击强度" +-- /rb stat str block +L["Show Block Value"] = "显示格档值" +L["Show Block Value from Strength"] = "显示力量给的格档值" +-- /rb stat str dmg +L["Show Spell Damage"] = "显示法伤" +L["Show Spell Damage from Strength"] = "显示力量给的法术伤害加成" +-- /rb stat str heal +L["Show Healing"] = "显示治疗" +L["Show Healing from Strength"] = "显示力量给的治疗加成" +-- /rb stat str parry +L["Show Parry"] = "显示闪避" +L["Show Parry from Strength"] = "显示智力给的闪避加成" +--------------------------------------------------------------------------- +-- /rb stat agi +L["Agility"] = "敏捷" +L["Changes the display of Agility"] = "自订敏捷解析项目" +-- /rb stat agi crit +L["Show Crit"] = "显示物理爆击" +L["Show Crit chance from Agility"] = "显示敏捷给的物理爆击几率" +-- /rb stat agi dodge +L["Show Dodge"] = "显示躲闪" +L["Show Dodge chance from Agility"] = "显示敏捷给的躲闪几率" +-- /rb stat agi ap +L["Show Attack Power"] = "显示近战攻击强度" +L["Show Attack Power from Agility"] = "显示敏捷给的近战攻击强度" +-- /rb stat agi rap +L["Show Ranged Attack Power"] = "显示远程攻击强度" +L["Show Ranged Attack Power from Agility"] = "显示敏捷给的远程攻击强度" +-- /rb stat agi armor +L["Show Armor"] = "显示护甲值" +L["Show Armor from Agility"] = "显示敏捷给的护甲值" +-- /rb stat agi heal +L["Show Healing"] = "显示治疗" +L["Show Healing from Agility"] = "显示敏捷给的治疗加成" +--------------------------------------------------------------------------- +-- /rb stat sta +L["Stamina"] = "耐力" +L["Changes the display of Stamina"] = "自订耐力解析项目" +-- /rb stat sta hp +L["Show Health"] = "显示生命值" +L["Show Health from Stamina"] = "显示耐力给的生命值" +-- /rb stat sta dmg +L["Show Spell Damage"] = "显示法伤" +L["Show Spell Damage from Stamina"] = "显示耐力给的法术伤害加成" +-- /rb stat sta heal +L["Show Healing"] = "显示治疗" +L["Show Healing from Stamina"] = "显示智力给的治疗加成" +-- /rb stat sta ap +L["Show Attack Power"] = "显示攻击强度" +L["Show Attack Power from Stamina"] = "显示智力给的攻击强度加成" +--------------------------------------------------------------------------- +-- /rb stat int +L["Intellect"] = "智力" +L["Changes the display of Intellect"] = "自订智力解析项目" +-- /rb stat int spellcrit +L["Show Spell Crit"] = "显示法术爆击" +L["Show Spell Crit chance from Intellect"] = "显示智力给的法术爆击几率" +-- /rb stat int mp +L["Show Mana"] = "显示法力值" +L["Show Mana from Intellect"] = "显示智力给的法力值" +-- /rb stat int dmg +L["Show Spell Damage"] = "显示法伤" +L["Show Spell Damage from Intellect"] = "显示智力给的法术伤害加成" +-- /rb stat int heal +L["Show Healing"] = "显示治疗" +L["Show Healing from Intellect"] = "显示智力给的治疗加成" +-- /rb stat int mp5 +L["Show Mana Regen"] = "显示施法回魔" +L["Show Mana Regen while casting from Intellect"] = "显示智力给的施法中法力恢复量" +-- /rb stat int mp5nc +L["Show Mana Regen while NOT casting"] = "显示5秒外回魔" +L["Show Mana Regen while NOT casting from Intellect"] = "显示在非施法状态下的法力恢复量" +-- /rb stat int rap +L["Show Ranged Attack Power"] = "显示远程攻击强度" +L["Show Ranged Attack Power from Intellect"] = "显示智力给的远程攻击强度" +-- /rb stat int armor +L["Show Armor"] = "显示护甲值" +L["Show Armor from Intellect"] = "显示智力给的护甲值" +-- /rb stat int ap +L["Show Attack Power"] = "显示攻击强度" +L["Show Attack Power from Intellect"] = "显示智力给的攻击强度加成" +--------------------------------------------------------------------------- +-- /rb stat spi +L["Spirit"] = "精神" +L["Changes the display of Spirit"] = "自订精神解析项目" +-- /rb stat spi mp5 +L["Show Mana Regen"] = "显示施法回魔" +L["Show Mana Regen while casting from Spirit"] = "显示在施法状态时,精神给的法力恢复量" +-- /rb stat spi mp5nc +L["Show Mana Regen while NOT casting"] = "显示正常回魔" +L["Show Mana Regen while NOT casting from Spirit"] = "显示在未施法状态时,精神给的法力恢复量" +-- /rb stat spi hp5 +L["Show Health Regen"] = "显示回血" +L["Show Health Regen from Spirit"] = "显示精神给的正常回血" +-- /rb stat spi dmg +L["Show Spell Damage"] = "显示法伤" +L["Show Spell Damage from Spirit"] = "显示精神给的法术伤害加成" +-- /rb stat spi heal +L["Show Healing"] = "显示治疗" +L["Show Healing from Spirit"] = "显示精神给的治疗加成" +--------------------------------------------------------------------------- +-- /rb sum +L["Stat Summary"] = "属性统计" +L["Options for stat summary"] = "自订属性选项" +-- /rb sum show +L["Show Stat Summary"] = "显示属性统计" +L["Show stat summary in tooltips"] = "在物品提示中显示属性统计" +-- /rb sum ignore +L["Ignore Settings"] = "忽略设定" +L["Ignore stuff when calculating the stat summary"] = "设定在统计总合时所要忽略的事项" +-- /rb sum ignore unused +--L["Ignore Undesirable Items"] = true +--L["Hide stat summary for undesirable items"] = true +-- /rb sum ignore quality +--L["Minimum Item Quality"] = true +--L["Show stat summary only for selected quality items and up"] = true +-- /rb sum ignore armor +--L["Armor Types"] = true +--L["Select armor types you want to ignore"] = true +-- /rb sum ignore armor cloth +--L["Ignore Cloth"] = true +--L["Hide stat summary for all cloth armor"] = true +-- /rb sum ignore armor leather +--L["Ignore Leather"] = true +--L["Hide stat summary for all leather armor"] = true +-- /rb sum ignore armor mail +--L["Ignore Mail"] = true +--L["Hide stat summary for all mail armor"] = true +-- /rb sum ignore armor plate +--L["Ignore Plate"] = true +--L["Hide stat summary for all plate armor"] = true +-- /rb sum ignore equipped +L["Ignore Equipped Items"] = "忽略已装备的物品" +L["Hide stat summary for equipped items"] = "隐藏已装备的物品的统计总合" +-- /rb sum ignore enchant +L["Ignore Enchants"] = "忽略附魔" +L["Ignore enchants on items when calculating the stat summary"] = "计算时忽略物品上的附魔效果" +-- /rb sum ignore gem +L["Ignore Gems"] = "忽略宝石" +L["Ignore gems on items when calculating the stat summary"] = "计算时忽略物品上的宝石效果" +-- /rb sum diffstyle +L["Display Style For Diff Value"] = "差异值显示方式" +L["Display diff values in the main tooltip or only in compare tooltips"] = "设定在主提示框架或只在比较框架中显示差异值" +-- /rb sum space +L["Add Empty Line"] = "加入空白列" +L["Add a empty line before or after stat summary"] = "在物品提示中的属性统计前或后加入空白列" +-- /rb sum space before +L["Add Before Summary"] = "加在统计前" +L["Add a empty line before stat summary"] = "在物品提示中的属性统计前加入空白列" +-- /rb sum space after +L["Add After Summary"] = "加在统计后" +L["Add a empty line after stat summary"] = "在物品提示中的属性统计后加入空白列" +-- /rb sum icon +L["Show Icon"] = "显示图示" +L["Show the sigma icon before summary listing"] = "在属性统计前显示图示" +-- /rb sum title +L["Show Title Text"] = "显示标题" +L["Show the title text before summary listing"] = "在属性统计前显示标题文字" +-- /rb sum showzerostat +L["Show Zero Value Stats"] = "显示数值为0的属性" +L["Show zero value stats in summary for consistancy"] = "为了一致性,在统计中显示数值为0的属性" +-- /rb sum calcsum +L["Calculate Stat Sum"] = "计算总和统计" +L["Calculate the total stats for the item"] = "计算物品的总和统计" +-- /rb sum calcdiff +L["Calculate Stat Diff"] = "计算差异统计" +L["Calculate the stat difference for the item and equipped items"] = "计算物品和已装备物品的统计差异" +-- /rb sum sort +L["Sort StatSummary Alphabetically"] = "按照字母排序" +L["Enable to sort StatSummary alphabetically, disable to sort according to stat type(basic, physical, spell, tank)"] = "启用以按照字母顺序排列,禁用按照属性类型排列(基础、物理、法术、抵抗……)" +-- /rb sum avoidhasblock +L["Include Block Chance In Avoidance Summary"] = "在躲避统计中显示格挡几率" +L["Enable to include block chance in Avoidance summary, Disable for only dodge, parry, miss"] = "启用该选项后将在躲避统计中加入格挡几率,禁用将仅显示躲闪,招架,未击中" +--------------------------------------------------------------------------- +-- /rb sum basic +L["Stat - Basic"] = "属性 - 基本" +L["Choose basic stats for summary"] = "选择想要统计的基本属性" +-- /rb sum basic hp +L["Sum Health"] = "统计生命值" +L["Health <- Health, Stamina"] = "生命值 ← 生命值、耐力" +-- /rb sum basic mp +L["Sum Mana"] = "统计法力值" +L["Mana <- Mana, Intellect"] = "法力值 ← 法力值、智力" +-- /rb sum basic mp5 +L["Sum Mana Regen"] = "统计法力恢复" +L["Mana Regen <- Mana Regen, Spirit"] = "法力恢复 ← 法力恢复、精神" +-- /rb sum basic mp5nc +L["Sum Mana Regen while not casting"] = "统计法力恢复(未施法时)" +L["Mana Regen while not casting <- Spirit"] = "法力恢复(未施法时) ← 精神" +-- /rb sum basic hp5 +L["Sum Health Regen"] = "统计生命恢复" +L["Health Regen <- Health Regen"] = "生命恢复 ← 生命恢复" +-- /rb sum basic hp5oc +L["Sum Health Regen when out of combat"] = "统计生命恢复(未战斗时)" +L["Health Regen when out of combat <- Spirit"] = "生命恢复(未战斗时) ← 精神" +-- /rb sum basic str +L["Sum Strength"] = "统计力量" +L["Strength Summary"] = "统计力量" +-- /rb sum basic agi +L["Sum Agility"] = "统计敏捷" +L["Agility Summary"] = "统计敏捷" +-- /rb sum basic sta +L["Sum Stamina"] = "统计耐力" +L["Stamina Summary"] = "统计耐力" +-- /rb sum basic int +L["Sum Intellect"] = "统计智力" +L["Intellect Summary"] = "统计智力" +-- /rb sum basic spi +L["Sum Spirit"] = "统计精神" +L["Spirit Summary"] = "统计精神" +-- /rb sum basic mastery +--L["Sum Mastery"] = "" +--L["Mastery Summary"] = "" +-- /rb sum basic masteryrating +--L["Sum Mastery Rating"] = "" +--L["Mastery Rating Summary"] = "" +--------------------------------------------------------------------------- +-- /rb sum physical +L["Stat - Physical"] = "属性 - 物理" +L["Choose physical damage stats for summary"] = "选择想要统计的物理攻击属性" +-- /rb sum physical ap +L["Sum Attack Power"] = "统计近战攻击强度" +L["Attack Power <- Attack Power, Strength, Agility"] = "近战攻击强度 ← 攻击强度、力量、敏捷" +-- /rb sum physical rap +L["Sum Ranged Attack Power"] = "统计远程攻击强度" +L["Ranged Attack Power <- Ranged Attack Power, Intellect, Attack Power, Strength, Agility"] = "远程攻击强度 ← 远程攻击强度、智力、攻击强度、力量、敏捷" +-- /rb sum physical fap +L["Sum Feral Attack Power"] = "统计野性攻击强度" +L["Feral Attack Power <- Feral Attack Power, Attack Power, Strength, Agility"] = "野性攻击强度 ← 野性攻击强度、攻击强度、力量、敏捷" +-- /rb sum physical hit +L["Sum Hit Chance"] = "统计物理命中几率" +--L["Hit Chance <- Hit Rating"] = "物理命中几率 ← 命中等级、武器技能等级" +-- /rb sum physical hitrating +L["Sum Hit Rating"] = "统计命中等级" +L["Hit Rating Summary"] = "统计命中等级" +-- /rb sum physical crit +L["Sum Crit Chance"] = "统计物理爆击几率" +--L["Crit Chance <- Crit Rating, Agility"] = "物理爆击几率 ← 爆击等级、敏捷、武器技能等级" +-- /rb sum physical critrating +L["Sum Crit Rating"] = "统计爆击等级" +L["Crit Rating Summary"] = "统计爆击等级" +-- /rb sum physical haste +L["Sum Haste"] = "统计急速" +L["Haste <- Haste Rating"] = "急速 ← 急速等级" +-- /rb sum physical hasterating +L["Sum Haste Rating"] = "统计急速等级" +L["Haste Rating Summary"] = "统计急速等级" +-- /rb sum physical rangedhit +L["Sum Ranged Hit Chance"] = "统计远程命中几率" +--L["Ranged Hit Chance <- Hit Rating, Ranged Hit Rating"] = "远程米中几率 ← 命中等级、武器技能等级、远程命中等级" +-- /rb sum physical rangedhitrating +L["Sum Ranged Hit Rating"] = "统计远程命中等级" +L["Ranged Hit Rating Summary"] = "统计远程命中等级" +-- /rb sum physical rangedcrit +L["Sum Ranged Crit Chance"] = "统计远爆击几率" +--L["Ranged Crit Chance <- Crit Rating, Agility, Ranged Crit Rating"] = "远程爆击几率 ← 爆击等级、敏捷、武器技能等级、远程爆击等级" +-- /rb sum physical rangedcritrating +L["Sum Ranged Crit Rating"] = "统计远程爆击等级" +L["Ranged Crit Rating Summary"] = "统计远程爆击等级" +-- /rb sum physical rangedhaste +L["Sum Ranged Haste"] = "统计远程急速" +L["Ranged Haste <- Haste Rating, Ranged Haste Rating"] = "远程急速 ← 急速等级、远程急速等级" +-- /rb sum physical rangedhasterating +L["Sum Ranged Haste Rating"] = "统计远程急速等级" +L["Ranged Haste Rating Summary"] = "统计远程急速等级" +-- /rb sum physical maxdamage +L["Sum Weapon Max Damage"] = "统计武器最大伤害" +L["Weapon Max Damage Summary"] = "统计武器最大伤害" +-- /rb sum physical weapondps +--L["Sum Weapon DPS"] = "统计武器DPS" +--L["Weapon DPS Summary"] = "武器DPS统计" +-- /rb sum physical wpn +L["Sum Weapon Skill"] = "统计武器技能" +L["Weapon Skill <- Weapon Skill Rating"] = "武器技能 ← 武器技能等级" +-- /rb sum physical exp +L["Sum Expertise"] = "统计精准" +L["Expertise <- Expertise Rating"] = "精准 ← 精准等级" +-- /rb sum physical exprating +L["Sum Expertise Rating"] = "统计精准等级" +L["Expertise Rating Summary"] = "统计精准等级" +--------------------------------------------------------------------------- +-- /rb sum spell +L["Stat - Spell"] = "属性 - 法术" +L["Choose spell damage and healing stats for summary"] = "选择想要统计的法术攻击和治疗的属性" +-- /rb sum spell dmg +L["Sum Spell Damage"] = "统计法术伤害" +L["Spell Damage <- Spell Damage, Intellect, Spirit, Stamina"] = "法术伤害 ← 法术伤害、智力、精神、耐力" +-- /rb sum spell dmgholy +L["Sum Holy Spell Damage"] = "统计神圣法术伤害" +L["Holy Spell Damage <- Holy Spell Damage, Spell Damage, Intellect, Spirit"] = "神圣法术伤害 ← 神圣法术伤害、法术伤害、智力、精神" +-- /rb sum spell dmgarcane +L["Sum Arcane Spell Damage"] = "统计奥术法术伤害" +L["Arcane Spell Damage <- Arcane Spell Damage, Spell Damage, Intellect"] = "奥术法术伤害 ← 奥术法术伤害、法术伤害、智力" +-- /rb sum spell dmgfire +L["Sum Fire Spell Damage"] = "统计火焰法术伤害" +L["Fire Spell Damage <- Fire Spell Damage, Spell Damage, Intellect, Stamina"] = "火焰法术伤害 ← 火焰法术伤害、法术伤害、智力、耐力" +-- /rb sum spell dmgnature +L["Sum Nature Spell Damage"] = "统计自然法术伤害" +L["Nature Spell Damage <- Nature Spell Damage, Spell Damage, Intellect"] = "自然法术伤害 ← 自然法术伤害、法术伤害、智力" +-- /rb sum spell dmgfrost +L["Sum Frost Spell Damage"] = "统计冰霜法术伤害" +L["Frost Spell Damage <- Frost Spell Damage, Spell Damage, Intellect"] = "冰霜法术伤害 ← 冰霜法术伤害、法术伤害、智力" +-- /rb sum spell dmgshadow +L["Sum Shadow Spell Damage"] = "统计暗影法术伤害" +L["Shadow Spell Damage <- Shadow Spell Damage, Spell Damage, Intellect, Spirit, Stamina"] = "暗影法术伤害 ← 暗影法术伤害、法术伤害、智力、精神、耐力" +-- /rb sum spell heal +L["Sum Healing"] = "统计治疗" +L["Healing <- Healing, Intellect, Spirit, Agility, Strength"] = "治疗 ← 治疗、智力、精神、敏捷、力量" +-- /rb sum spell crit +L["Sum Spell Crit Chance"] = "统计法术爆击几率" +L["Spell Crit Chance <- Spell Crit Rating, Intellect"] = "法术爆击几率 ← 法术爆击等级、智力" +-- /rb sum spell hit +L["Sum Spell Hit Chance"] = "统计法术命中几率" +L["Spell Hit Chance <- Spell Hit Rating"] = "法术命中几率 ← 法术命中等级" +-- /rb sum spell haste +L["Sum Spell Haste"] = "统计法术急速" +L["Spell Haste <- Spell Haste Rating"] = "法术急速 ← 法术急速等级" +-- /rb sum spell pen +L["Sum Penetration"] = "统计穿透" +L["Spell Penetration Summary"] = "统计法术穿透" +-- /rb sum spell hitrating +L["Sum Spell Hit Rating"] = "统计法术命中等级" +L["Spell Hit Rating Summary"] = "统计法术命中等级" +-- /rb sum spell critrating +L["Sum Spell Crit Rating"] = "统计法术爆击等级" +L["Spell Crit Rating Summary"] = "统计法术爆击等级" +-- /rb sum spell hasterating +L["Sum Spell Haste Rating"] = "统计法术急速等级" +L["Spell Haste Rating Summary"] = "统计法术急速等级" +--------------------------------------------------------------------------- +-- /rb sum tank +L["Stat - Tank"] = "属性 - 抗打击" +L["Choose tank stats for summary"] = "选择你想要统计的抗打击能力的属性" +-- /rb sum tank armor +L["Sum Armor"] = "统计护甲值" +--L["Armor <- Armor from items and bonuses"] = "护甲值 ← 物品护甲、护甲加成、敏捷、智力" +-- /rb sum tank dodge +L["Sum Dodge Chance"] = "统计躲闪几率" +--L["Dodge Chance <- Dodge Rating, Agility"] = "躲闪几率 ← 躲闪等级、敏捷、防御等级" +-- /rb sum tank parry +L["Sum Parry Chance"] = "统计招架几率" +--L["Parry Chance <- Parry Rating"] = "招架几率 ← 招架等级、防御等级" +-- /rb sum tank block +L["Sum Block Chance"] = "统计格挡几率" +--L["Block Chance <- Block Rating"] = "格挡几率 ← 格挡等级、防御等级" +-- /rb sum tank neglectdodge +L["Sum Dodge Neglect"] = "统计防止被躲闪" +--L["Dodge Neglect <- Expertise"] = "防止被躲闪 ← 精准等级、武器技能等级" +-- /rb sum tank neglectparry +L["Sum Parry Neglect"] = "统计防止被招架" +--L["Parry Neglect <- Expertise"] = "防止被招架 ← 精准等级、武器技能等级" +-- /rb sum tank resarcane +L["Sum Arcane Resistance"] = "统计奥术抗性" +L["Arcane Resistance Summary"] = "统计奥术抗性" +-- /rb sum tank resfire +L["Sum Fire Resistance"] = "统计火焰抗性" +L["Fire Resistance Summary"] = "统计火焰抗性" +-- /rb sum tank resnature +L["Sum Nature Resistance"] = "统计自然抗性" +L["Nature Resistance Summary"] = "统计自然抗性" +-- /rb sum tank resfrost +L["Sum Frost Resistance"] = "统计冰霜抗性" +L["Frost Resistance Summary"] = "统计冰霜抗性" +-- /rb sum tank resshadow +L["Sum Shadow Resistance"] = "统计暗影抗性" +L["Shadow Resistance Summary"] = "统计暗影抗性" +-- /rb sum tank dodgerating +L["Sum Dodge Rating"] = "统计躲闪等级" +L["Dodge Rating Summary"] = "统计躲闪等级" +-- /rb sum tank parryrating +L["Sum Parry Rating"] = "统计招架等级" +L["Parry Rating Summary"] = "统计招架等级" +-- /rb sum tank blockrating +L["Sum Block Rating"] = "统计格挡等级" +L["Block Rating Summary"] = "统计格挡等级" +-- /rb sum tank res +L["Sum Resilience"] = "统计韧性" +L["Resilience Summary"] = "统计韧性等级" +-- /rb sum tank tp +L["Sum TankPoints"] = "统计抗打击能力" +L["TankPoints <- Health, Total Reduction"] = "抗打击能力 ← 生命值, 所有伤害减免" +-- /rb sum tank tr +L["Sum Total Reduction"] = "统计伤害减免" +--L["Total Reduction <- Armor, Dodge, Parry, Block, MobMiss, MobCrit, MobCrush, DamageTakenMods"] = "所有伤害减免 <- 护甲值, 躲闪, 招架, 格挡, 格挡值, 防御技能, 韧性, 怪物未击中几率, 怪物重击几率, 怪物碾压打击几率, 伤害减免" +-- /rb sum tank avoid +L["Sum Avoidance"] = "统计躲避" +L["Avoidance <- Dodge, Parry, MobMiss, Block(Optional)"] = "躲避 ← 躲闪, 招架, 怪物未命中, 格挡(可选)" +--------------------------------------------------------------------------- +-- /rb sum gemset +-- L["Gem Set"] = true +-- L["Select a gem set to configure"] = true +-- L["Default Gem Set 1"] = true +-- L["Default Gem Set 2"] = true +-- L["Default Gem Set 3"] = true +-- /rb sum gem +L["Auto fill empty gem slots"] = "自动填充空宝石位" +-- /rb sum gem red +L["Red Socket"] = EMPTY_SOCKET_RED +L["ItemID or Link of the gem you would like to auto fill"] = "你想要填充该空格位的物品ID或者链接" +L[""] = "<物品ID|链接>" +L["|cffffff7f%s|r is now set to |cffffff7f[%s]|r"] = "|cffffff7f%s|r 已设置为 |cffffff7f[%s]|r" +L["Queried server for Gem: %s. Try again in 5 secs."] = "对服务器查询宝石: %s。将会在5秒后重试。" +-- /rb sum gem yellow +L["Yellow Socket"] = EMPTY_SOCKET_YELLOW +-- /rb sum gem blue +L["Blue Socket"] = EMPTY_SOCKET_BLUE +-- /rb sum gem meta +L["Meta Socket"] = EMPTY_SOCKET_META +-- /rb sum gem2 +--L["Second set of default gems which can be toggled with a modifier key"] = true +--L["Can't use the same modifier as Gem Set 3"] = true +-- /rb sum gem2 key +--L["Toggle Key"] = true +--L["Use this key to toggle alternate gems"] = true +-- /rb sum gem3 +--L["Third set of default gems which can be toggled with a modifier key"] = true +--L["Can't use the same modifier as Gem Set 2"] = true + +----------------------- +-- Item Level and ID -- +----------------------- +L["ItemLevel: "] = "物品等级: " +L["ItemID: "] = "物品编号: " +----------------------- +-- Matching Patterns -- +----------------------- +-- Items to check -- +-------------------- +-- [Potent Ornate Topaz] +-- +6 Spell Damage, +5 Spell Crit Rating +-------------------- +-- ZG enchant +-- +10 Defense Rating/+10 Stamina/+15 Block Value +-------------------- +-- [Glinting Flam Spessarite] +-- +3 Hit Rating and +3 Agility +-------------------- +-- ItemID: 22589 +-- [Atiesh, Greatstaff of the Guardian] warlock version +-- Equip: Increases the spell critical strike rating of all party members within 30 yards by 28. +-------------------- +-- [Brilliant Wizard Oil] +-- Use: While applied to target weapon it increases spell damage by up to 36 and increases spell critical strike rating by 14 . Lasts for 30 minutes. +---------------------------------------------------------------------------------------------------- +-- I redesigned the tooltip scanner using a more locale friendly, 2 pass matching matching algorithm. +-- +-- The first pass searches for the rating number, the patterns are read from L["numberPatterns"] here, +-- " by (%d+)" will match strings like: "Increases defense rating by 16." +-- "%+(%d+)" will match strings like: "+10 Defense Rating" +-- You can add additional patterns if needed, its not limited to 2 patterns. +-- The separators are a table of strings used to break up a line into multiple lines what will be parsed seperately. +-- For example "+3 Hit Rating, +5 Spell Crit Rating" will be split into "+3 Hit Rating" and " +5 Spell Crit Rating" +-- +-- The second pass searches for the rating name, the names are read from L["statList"] here, +-- It will look through the table in order, so you can put common strings at the begining to speed up the search, +-- and longer strings should be listed first, like "spell critical strike" should be listed before "critical strike", +-- this way "spell critical strike" does get matched by "critical strike". +-- Strings need to be in lower case letters, because string.lower is called on lookup +-- +-- IMPORTANT: there may not exist a one-to-one correspondence, meaning you can't just translate this file, +-- but will need to go in game and find out what needs to be put in here. +-- For example, in english I found 3 different strings that maps to CR_CRIT_MELEE: "critical strike", "critical hit" and "crit". +-- You will need to find out every string that represents CR_CRIT_MELEE, and so on. +-- In other languages there may be 5 different strings that should all map to CR_CRIT_MELEE. +-- so please check in game that you have all strings, and not translate directly off this table. +-- +-- Tip1: When doing localizations, I recommend you set debugging to true in RatingBuster.lua +-- Find RatingBuster:SetDebugging(false) and change it to RatingBuster:SetDebugging(true) +-- or you can type /rb debug to enable it in game +-- +-- Tip2: The strings are passed into string.find, so you should escape the magic characters ^$()%.[]*+-? with a % +L["numberPatterns"] = { + {pattern = "(%d+)。", addInfo = "AfterNumber",}, + {pattern = "([%+%-]%d+)", addInfo = "AfterStat",}, + {pattern = "佩戴者.-(%d+)", addInfo = "AfterNumber",}, -- for "grant you xx stat" type pattern, ex: Quel'Serrar, Assassination Armor set + {pattern = "提高.-(%d+)", addInfo = "AfterNumber",}, + -- Added [^%%] so that it doesn't match strings like "Increases healing by up to 10% of your total Intellect." [Whitemend Pants] ID: 24261 + -- Added [^|] so that it doesn't match enchant strings (JewelTips) + {pattern = "(%d+)([^%d%%|]+)", addInfo = "AfterStat",}, -- [发光的暗影卓奈石] +6法术伤害及5耐力 +} +L["separators"] = { + "/", "和", ",", "。", " 持续 ", "&", "及", "并", ",","、", +} +--[[ Rating ID +CR_WEAPON_SKILL = 1; +CR_DEFENSE_SKILL = 2; +CR_DODGE = 3; +CR_PARRY = 4; +CR_BLOCK = 5; +CR_HIT_MELEE = 6; +CR_HIT_RANGED = 7; +CR_HIT_SPELL = 8; +CR_CRIT_MELEE = 9; +CR_CRIT_RANGED = 10; +CR_CRIT_SPELL = 11; +CR_HIT_TAKEN_MELEE = 12; +CR_HIT_TAKEN_RANGED = 13; +CR_HIT_TAKEN_SPELL = 14; +CR_CRIT_TAKEN_MELEE = 15; +CR_CRIT_TAKEN_RANGED = 16; +CR_CRIT_TAKEN_SPELL = 17; +CR_HASTE_MELEE = 18; +CR_HASTE_RANGED = 19; +CR_HASTE_SPELL = 20; +CR_WEAPON_SKILL_MAINHAND = 21; +CR_WEAPON_SKILL_OFFHAND = 22; +CR_WEAPON_SKILL_RANGED = 23; +CR_EXPERTISE = 24; +-- +SPELL_STAT1_NAME = "Strength" +SPELL_STAT2_NAME = "Agility" +SPELL_STAT3_NAME = "Stamina" +SPELL_STAT4_NAME = "Intellect" +SPELL_STAT5_NAME = "Spirit" +--]] +L["statList"] = { + {pattern = string.lower(SPELL_STAT1_NAME), id = SPELL_STAT1_NAME}, -- Strength + {pattern = string.lower(SPELL_STAT2_NAME), id = SPELL_STAT2_NAME}, -- Agility + {pattern = string.lower(SPELL_STAT3_NAME), id = SPELL_STAT3_NAME}, -- Stamina + {pattern = string.lower(SPELL_STAT4_NAME), id = SPELL_STAT4_NAME}, -- Intellect + {pattern = string.lower(SPELL_STAT5_NAME), id = SPELL_STAT5_NAME}, -- Spirit + {pattern = "防御等级", id = CR_DEFENSE_SKILL}, + {pattern = "躲闪等级", id = CR_DODGE}, + {pattern = "格挡等级", id = CR_BLOCK}, -- block enchant: "+10 Shield Block Rating" + {pattern = "招架等级", id = CR_PARRY}, + + {pattern = "法术爆击等级", id = CR_CRIT_SPELL}, + {pattern = "法术爆击命中等级", id = CR_CRIT_SPELL}, + {pattern = "法术爆击等级", id = CR_CRIT_SPELL}, + {pattern = "远程爆击等级", id = CR_CRIT_RANGED}, + {pattern = "远程爆击命中等级", id = CR_CRIT_RANGED}, + {pattern = "远程爆击等级", id = CR_CRIT_RANGED}, + {pattern = "近战爆击等级", id = CR_CRIT_MELEE}, + {pattern = "爆击等级", id = CR_CRIT_MELEE}, + + {pattern = "法术命中等级", id = CR_HIT_SPELL}, + {pattern = "远程命中等级", id = CR_HIT_RANGED}, + {pattern = "命中等级", id = CR_HIT_MELEE}, + + {pattern = "韧性等级", id = CR_CRIT_TAKEN_MELEE}, -- resilience is implicitly a rating + + {pattern = "法术急速等级", id = CR_HASTE_SPELL}, + {pattern = "远程急速等级", id = CR_HASTE_RANGED}, + {pattern = "急速等级", id = CR_HASTE_MELEE}, + {pattern = "加速等级", id = CR_HASTE_MELEE}, -- [Drums of Battle] + + {pattern = "武器技能等级", id = CR_WEAPON_SKILL}, + {pattern = "精准等级", id = CR_EXPERTISE}, + + {pattern = "命中躲闪等级", id = CR_HIT_TAKEN_MELEE}, + {pattern = "护甲穿透等级", id = CR_ARMOR_PENETRATION}, + {pattern = string.lower(ARMOR), id = ARMOR}, + --[[ + {pattern = "dagger skill rating", id = CR_WEAPON_SKILL}, + {pattern = "sword skill rating", id = CR_WEAPON_SKILL}, + {pattern = "two%-handed swords skill rating", id = CR_WEAPON_SKILL}, + {pattern = "axe skill rating", id = CR_WEAPON_SKILL}, + {pattern = "bow skill rating", id = CR_WEAPON_SKILL}, + {pattern = "crossbow skill rating", id = CR_WEAPON_SKILL}, + {pattern = "gun skill rating", id = CR_WEAPON_SKILL}, + {pattern = "feral combat skill rating", id = CR_WEAPON_SKILL}, + {pattern = "mace skill rating", id = CR_WEAPON_SKILL}, + {pattern = "polearm skill rating", id = CR_WEAPON_SKILL}, + {pattern = "staff skill rating", id = CR_WEAPON_SKILL}, + {pattern = "two%-handed axes skill rating", id = CR_WEAPON_SKILL}, + {pattern = "two%-handed maces skill rating", id = CR_WEAPON_SKILL}, + {pattern = "fist weapons skill rating", id = CR_WEAPON_SKILL}, + --]] +} +------------------------- +-- Added info patterns -- +------------------------- +-- $value will be replaced with the number +-- EX: "$value% Crit" -> "+1.34% Crit" +-- EX: "Crit $value%" -> "Crit +1.34%" +L["$value% Crit"] = "$value% 爆击" +L["$value% Spell Crit"] = "$value% 法爆" +L["$value% Dodge"] = "$value% 躲闪" +L["$value HP"] = "$value 生命" +L["$value MP"] = "$value 法力" +L["$value AP"] = "$value 攻击强度" +L["$value RAP"] = "$value 远攻强度" +L["$value Dmg"] = "$value 法伤" +L["$value Heal"] = "$value 治疗" +L["$value Armor"] = "$value 护甲" +L["$value Block"] = "$value 格挡值" +L["$value MP5"] = "$value 施法回魔" +L["$value MP5(NC)"] = "$value 精神回魔" +L["$value HP5"] = "$value 回血" +L["$value to be Dodged/Parried"] = "$value 被躲闪/被招架" +L["$value to be Crit"] = "$value 被致命一击" +L["$value Crit Dmg Taken"] = "$value 致命一击伤害减免" +L["$value DOT Dmg Taken"] = "$value 持续伤害减免" +L["$value% Parry"] = "$value% 招架" +-- for hit rating showing both physical and spell conversions +-- (+1.21%, S+0.98%) +-- (+1.21%, +0.98% S) +L["$value Spell"] = "$value 法术" + +------------------ +-- Stat Summary -- +------------------ +L["Stat Summary"] = "属性统计" \ No newline at end of file diff --git a/RatingBuster/RatingBuster-Locale-zhTW.lua b/RatingBuster/RatingBuster-Locale-zhTW.lua new file mode 100644 index 0000000..23d02e0 --- /dev/null +++ b/RatingBuster/RatingBuster-Locale-zhTW.lua @@ -0,0 +1,713 @@ +--[[ +Name: RatingBuster zhTW locale +Revision: $Revision: 294 $ +Translated by: +- Whitetooth@Cenarius (hotdogee@bahamut.twbbs.org) +- CuteMiyu +- 小紫 +- mcc +]] + +local L = LibStub("AceLocale-3.0"):NewLocale("RatingBuster", "zhTW") +if not L then return end +-- This file is coded in UTF-8 +-- If you don't have a editor that can save in UTF-8, I recommend Ultraedit +---- +-- To translate AceLocale strings, replace true with the translation string +-- Before: L["Show Item ID"] = true +-- After: L["Show Item ID"] = "顯示物品編號" +--------------- +-- Waterfall -- +--------------- +L["RatingBuster Options"] = "屬性轉換選項" +L["Waterfall-1.0 is required to access the GUI."] = "需要 Waterfall-1.0 才能使用設定介面。" +L["Enabled"] = "啟用" +L["Suspend/resume this addon"] = "暫停/繼續使用這個插件" +--------------------------- +-- Slash Command Options -- +--------------------------- +L["Always"] = "永遠顯示" +L["ALT Key"] = "ALT 鍵" +L["CTRL Key"] = "CTRL 鍵" +L["SHIFT Key"] = "SHIFT 鍵" +L["Never"] = "不顯示" +L["General Settings"] = "一般設定" +L["Profiles"] = "設定檔" +-- /rb win +L["Options Window"] = "選項視窗" +L["Shows the Options Window"] = "顯示選項視窗" +-- /rb hidebzcomp +L["Hide Blizzard Item Comparisons"] = "隱藏內建的物品比較" +L["Disable Blizzard stat change summary when using the built-in comparison tooltip"] = "觀看內建的已裝備物品提示時不顯示內建的物品比較功能" +-- /rb statmod +L["Enable Stat Mods"] = "屬性加成" +L["Enable support for Stat Mods"] = "啟用屬性加成計算" +-- /rb avoidancedr +L["Enable Avoidance Diminishing Returns"] = "啟用迴避遞減效應" +L["Dodge, Parry, Hit Avoidance values will be calculated using the avoidance deminishing return formula with your current stats"] = "你的閃避、招架、避免命中值會被計算在迴避遞減效應中" +-- /rb itemid +L["Show ItemID"] = "顯示物品編號" +L["Show the ItemID in tooltips"] = "顯示物品編號" +-- /rb itemlevel +L["Show ItemLevel"] = "顯示物品等級" +L["Show the ItemLevel in tooltips"] = "顯示物品等級" +-- /rb usereqlv +L["Use Required Level"] = "使用需要等級" +L["Calculate using the required level if you are below the required level"] = "如果你的等級低於需要等級則用需要等級來換算" +-- /rb level +L["Set Level"] = "設定換算等級" +L["Set the level used in calculations (0 = your level)"] = "設定換算等級 (0 = 你的目前的等級)" +--------------------------------------------------------------------------- +-- /rb rating +L["Rating"] = "屬性等級" +L["Options for Rating display"] = "設定屬性等級顯示" +-- /rb rating show +L["Show Rating Conversions"] = "顯示屬性等級轉換" +L["Show Rating conversions in tooltips"] = "在提示框架中顯示屬性等級轉換結果" +-- /rb rating spell +L["Show Spell Hit/Haste"] = "顯示法術命中/加速" +L["Show Spell Hit/Haste from Hit/Haste Rating"] = "顯示命中/加速給的法術命中/加速" +-- /rb rating physical +L["Show Physical Hit/Haste"] = "顯示物理命中/加速" +L["Show Physical Hit/Haste from Hit/Haste Rating"] = "顯示命中/加速給的物理命中/加速" +-- /rb rating detail +L["Show Detailed Conversions Text"] = "顯示詳細轉換文字" +L["Show detailed text for Resilience and Expertise conversions"] = "顯示韌性和熟練技能的詳細轉換文字" +-- /rb rating exp +L["Expertise Breakdown"] = "分析熟練技能" +L["Convert Expertise into Dodge Neglect and Parry Neglect"] = "將熟練技能分為防止被閃躲、防止被招架" +--------------------------------------------------------------------------- +-- /rb rating color +L["Change Text Color"] = "設定文字顏色" +L["Changes the color of added text"] = "設定 RB 所增加的文字的顏色" +-- /rb rating color pick +L["Pick Color"] = "挑選顏色" +L["Pick a color"] = "挑選顏色" +-- /rb rating color enable +L["Enable Color"] = "啟用文字顏色" +L["Enable colored text"] = "啟用文字顏色" +--------------------------------------------------------------------------- +-- /rb stat +L["Stat Breakdown"] = "基本屬性解析" +L["Changes the display of base stats"] = "設定基本屬性的解析顯示" +-- /rb stat show +L["Show Base Stat Conversions"] = "顯示基本屬性解析" +L["Show base stat conversions in tooltips"] = "在物品提示中顯示基本屬性解析" +--------------------------------------------------------------------------- +-- /rb stat str +L["Strength"] = "力量" +L["Changes the display of Strength"] = "自訂力量解析項目" +-- /rb stat str ap +L["Show Attack Power"] = "顯示攻擊強度" +L["Show Attack Power from Strength"] = "顯示力量給的攻擊強度" +-- /rb stat str block +L["Show Block Value"] = "顯示格檔值" +L["Show Block Value from Strength"] = "顯示力量給的格檔值" +-- /rb stat str dmg +L["Show Spell Damage"] = "顯示法傷" +L["Show Spell Damage from Strength"] = "顯示力量給的法術傷害加成" +-- /rb stat str heal +L["Show Healing"] = "顯示治療" +L["Show Healing from Strength"] = "顯示力量給的治療加成" +-- /rb stat str parry +L["Show Parry"] = "顯示招架" +L["Show Parry from Strength"] = "顯示力量給的招架加成" +--------------------------------------------------------------------------- +-- /rb stat agi +L["Agility"] = "敏捷" +L["Changes the display of Agility"] = "自訂敏捷解析項目" +-- /rb stat agi crit +L["Show Crit"] = "顯示致命" +L["Show Crit chance from Agility"] = "顯示敏捷給的致命一擊機率" +-- /rb stat agi dodge +L["Show Dodge"] = "顯示閃躲" +L["Show Dodge chance from Agility"] = "顯示敏捷給的閃躲機率" +-- /rb stat agi ap +L["Show Attack Power"] = "顯示攻擊強度" +L["Show Attack Power from Agility"] = "顯示敏捷給的攻擊強度" +-- /rb stat agi rap +L["Show Ranged Attack Power"] = "顯示遠程攻擊強度" +L["Show Ranged Attack Power from Agility"] = "顯示敏捷給的遠程攻擊強度" +-- /rb stat agi armor +L["Show Armor"] = "顯示裝甲值" +L["Show Armor from Agility"] = "顯示敏捷給的裝甲值" +-- /rb stat agi heal +L["Show Healing"] = "顯示治療" +L["Show Healing from Agility"] = "顯示敏捷給的治療加成" +--------------------------------------------------------------------------- +-- /rb stat sta +L["Stamina"] = "耐力" +L["Changes the display of Stamina"] = "自訂耐力解析項目" +-- /rb stat sta hp +L["Show Health"] = "顯示生命力" +L["Show Health from Stamina"] = "顯示耐力給的生命力" +-- /rb stat sta dmg +L["Show Spell Damage"] = "顯示法傷" +L["Show Spell Damage from Stamina"] = "顯示耐力給的法術傷害加成" +-- /rb stat sta heal +L["Show Healing"] = "顯示治療" +L["Show Healing from Stamina"] = "顯示耐力給的治療加成" +-- /rb stat sta ap +L["Show Attack Power"] = "顯示治療" +L["Show Attack Power from Stamina"] = "顯示耐力給的攻擊強度" +--------------------------------------------------------------------------- +-- /rb stat int +L["Intellect"] = "智力" +L["Changes the display of Intellect"] = "自訂智力解析項目" +-- /rb stat int spellcrit +L["Show Spell Crit"] = "顯示法術致命" +L["Show Spell Crit chance from Intellect"] = "顯示智力給的法術致命一擊機率" +-- /rb stat int mp +L["Show Mana"] = "顯示法力" +L["Show Mana from Intellect"] = "顯示智力給的法力" +-- /rb stat int dmg +L["Show Spell Damage"] = "顯示法傷" +L["Show Spell Damage from Intellect"] = "顯示智力給的法術傷害加成" +-- /rb stat int heal +L["Show Healing"] = "顯示治療" +L["Show Healing from Intellect"] = "顯示智力給的治療加成" +-- /rb stat int mp5 +L["Show Mana Regen"] = "顯示施法回魔" +L["Show Mana Regen while casting from Intellect"] = "顯示智力給的施法中法力恢復量" +-- /rb stat int mp5nc +L["Show Mana Regen while NOT casting"] = "顯示一般回魔" +L["Show Mana Regen while NOT casting from Intellect"] = "顯示在未施法狀態時,智力給的法力恢復量" +-- /rb stat int rap +L["Show Ranged Attack Power"] = "顯示遠程攻擊強度" +L["Show Ranged Attack Power from Intellect"] = "顯示智力給的遠程攻擊強度" +-- /rb stat int armor +L["Show Armor"] = "顯示裝甲值" +L["Show Armor from Intellect"] = "顯示智力給的裝甲值" +-- /rb stat int ap +L["Show Attack Power"] = "顯示攻擊強度" +L["Show Attack Power from Intellect"] = "顯示智力給的攻擊強度" +--------------------------------------------------------------------------- +-- /rb stat spi +L["Spirit"] = "精神" +L["Changes the display of Spirit"] = "自訂精神解析項目" +-- /rb stat spi mp5 +L["Show Mana Regen"] = "顯示施法回魔" +L["Show Mana Regen while casting from Spirit"] = "顯示在施法狀態時,精神給的法力恢復量" +-- /rb stat spi mp5nc +L["Show Mana Regen while NOT casting"] = "顯示一般回魔" +L["Show Mana Regen while NOT casting from Spirit"] = "顯示在未施法狀態時,精神給的法力恢復量" +-- /rb stat spi hp5 +L["Show Health Regen"] = "顯示回血" +L["Show Health Regen from Spirit"] = "顯示精神給的戰鬥外回生命力" +-- /rb stat spi dmg +L["Show Spell Damage"] = "顯示法傷" +L["Show Spell Damage from Spirit"] = "顯示精神給的法術傷害加成" +-- /rb stat spi heal +L["Show Healing"] = "顯示治療" +L["Show Healing from Spirit"] = "顯示精神給的治療加成" +-- /rb stat spi spellcrit +L["Show Spell Crit"] = "顯示法術致命" +L["Show Spell Crit chance from Spirit"] = "顯示精神給的法術致命一擊機率" +--------------------------------------------------------------------------- +-- /rb stat armor +L["Armor"] = "護甲" +L["Changes the display of Armor"] = "自訂護甲解析項目" +-- /rb stat armor ap +L["Show Attack Power"] = "顯示攻擊強度" +L["Show Attack Power from Armor"] = "顯示護甲給的攻擊強度" +--------------------------------------------------------------------------- +-- /rb sum +L["Stat Summary"] = "屬性統計" +L["Options for stat summary"] = "自訂屬性選項" +-- /rb sum show +L["Show Stat Summary"] = "顯示屬性統計" +L["Show stat summary in tooltips"] = "在物品提示中顯示屬性統計" +-- /rb sum ignore +L["Ignore Settings"] = "忽略設定" +L["Ignore stuff when calculating the stat summary"] = "設定在統計總合時所要忽略的項目" +-- /rb sum ignore unused +L["Ignore Undesirable Items"] = "忽略不想要的物品" +L["Hide stat summary for undesirable items"] = "只在你可以裝備的物品顯示屬性統計" +-- /rb sum ignore quality +L["Minimum Item Quality"] = "最低物品品質" +L["Show stat summary only for selected quality items and up"] = "只在你所選的品質或更好的物品上顯示屬性統計" +-- /rb sum ignore armor +L["Armor Types"] = "護甲種類" +L["Select armor types you want to ignore"] = "選擇你想忽略的護甲種類" +-- /rb sum ignore armor cloth +L["Ignore Cloth"] = "忽略布甲" +L["Hide stat summary for all cloth armor"] = "隱藏所有布甲的屬性統計" +-- /rb sum ignore armor leather +L["Ignore Leather"] = "忽略皮甲" +L["Hide stat summary for all leather armor"] = "隱藏所有皮甲的屬性統計" +-- /rb sum ignore armor mail +L["Ignore Mail"] = "忽略鎖甲" +L["Hide stat summary for all mail armor"] = "隱藏所有鎖甲的屬性統計" +-- /rb sum ignore armor plate +L["Ignore Plate"] = "忽略鎧甲" +L["Hide stat summary for all plate armor"] = "隱藏所有鎧甲的屬性統計" +-- /rb sum ignore equipped +L["Ignore Equipped Items"] = "忽略已裝備的物品" +L["Hide stat summary for equipped items"] = "隱藏已裝備的物品的屬性統計" +-- /rb sum ignore enchant +L["Ignore Enchants"] = "忽略附魔" +L["Ignore enchants on items when calculating the stat summary"] = "統計時忽略物品上的附魔效果" +-- /rb sum ignore gem +L["Ignore Gems"] = "忽略寶石" +L["Ignore gems on items when calculating the stat summary"] = "統計時忽略物品上的寶石效果" +-- /rb sum ignore prismaticSocket +L["Ignore Prismatic Sockets"] = "忽略多色插槽" +L["Ignore gems in prismatic sockets when calculating the stat summary"] = "統計時忽略多色插槽裡的寶石效果" +-- /rb sum diffstyle +L["Display Style For Diff Value"] = "差異值顯示方式" +L["Display diff values in the main tooltip or only in compare tooltips"] = "設定在主提示框架或只在比較框架中顯示差異值" +-- /rb sum space +L["Add Empty Line"] = "加入空白列" +L["Add a empty line before or after stat summary"] = "在物品提示中的屬性統計前或後加入空白列" +-- /rb sum space before +L["Add Before Summary"] = "加在統計前" +L["Add a empty line before stat summary"] = "在物品提示中的屬性統計前加入空白列" +-- /rb sum space after +L["Add After Summary"] = "加在統計後" +L["Add a empty line after stat summary"] = "在物品提示中的屬性統計後加入空白列" +-- /rb sum icon +L["Show Icon"] = "顯示圖示" +L["Show the sigma icon before summary listing"] = "在屬性統計前顯示圖示" +-- /rb sum title +L["Show Title Text"] = "顯示標題" +L["Show the title text before summary listing"] = "在屬性統計前顯示標題文字" +-- /rb sum showzerostat +L["Show Zero Value Stats"] = "顯示數值為 0 的屬性" +L["Show zero value stats in summary for consistancy"] = "為了一致性,在統計中顯示數值為 0 的屬性" +-- /rb sum calcsum +L["Calculate Stat Sum"] = "計算統計總合" +L["Calculate the total stats for the item"] = "計算物品的統計總合" +-- /rb sum calcdiff +L["Calculate Stat Diff"] = "計算統計差異" +L["Calculate the stat difference for the item and equipped items"] = "計算物品和已裝備物品的統計差異" +-- /rb sum sort +L["Sort StatSummary Alphabetically"] = "依字幕順序排列屬性統計" +L["Enable to sort StatSummary alphabetically, disable to sort according to stat type(basic, physical, spell, tank)"] = "開啟時依字幕順序排列,關閉時依屬性種類排列(基本、物理、魔法、坦克)" +-- /rb sum avoidhasblock +L["Include Block Chance In Avoidance Summary"] = "傷害迴避包含格檔率" +L["Enable to include block chance in Avoidance summary, Disable for only dodge, parry, miss"] = "開啟時傷害迴避包含格檔率,關閉時有閃躲、招架、未擊中" +--------------------------------------------------------------------------- +-- /rb sum basic +L["Stat - Basic"] = "統計基本屬性" +L["Choose basic stats for summary"] = "自訂基本屬性統計項目" +-- /rb sum basic hp +L["Sum Health"] = "統計生命力" +L["Health <- Health, Stamina"] = "生命力 ← 生命力、耐力" +-- /rb sum basic mp +L["Sum Mana"] = "統計法力" +L["Mana <- Mana, Intellect"] = "法力 ← 法力、智力" +-- /rb sum basic mp5 +L["Sum Mana Regen"] = "統計法力恢復" +L["Mana Regen <- Mana Regen, Spirit"] = "法力恢復 ← 法力恢復、精神" +-- /rb sum basic mp5nc +L["Sum Mana Regen while not casting"] = "統計法力恢復 (未施法時)" +L["Mana Regen while not casting <- Spirit"] = "法力恢復 (未施法時) ← 精神" +-- /rb sum basic hp5 +L["Sum Health Regen"] = "統計生命恢復" +L["Health Regen <- Health Regen"] = "生命恢復 ← 生命恢復" +-- /rb sum basic hp5oc +L["Sum Health Regen when out of combat"] = "統計生命恢復 (未戰鬥時)" +L["Health Regen when out of combat <- Spirit"] = "生命恢復 (未戰鬥時) ← 精神" +-- /rb sum basic str +L["Sum Strength"] = "統計力量" +L["Strength Summary"] = "統計力量" +-- /rb sum basic agi +L["Sum Agility"] = "統計敏捷" +L["Agility Summary"] = "統計敏捷" +-- /rb sum basic sta +L["Sum Stamina"] = "統計耐力" +L["Stamina Summary"] = "統計耐力" +-- /rb sum basic int +L["Sum Intellect"] = "統計智力" +L["Intellect Summary"] = "統計智力" +-- /rb sum basic spi +L["Sum Spirit"] = "統計精神" +L["Spirit Summary"] = "統計精神" +-- /rb sum basic mastery +L["Sum Mastery"] = "統計精通" +L["Mastery Summary"] = "統計精通" +-- /rb sum basic masteryrating +L["Sum Mastery Rating"] = "統計精通等級" +L["Mastery Rating Summary"] = "統計精通等級" +--------------------------------------------------------------------------- +-- /rb sum physical +L["Stat - Physical"] = "統計物理屬性" +L["Choose physical damage stats for summary"] = "自訂物理傷害屬性統計項目" +-- /rb sum physical ap +L["Sum Attack Power"] = "統計攻擊強度" +L["Attack Power <- Attack Power, Strength, Agility"] = "攻擊強度 ← 攻擊強度、力量、敏捷" +-- /rb sum physical rap +L["Sum Ranged Attack Power"] = "統計遠程攻擊強度" +L["Ranged Attack Power <- Ranged Attack Power, Intellect, Attack Power, Strength, Agility"] = "遠程攻擊強度 ← 遠程攻擊強度、智力、攻擊強度、力量、敏捷" +-- /rb sum physical fap +L["Sum Feral Attack Power"] = "統計野性攻擊強度" +L["Feral Attack Power <- Feral Attack Power, Attack Power, Strength, Agility"] = "野性攻擊強度 ← 野性攻擊強度、攻擊強度、力量、敏捷" +-- /rb sum physical hit +L["Sum Hit Chance"] = "統計命中機率" +--L["Hit Chance <- Hit Rating"] = "命中機率 ← 命中等級、武器技能等級" +-- /rb sum physical hitrating +L["Sum Hit Rating"] = "統計命中等級" +L["Hit Rating Summary"] = "統計命中等級" +-- /rb sum physical crit +L["Sum Crit Chance"] = "統計致命一擊機率" +--L["Crit Chance <- Crit Rating, Agility"] = "致命一擊機率 ← 致命一擊等級、敏捷、武器技能等級" +-- /rb sum physical critrating +L["Sum Crit Rating"] = "統計致命等級" +L["Crit Rating Summary"] = "統計致命等級" +-- /rb sum physical haste +L["Sum Haste"] = "統計加速" +L["Haste <- Haste Rating"] = "加速 ← 加速等級" +-- /rb sum physical hasterating +L["Sum Haste Rating"] = "統計加速等級" +L["Haste Rating Summary"] = "統計加速等級" +-- /rb sum physical rangedhit +L["Sum Ranged Hit Chance"] = "統計遠程命中機率" +--L["Ranged Hit Chance <- Hit Rating, Ranged Hit Rating"] = "遠程命中機率 ← 命中等級、武器技能等級、遠程命中等級" +-- /rb sum physical rangedhitrating +L["Sum Ranged Hit Rating"] = "統計遠程命中等級" +L["Ranged Hit Rating Summary"] = "統計遠程命中等級" +-- /rb sum physical rangedcrit +L["Sum Ranged Crit Chance"] = "統計遠程致命一級機率" +--L["Ranged Crit Chance <- Crit Rating, Agility, Ranged Crit Rating"] = "遠程致命一擊機率 ← 致命一擊等級、敏捷、武器技能等級、遠程致命一級等級" +-- /rb sum physical rangedcritrating +L["Sum Ranged Crit Rating"] = "統計遠程致命一級等級" +L["Ranged Crit Rating Summary"] = "統計遠程致命一級等級" +-- /rb sum physical rangedhaste +L["Sum Ranged Haste"] = "統計遠程加速" +L["Ranged Haste <- Haste Rating, Ranged Haste Rating"] = "遠程加速 ← 加速等級、遠程加速等級" +-- /rb sum physical rangedhasterating +L["Sum Ranged Haste Rating"] = "統計遠程加速等級" +L["Ranged Haste Rating Summary"] = "統計遠程加速等級" +-- /rb sum physical maxdamage +L["Sum Weapon Max Damage"] = "統計武器最大傷害" +L["Weapon Max Damage Summary"] = "統計武器最大傷害" +-- /rb sum physical weapondps +--L["Sum Weapon DPS"] = true +--L["Weapon DPS Summary"] = true +-- /rb sum physical wpn +L["Sum Weapon Skill"] = "統計武器技能" +L["Weapon Skill <- Weapon Skill Rating"] = "武器技能 ← 武器技能等級" +-- /rb sum physical exp +L["Sum Expertise"] = "統計熟練技能" +L["Expertise <- Expertise Rating"] = "熟練技能 ← 熟練等級" +-- /rb sum physical exprating +L["Sum Expertise Rating"] = "統計熟練等級" +L["Expertise Rating Summary"] = "統計熟練等級" +--------------------------------------------------------------------------- +-- /rb sum spell +L["Stat - Spell"] = "統計魔法屬性" +L["Choose spell damage and healing stats for summary"] = "自訂魔法傷害及治療屬性統計項目" +-- /rb sum spell dmg +L["Sum Spell Damage"] = "統計法術傷害" +L["Spell Damage <- Spell Damage, Intellect, Spirit, Stamina"] = "法術傷害 ← 法術傷害、智力、精神、耐力" +-- /rb sum spell dmgholy +L["Sum Holy Spell Damage"] = "統計神聖法術傷害" +L["Holy Spell Damage <- Holy Spell Damage, Spell Damage, Intellect, Spirit"] = "神聖法術傷害 ← 神聖法術傷害、法術傷害、智力、精神" +-- /rb sum spell dmgarcane +L["Sum Arcane Spell Damage"] = "統計秘法法術傷害" +L["Arcane Spell Damage <- Arcane Spell Damage, Spell Damage, Intellect"] = "秘法法術傷害 ← 秘法法術傷害、法術傷害、智力" +-- /rb sum spell dmgfire +L["Sum Fire Spell Damage"] = "統計火焰法術傷害" +L["Fire Spell Damage <- Fire Spell Damage, Spell Damage, Intellect, Stamina"] = "火焰法術傷害 ← 火焰法術傷害、法術傷害、智力、耐力" +-- /rb sum spell dmgnature +L["Sum Nature Spell Damage"] = "統計自然法術傷害" +L["Nature Spell Damage <- Nature Spell Damage, Spell Damage, Intellect"] = "自然法術傷害 ← 自然法術傷害、法術傷害、智力" +-- /rb sum spell dmgfrost +L["Sum Frost Spell Damage"] = "統計冰霜法術傷害" +L["Frost Spell Damage <- Frost Spell Damage, Spell Damage, Intellect"] = "冰霜法術傷害 ← 冰霜法術傷害、法術傷害、智力" +-- /rb sum spell dmgshadow +L["Sum Shadow Spell Damage"] = "統計暗影法術傷害" +L["Shadow Spell Damage <- Shadow Spell Damage, Spell Damage, Intellect, Spirit, Stamina"] = "暗影法術傷害 ← 暗影法術傷害、法術傷害、智力、精神、耐力" +-- /rb sum spell heal +L["Sum Healing"] = "統計治療" +L["Healing <- Healing, Intellect, Spirit, Agility, Strength"] = "治療 ← 治療、智力、精神、敏捷、力量" +-- /rb sum spell crit +L["Sum Spell Crit Chance"] = "統計法術致命一擊機率" +L["Spell Crit Chance <- Spell Crit Rating, Intellect"] = "法術致命一擊機率 ← 法術致命一擊等級、智力" +-- /rb sum spell hit +L["Sum Spell Hit Chance"] = "統計法術命中機率" +L["Spell Hit Chance <- Spell Hit Rating"] = "法術命中機率 ← 法術命中機率" +-- /rb sum spell haste +L["Sum Spell Haste"] = "統計法術加速" +L["Spell Haste <- Spell Haste Rating"] = "法術加速 ← 法術加速等級" +-- /rb sum spell pen +L["Sum Penetration"] = "統計法術穿透力" +L["Spell Penetration Summary"] = "統計法術穿透力" +-- /rb sum spell hitrating +L["Sum Spell Hit Rating"] = "統計法術命中等級" +L["Spell Hit Rating Summary"] = "統計法術命中等級" +-- /rb sum spell critrating +L["Sum Spell Crit Rating"] = "統計法術致命等級" +L["Spell Crit Rating Summary"] = "統計法術致命等級" +-- /rb sum spell hasterating +L["Sum Spell Haste Rating"] = "統計法術加速等級" +L["Spell Haste Rating Summary"] = "統計法術加速等級" +--------------------------------------------------------------------------- +-- /rb sum tank +L["Stat - Tank"] = "統計坦克屬性" +L["Choose tank stats for summary"] = "自訂坦克屬性統計項目" +-- /rb sum tank armor +L["Sum Armor"] = "統計護甲值" +--L["Armor <- Armor from items and bonuses"] = "護甲值 ← 物品護甲、護甲加成、敏捷、智力" +-- /rb sum tank dodge +L["Sum Dodge Chance"] = "統計閃躲機率" +--L["Dodge Chance <- Dodge Rating, Agility"] = "閃躲機率 ← 閃躲等級、敏捷、防禦等級" +-- /rb sum tank parry +L["Sum Parry Chance"] = "統計招架機率" +--L["Parry Chance <- Parry Rating"] = "招架機率 ← 招架等級、防禦等級" +-- /rb sum tank block +L["Sum Block Chance"] = "統計格擋機率" +--L["Block Chance <- Block Rating"] = "格擋機率 ← 格擋等級、防禦等級" +-- /rb sum tank neglectdodge +L["Sum Dodge Neglect"] = "統計防止被閃躲" +--L["Dodge Neglect <- Expertise"] = "防止被閃躲 ← 熟練技能、武器技能等級" +-- /rb sum stat neglectparry +L["Sum Parry Neglect"] = "統計防止被招架" +--L["Parry Neglect <- Expertise"] = "防止被招架 ← 熟練技能、武器技能等級" +-- /rb sum tank resarcane +L["Sum Arcane Resistance"] = "統計秘法抗性" +L["Arcane Resistance Summary"] = "統計秘法抗性" +-- /rb sum tank resfire +L["Sum Fire Resistance"] = "統計火焰抗性" +L["Fire Resistance Summary"] = "統計火焰抗性" +-- /rb sum tank resnature +L["Sum Nature Resistance"] = "統計自然抗性" +L["Nature Resistance Summary"] = "統計自然抗性" +-- /rb sum tank resfrost +L["Sum Frost Resistance"] = "統計冰霜抗性" +L["Frost Resistance Summary"] = "統計冰霜抗性" +-- /rb sum tank resshadow +L["Sum Shadow Resistance"] = "統計暗影抗性" +L["Shadow Resistance Summary"] = "統計暗影抗性" +-- /rb sum tank dodgerating +L["Sum Dodge Rating"] = "統計閃躲等級" +L["Dodge Rating Summary"] = "統計閃躲等級" +-- /rb sum tank parryrating +L["Sum Parry Rating"] = "統計招架等級" +L["Parry Rating Summary"] = "統計招架等級" +-- /rb sum tank blockrating +L["Sum Block Rating"] = "統計格檔等級" +L["Block Rating Summary"] = "統計格檔等級" +-- /rb sum tank res +L["Sum Resilience"] = "統計韌性" +L["Resilience Summary"] = "統計韌性" +-- /rb sum tank tp +L["Sum TankPoints"] = "統計坦克點" +L["TankPoints <- Health, Total Reduction"] = "坦克點 ← 生命力、傷害減免總值" +-- /rb sum tank tr +L["Sum Total Reduction"] = "統計傷害減免總值" +--L["Total Reduction <- Armor, Dodge, Parry, Block, MobMiss, MobCrit, MobCrush, DamageTakenMods"] = "傷害減免總值 ← 護甲、閃躲、招架、格擋、格檔值、防禦、韌性、怪物未擊中、怪物致命、怪物輾壓、DamageTakenMods (?)" +-- /rb sum tank avoid +L["Sum Avoidance"] = "統計傷害迴避" +L["Avoidance <- Dodge, Parry, MobMiss, Block(Optional)"] = "傷害迴避 ← 閃躲、招架、怪物未擊中、格擋(選項)" +--------------------------------------------------------------------------- +-- /rb sum gemset +L["Gem Set"] = "寶石設定" +L["Select a gem set to configure"] = "選擇一組寶石設定" +L["Default Gem Set 1"] = "寶石設定 1" +L["Default Gem Set 2"] = "寶石設定 2" +L["Default Gem Set 3"] = "寶石設定 3" +-- /rb sum gem +L["Auto fill empty gem slots"] = "空寶石插槽的預設寶石" +-- /rb sum gem red +L["Red Socket"] = EMPTY_SOCKET_RED +L["ItemID or Link of the gem you would like to auto fill"] = "預設寶石的物品編號或連結" +L[""] = "<物品編號|連結>" +L["|cffffff7f%s|r is now set to |cffffff7f[%s]|r"] = "|cffffff7f%s|r 已設定為 |cffffff7f[%s]|r" +L["Invalid input: %s. ItemID or ItemLink required."] = "輸入錯誤:%s,請輸入物品編號或物品連結。" +L["Queried server for Gem: %s. Try again in 5 secs."] = "嘗試查詢編號:%s,請5秒後再試一次。" +-- /rb sum gem yellow +L["Yellow Socket"] = EMPTY_SOCKET_YELLOW +-- /rb sum gem blue +L["Blue Socket"] = EMPTY_SOCKET_BLUE +-- /rb sum gem meta +L["Meta Socket"] = EMPTY_SOCKET_META +-- /rb sum gem2 +L["Second set of default gems which can be toggled with a modifier key"] = "你可以使用 SHIFT, ALT 或 CTRL 來切換第二組預設寶石設定" +L["Can't use the same modifier as Gem Set 3"] = "無法使用與第 3 組預設寶石設定相同的切換鍵" +-- /rb sum gem2 key +L["Toggle Key"] = "切換鍵" +L["Use this key to toggle alternate gems"] = "選擇一個按鍵來切換這組寶石設定" +-- /rb sum gem3 +L["Third set of default gems which can be toggled with a modifier key"] = "你可以使用 SHIFT, ALT 或 CTRL 來切換第三組預設寶石設定" +L["Can't use the same modifier as Gem Set 2"] = "無法使用與第 2 組預設寶石設定相同的切換鍵" + +----------------------- +-- Item Level and ID -- +----------------------- +L["ItemLevel: "] = "物品等級: " +L["ItemID: "] = "物品編號: " +----------------------- +-- Matching Patterns -- +----------------------- +-- Items to check -- +-------------------- +-- [Potent Ornate Topaz] +-- +6 Spell Damage, +5 Spell Crit Rating +-------------------- +-- ZG enchant +-- +10 Defense Rating/+10 Stamina/+15 Block Value +-------------------- +-- [Glinting Flam Spessarite] +-- +3 Hit Rating and +3 Agility +-------------------- +-- ItemID: 22589 +-- [Atiesh, Greatstaff of the Guardian] warlock version +-- Equip: Increases the spell critical strike rating of all party members within 30 yards by 28. +-------------------- +-- [Brilliant Wizard Oil] +-- Use: While applied to target weapon it increases spell damage by up to 36 and increases spell critical strike rating by 14 . Lasts for 30 minutes. +---------------------------------------------------------------------------------------------------- +-- I redesigned the tooltip scanner using a more locale friendly, 2 pass matching matching algorithm. +-- +-- The first pass searches for the rating number, the patterns are read from L["numberPatterns"] here, +-- " by (%d+)" will match strings like: "Increases defense rating by 16." +-- "%+(%d+)" will match strings like: "+10 Defense Rating" +-- You can add additional patterns if needed, its not limited to 2 patterns. +-- The separators are a table of strings used to break up a line into multiple lines what will be parsed seperately. +-- For example "+3 Hit Rating, +5 Spell Crit Rating" will be split into "+3 Hit Rating" and " +5 Spell Crit Rating" +-- +-- The second pass searches for the rating name, the names are read from L["statList"] here, +-- It will look through the table in order, so you can put common strings at the begining to speed up the search, +-- and longer strings should be listed first, like "spell critical strike" should be listed before "critical strike", +-- this way "spell critical strike" does get matched by "critical strike". +-- Strings need to be in lower case letters, because string.lower is called on lookup +-- +-- IMPORTANT: there may not exist a one-to-one correspondence, meaning you can't just translate this file, +-- but will need to go in game and find out what needs to be put in here. +-- For example, in english I found 3 different strings that maps to CR_CRIT_MELEE: "critical strike", "critical hit" and "crit". +-- You will need to find out every string that represents CR_CRIT_MELEE, and so on. +-- In other languages there may be 5 different strings that should all map to CR_CRIT_MELEE. +-- so please check in game that you have all strings, and not translate directly off this table. +-- +-- Tip1: When doing localizations, I recommend you set debugging to true in RatingBuster.lua +-- Find RatingBuster:SetDebugging(false) and change it to RatingBuster:SetDebugging(true) +-- or you can type /rb debug to enable it in game +-- +-- Tip2: The strings are passed into string.find, so you should escape the magic characters ^$()%.[]*+-? with a % +L["numberPatterns"] = { + {pattern = "提高.-(%d+)", addInfo = "AfterNumber",}, + {pattern = "提升.-(%d+)", addInfo = "AfterNumber",}, -- [奎克米瑞之眼] ID:27683 + {pattern = "(%d+)。", addInfo = "AfterNumber",}, + {pattern = "([%+%-]%d+)", addInfo = "AfterStat",}, + {pattern = "佩戴者.-(%d+)", addInfo = "AfterNumber",}, -- for "grant you xx stat" type pattern, ex: Quel'Serrar, Assassination Armor set + {pattern = "(%d+)([^%d%%|]+)", addInfo = "AfterStat",}, -- [發光的暗影卓奈石] +6法術傷害及5耐力 +} +L["separators"] = { + "/", "和", ",", "。", " 持續 ", "&", "及", "並", ",", +} +--[[ Rating ID +CR_WEAPON_SKILL = 1; +CR_DEFENSE_SKILL = 2; +CR_DODGE = 3; +CR_PARRY = 4; +CR_BLOCK = 5; +CR_HIT_MELEE = 6; +CR_HIT_RANGED = 7; +CR_HIT_SPELL = 8; +CR_CRIT_MELEE = 9; +CR_CRIT_RANGED = 10; +CR_CRIT_SPELL = 11; +CR_HIT_TAKEN_MELEE = 12; +CR_HIT_TAKEN_RANGED = 13; +CR_HIT_TAKEN_SPELL = 14; +CR_CRIT_TAKEN_MELEE = 15; +CR_CRIT_TAKEN_RANGED = 16; +CR_CRIT_TAKEN_SPELL = 17; +CR_HASTE_MELEE = 18; +CR_HASTE_RANGED = 19; +CR_HASTE_SPELL = 20; +CR_WEAPON_SKILL_MAINHAND = 21; +CR_WEAPON_SKILL_OFFHAND = 22; +CR_WEAPON_SKILL_RANGED = 23; +CR_EXPERTISE = 24; +-- +SPELL_STAT1_NAME = "Strength" +SPELL_STAT2_NAME = "Agility" +SPELL_STAT3_NAME = "Stamina" +SPELL_STAT4_NAME = "Intellect" +SPELL_STAT5_NAME = "Spirit" +--]] +L["statList"] = { + {pattern = string.lower(SPELL_STAT1_NAME), id = SPELL_STAT1_NAME}, -- Strength + {pattern = string.lower(SPELL_STAT2_NAME), id = SPELL_STAT2_NAME}, -- Agility + {pattern = string.lower(SPELL_STAT3_NAME), id = SPELL_STAT3_NAME}, -- Stamina + {pattern = string.lower(SPELL_STAT4_NAME), id = SPELL_STAT4_NAME}, -- Intellect + {pattern = string.lower(SPELL_STAT5_NAME), id = SPELL_STAT5_NAME}, -- Spirit + {pattern = "防禦等級", id = CR_DEFENSE_SKILL}, + {pattern = "閃躲等級", id = CR_DODGE}, + {pattern = "格擋等級", id = CR_BLOCK}, -- block enchant: "+10 Shield Block Rating" + {pattern = "招架等級", id = CR_PARRY}, + + {pattern = "法術致命一擊等級", id = CR_CRIT_SPELL}, + {pattern = "遠程攻擊致命一擊等級", id = CR_CRIT_RANGED}, + {pattern = "致命一擊等級", id = CR_CRIT_MELEE}, + + {pattern = "法術命中等級", id = CR_HIT_SPELL}, + {pattern = "遠程命中等級", id = CR_HIT_RANGED}, + {pattern = "命中等級", id = CR_HIT_MELEE}, + + {pattern = "韌性", id = CR_CRIT_TAKEN_MELEE}, -- resilience is implicitly a rating + + {pattern = "法術加速等級", id = CR_HASTE_SPELL}, + {pattern = "遠程攻擊加速等級", id = CR_HASTE_RANGED}, + {pattern = "加速等級", id = CR_HASTE_MELEE}, + {pattern = "攻擊速度等級", id = CR_HASTE_MELEE}, -- [Drums of Battle] + + {pattern = "技能等級", id = CR_WEAPON_SKILL}, + {pattern = "熟練等級", id = CR_EXPERTISE}, -- 2.3 + + {pattern = "命中迴避率", id = CR_HIT_TAKEN_MELEE}, + {pattern = "護甲穿透等級", id = CR_ARMOR_PENETRATION}, + {pattern = string.lower(ARMOR), id = ARMOR}, + --[[ + {pattern = "匕首技能等級", id = CR_WEAPON_SKILL}, + {pattern = "劍技能等級", id = CR_WEAPON_SKILL}, + {pattern = "雙手劍技能等級", id = CR_WEAPON_SKILL}, + {pattern = "斧技能等級", id = CR_WEAPON_SKILL}, + {pattern = "弓技能等級", id = CR_WEAPON_SKILL}, + {pattern = "弩技能等級", id = CR_WEAPON_SKILL}, + {pattern = "槍械技能等級", id = CR_WEAPON_SKILL}, + {pattern = "野性戰鬥技能等級", id = CR_WEAPON_SKILL}, + {pattern = "錘技能等級", id = CR_WEAPON_SKILL}, + {pattern = "長柄武器技能等級", id = CR_WEAPON_SKILL}, + {pattern = "法杖技能等級", id = CR_WEAPON_SKILL}, + {pattern = "雙手斧技能等級", id = CR_WEAPON_SKILL}, + {pattern = "雙手錘技能等級", id = CR_WEAPON_SKILL}, + {pattern = "徒手戰鬥技能等級", id = CR_WEAPON_SKILL}, + --]] +} +------------------------- +-- Added info patterns -- +------------------------- +-- $value will be replaced with the number +-- EX: "$value% Crit" -> "+1.34% Crit" +-- EX: "Crit $value%" -> "Crit +1.34%" +L["$value% Crit"] = "$value% 致命" +L["$value% Spell Crit"] = "$value% 法術致命" +L["$value% Dodge"] = "$value% 閃躲" +L["$value HP"] = "$value 生命" +L["$value MP"] = "$value 法力" +L["$value AP"] = "$value 強度" +L["$value RAP"] = "$value 遠程強度" +L["$value Dmg"] = "$value 法傷" +L["$value Heal"] = "$value 治療" +L["$value Armor"] = "$value 護甲" +L["$value Block"] = "$value 格擋值" +L["$value MP5"] = "$value 施法回魔" +L["$value MP5(NC)"] = "$value 一般回魔" +L["$value HP5"] = "$value 回血" +L["$value to be Dodged/Parried"] = "$value 被閃躲/被招架" +L["$value to be Crit"] = "$value 被致命" +L["$value Crit Dmg Taken"] = "$value 致命傷害減免" +L["$value DOT Dmg Taken"] = "$value 持續傷害減免" +L["$value% Parry"] = "$value% 招架" +-- for hit rating showing both physical and spell conversions +-- (+1.21%, S+0.98%) +-- (+1.21%, +0.98% S) +L["$value Spell"] = "$value 法術" + +------------------ +-- Stat Summary -- +------------------ +L["Stat Summary"] = "屬性統計" \ No newline at end of file diff --git a/RatingBuster/RatingBuster.lua b/RatingBuster/RatingBuster.lua new file mode 100644 index 0000000..6f071f1 --- /dev/null +++ b/RatingBuster/RatingBuster.lua @@ -0,0 +1,4561 @@ +--[[ +Name: RatingBuster +Description: Converts combat ratings in tooltips into normal percentages. +Revision: $Revision: 294 $ +Author: Whitetooth +Email: hotdogee [at] gmail [dot] com +LastUpdate: $Date: 2010-10-22 16:07:47 +0000 (Fri, 22 Oct 2010) $ +]] + +--------------- +-- Libraries -- +--------------- +local AceConfig = LibStub("AceConfig-3.0") +local AceConfigDialog = LibStub("AceConfigDialog-3.0") +local AceConfigRegistry = LibStub("AceConfigRegistry-3.0") +local AceDB = LibStub("AceDB-3.0") +local TipHooker = LibStub("LibTipHooker-1.1") +local StatLogic = LibStub("LibStatLogic-1.2") +local L = LibStub("AceLocale-3.0"):GetLocale("RatingBuster") +local BI = LibStub("LibBabble-Inventory-3.0"):GetLookupTable() + + +-------------------- +-- AceAddon Setup -- +-------------------- +-- AceAddon Initialization +RatingBuster = LibStub("AceAddon-3.0"):NewAddon("RatingBuster", "AceConsole-3.0", "AceEvent-3.0") +RatingBuster.version = "1.5.0 (r"..gsub("$Revision: 294 $", "$Revision: (%d+) %$", "%1")..")" +RatingBuster.date = gsub("$Date: 2010-10-22 16:07:47 +0000 (Fri, 22 Oct 2010) $", "^.-(%d%d%d%d%-%d%d%-%d%d).-$", "%1") + + +----------- +-- Cache -- +----------- +local cache = {} +setmetatable(cache, {__mode = "kv"}) -- weak table to enable garbage collection +local function clearCache() + for k in pairs(cache) do + cache[k] = nil + end +end +--debug +--RatingBuster.cache = cache + + +--------------------- +-- Local Variables -- +--------------------- +local _ +local _, class = UnitClass("player") +local playerLevel = UnitLevel("player") or 80 +local calcLevel +local profileDB -- Initialized in :OnInitialize() +-- Cached GetItemInfo +local GetItemInfo = StatLogic.GetItemInfo +-- Localize globals +local _G = getfenv(0) +local strfind = strfind +local strsub = strsub +local gsub = gsub +local pairs = pairs +local ipairs = ipairs +local type = type +local select = select +local tinsert = tinsert +local tremove = tremove +local tsort = table.sort +local strsplit = strsplit +local strjoin = strjoin +local unpack = unpack +local tonumber = tonumber +local UnitStat = UnitStat +local wowBuildNo = select(2, GetBuildInfo()) +local GetParryChance = GetParryChance +local GetBlockChance = GetBlockChance +local SPELL_STAT1_NAME = SPELL_STAT1_NAME +local SPELL_STAT2_NAME = SPELL_STAT2_NAME +local SPELL_STAT3_NAME = SPELL_STAT3_NAME +local SPELL_STAT4_NAME = SPELL_STAT4_NAME +local SPELL_STAT5_NAME = SPELL_STAT5_NAME +local ARMOR = ARMOR + +----------------- +-- DB Defaults -- +----------------- +local profileDefault = { + hideBlizzardComparisons = true, + showItemLevel = true, + showItemID = false, + useRequiredLevel = true, + customLevel = 0, + textColor = {r = 1.0, g = 0.996, b = 0.545, hex = "|cfffffe8b"}, + enableTextColor = true, + enableStatMods = true, + enableAvoidanceDiminishingReturns = true, + showRatings = 0, + ratingSpell = false, + ratingPhysical = false, + detailedConversionText = false, + expBreakDown = false, + showStats = 0, + showSum = 0, + sumIgnoreUnused = true, + sumMinQuality = 2, -- uncommon + sumIgnoreCloth = true, + sumIgnoreLeather = true, + sumIgnoreMail = true, + sumIgnorePlate = true, + sumIgnoreEquipped = false, + sumIgnoreEnchant = true, + sumIgnoreGems = false, + sumIgnorePris = true, + sumBlankLine = true, + sumBlankLineAfter = false, + sumShowIcon = true, + sumShowTitle = true, + sumDiffStyle = "main", + sumSortAlpha = false, + sumAvoidWithBlock = false, + showZeroValueStat = false, + calcDiff = true, + calcSum = true, +--[[ +Str -> AP, Block, Healing +Agi -> Crit, Dodge, AP, RAP, Armor +Sta -> Health, SpellDmg +Int -> Mana, SpellCrit, SpellDmg, Healing, MP5, RAP, Armor +Spi -> MP5, MP5NC, HP5, SpellDmg, Healing +--]] + -- Base stat conversions + showAPFromStr = false, + showBlockValueFromStr = false, + + showCritFromAgi = true, + showDodgeFromAgi = true, + showAPFromAgi = false, + showRAPFromAgi = false, + showArmorFromAgi = false, + showHealingFromAgi = false, -- Druid - Nurturing Instinct + + showHealthFromSta = false, + showSpellDmgFromSta = false, -- Warlock + + showManaFromInt = false, + showSpellCritFromInt = true, + showSpellDmgFromInt = false, -- Druid, Mage, Paladin, Shaman, Warlock + showHealingFromInt = false, -- Druid, Paladin, Shaman + showMP5FromInt = false, + showMP5NCFromInt = false, + showRAPFromInt = false, -- Hunter + showArmorFromInt = false, -- Mage + + showMP5FromSpi = false, -- Druid, Mage, Priest + showMP5NCFromSpi = false, + showHP5FromSpi = false, + showSpellDmgFromSpi = false, -- Priest + showHealingFromSpi = false, -- Priest + showSpellCritFromSpi = false, -- Mage + + showAPFromArmor = false, -- Warrior, DK + ------------------ + -- Stat Summary -- + ------------------ + -- Basic + sumHP = false, + sumMP = false, + sumMP5 = false, + sumMP5NC = false, + sumHP5 = false, + sumHP5OC = false, + sumStr = false, + sumAgi = false, + sumSta = false, + sumInt = false, + sumSpi = false, + sumMastery = false, + sumMasteryRating = false, + -- Physical + sumAP = false, + sumRAP = false, + sumFAP = false, + sumHit = false, + sumHitRating = false, + sumRangedHit = false, + sumRangedHitRating = false, + sumCrit = false, + sumCritRating = false, + sumRangedCrit = false, + sumRangedCritRating = false, + sumHaste = false, + sumHasteRating = false, + sumRangedHaste = false, + sumRangedHasteRating = false, + sumExpertise = false, + sumExpertiseRating = false, + sumDodgeNeglect = false, + sumParryNeglect = false, + sumWeaponMaxDamage = false, + sumWeaponDPS = false, + -- Spell + sumSpellDmg = false, + sumArcaneDmg = false, + sumFrostDmg = false, + sumNatureDmg = false, + sumFireDmg = false, + sumShadowDmg = false, + sumHolyDmg = false, + sumHealing = false, + sumSpellHit = false, + sumSpellHitRating = false, + sumSpellCrit = false, + sumSpellCritRating = false, + sumSpellHaste = false, + sumSpellHasteRating = false, + sumPenetration = false, + -- Tank + sumArmor = false, + sumDodge = false, + sumDodgeRating = false, + sumParry = false, + sumParryRating = false, + sumBlock = false, + sumBlockRating = false, + sumHitAvoid = false, + sumCritAvoid = false, + sumArcaneResist = false, + sumFrostResist = false, + sumNatureResist = false, + sumFireResist = false, + sumShadowResist = false, + sumResilience = false, + sumTankPoints = false, + sumTotalReduction = false, + sumAvoidance = false, + -- Gems + sumGemRed = { + itemID = nil, + gemID = nil, + gemText = nil, + gemName = nil, + gemLink = nil, + }, + sumGemYellow = { + itemID = nil, + gemID = nil, + gemText = nil, + gemName = nil, + gemLink = nil, + }, + sumGemBlue = { + itemID = nil, + gemID = nil, + gemText = nil, + gemName = nil, + gemLink = nil, + }, + sumGemMeta = { + itemID = nil, + gemID = nil, + gemText = nil, + gemName = nil, + gemLink = nil, + }, + -- Gems Set 2 + sumGem2Toggle = 4, + sumGemRed2 = { + itemID = nil, + gemID = nil, + gemText = nil, + gemName = nil, + gemLink = nil, + }, + sumGemYellow2 = { + itemID = nil, + gemID = nil, + gemText = nil, + gemName = nil, + gemLink = nil, + }, + sumGemBlue2 = { + itemID = nil, + gemID = nil, + gemText = nil, + gemName = nil, + gemLink = nil, + }, + sumGemMeta2 = { + itemID = nil, + gemID = nil, + gemText = nil, + gemName = nil, + gemLink = nil, + }, + -- Gems Set 3 + sumGem3Toggle = 4, + sumGemRed3 = { + itemID = nil, + gemID = nil, + gemText = nil, + gemName = nil, + gemLink = nil, + }, + sumGemYellow3 = { + itemID = nil, + gemID = nil, + gemText = nil, + gemName = nil, + gemLink = nil, + }, + sumGemBlue3 = { + itemID = nil, + gemID = nil, + gemText = nil, + gemName = nil, + gemLink = nil, + }, + sumGemMeta3 = { + itemID = nil, + gemID = nil, + gemText = nil, + gemName = nil, + gemLink = nil, + }, +} + +-- Class specific defaults +if class == "DRUID" then + profileDefault.sumMastery = true + profileDefault.ratingSpell = true + profileDefault.ratingPhysical = true + profileDefault.sumHP = true + profileDefault.sumMP = true + profileDefault.sumFAP = true + profileDefault.sumHit = true + profileDefault.sumCrit = true + profileDefault.sumHaste = true + profileDefault.sumExpertise = true + profileDefault.sumDodge = true + profileDefault.sumArmor = true + profileDefault.sumResilience = true + profileDefault.sumSpellDmg = true + profileDefault.sumSpellHit = true + profileDefault.sumSpellCrit = true + profileDefault.sumSpellHaste = true + profileDefault.sumHealing = true + profileDefault.sumMP5 = true + profileDefault.showHealingFromAgi = true + profileDefault.showSpellDmgFromInt = true + profileDefault.showHealingFromInt = true + profileDefault.showMP5FromInt = true -- Dreamstate (Rank 3) - 1,17 + profileDefault.showMP5FromSpi = true + profileDefault.showSpellDmgFromSpi = true + profileDefault.showHealingFromSpi = true + profileDefault.sumIgnoreCloth = false + profileDefault.sumIgnoreLeather = false +elseif class == "HUNTER" then + profileDefault.sumMastery = true + profileDefault.ratingPhysical = true + profileDefault.sumHP = true + profileDefault.sumMP = true + profileDefault.sumResilience = true + profileDefault.sumRAP = true + profileDefault.sumRangedHit = true + profileDefault.sumRangedCrit = true + profileDefault.sumRangedHaste = true + profileDefault.sumMP5 = true + profileDefault.showMP5FromInt = true -- Aspect of the Viper + profileDefault.showDodgeFromAgi = false + profileDefault.showSpellCritFromInt = false + profileDefault.showRAPFromInt = true + profileDefault.showAPFromSta = true + profileDefault.sumIgnoreLeather = false + profileDefault.sumIgnoreMail = false +elseif class == "MAGE" then + profileDefault.sumMastery = true + profileDefault.ratingSpell = true + profileDefault.sumHP = true + profileDefault.sumMP = true + profileDefault.sumResilience = true + profileDefault.sumSpellDmg = true + profileDefault.sumSpellHit = true + profileDefault.sumSpellCrit = true + profileDefault.sumSpellHaste = true + profileDefault.sumMP5 = true + profileDefault.showCritFromAgi = false + profileDefault.showDodgeFromAgi = false + profileDefault.showSpellDmgFromInt = true + profileDefault.showArmorFromInt = true + profileDefault.showMP5FromInt = true + profileDefault.showMP5FromSpi = true + profileDefault.showSpellCritFromSpi = true -- Molten Armor + profileDefault.sumIgnoreCloth = false +elseif class == "PALADIN" then + profileDefault.sumMastery = true + profileDefault.ratingSpell = true + profileDefault.ratingPhysical = true + profileDefault.sumHP = true + profileDefault.sumMP = true + profileDefault.sumResilience = true + profileDefault.sumAP = true + profileDefault.sumHit = true + profileDefault.sumCrit = true + profileDefault.sumHaste = true + profileDefault.sumExpertise = true + profileDefault.sumHolyDmg = true + profileDefault.sumSpellHit = true + profileDefault.sumSpellCrit = true + profileDefault.sumSpellHaste = true + profileDefault.sumHealing = true + profileDefault.sumMP5 = true + profileDefault.sumDodge = true + profileDefault.sumParry = true + profileDefault.sumBlock = true + profileDefault.showSpellDmgFromInt = true + profileDefault.showHealingFromInt = true + profileDefault.showSpellDmgFromStr = true + profileDefault.showHealingFromStr = true + profileDefault.sumIgnoreCloth = false + profileDefault.sumIgnoreLeather = false + profileDefault.sumIgnoreMail = false + profileDefault.sumIgnorePlate = false +elseif class == "PRIEST" then + profileDefault.sumMastery = true + profileDefault.ratingSpell = true + profileDefault.sumHP = true + profileDefault.sumMP = true + profileDefault.sumResilience = true + profileDefault.sumSpellDmg = true + profileDefault.sumSpellHit = true + profileDefault.sumSpellCrit = true + profileDefault.sumSpellHaste = true + profileDefault.sumHealing = true + profileDefault.sumMP5 = true + profileDefault.showCritFromAgi = false + profileDefault.showDodgeFromAgi = false + profileDefault.showMP5FromInt = true + profileDefault.showMP5FromSpi = true + profileDefault.showSpellDmgFromSpi = true + profileDefault.showHealingFromSpi = true + profileDefault.sumIgnoreCloth = false +elseif class == "ROGUE" then + profileDefault.sumMastery = true + profileDefault.ratingPhysical = true + profileDefault.sumHP = true + profileDefault.sumResilience = true + profileDefault.sumAP = true + profileDefault.sumHit = true + profileDefault.sumCrit = true + profileDefault.sumHaste = true + profileDefault.sumExpertise = true + profileDefault.showSpellCritFromInt = false + profileDefault.sumIgnoreLeather = false +elseif class == "SHAMAN" then + profileDefault.sumMastery = true + profileDefault.ratingSpell = true + profileDefault.ratingPhysical = true + profileDefault.sumHP = true + profileDefault.sumMP = true + profileDefault.sumResilience = true + profileDefault.sumSpellDmg = true + profileDefault.sumSpellHit = true + profileDefault.sumSpellCrit = true + profileDefault.sumSpellHaste = true + profileDefault.sumHealing = true + profileDefault.sumMP5 = true + profileDefault.showSpellDmgFromStr = true + profileDefault.showHealingFromStr = true + profileDefault.showSpellDmgFromInt = true + profileDefault.showHealingFromInt = true + profileDefault.showMP5FromInt = true + profileDefault.showAPFromInt = true + profileDefault.sumIgnoreCloth = false + profileDefault.sumIgnoreLeather = false + profileDefault.sumIgnoreMail = false +elseif class == "WARLOCK" then + profileDefault.sumMastery = true + profileDefault.ratingSpell = true + profileDefault.sumHP = true + profileDefault.sumMP = true + profileDefault.sumResilience = true + profileDefault.sumSpellDmg = true + profileDefault.sumSpellHit = true + profileDefault.sumSpellCrit = true + profileDefault.sumSpellHaste = true + profileDefault.showCritFromAgi = false + profileDefault.showDodgeFromAgi = false + profileDefault.showSpellDmgFromSta = true + profileDefault.showSpellDmgFromInt = true + profileDefault.showMP5FromSpi = true + profileDefault.showSpellDmgFromSpi = true + profileDefault.sumIgnoreCloth = false +elseif class == "WARRIOR" then + profileDefault.sumMastery = true + profileDefault.ratingPhysical = true + profileDefault.sumHP = true + profileDefault.sumResilience = true + profileDefault.sumAP = true + profileDefault.sumHit = true + profileDefault.sumCrit = true + profileDefault.sumHaste = true + profileDefault.sumExpertise = true + profileDefault.sumDodge = true + profileDefault.sumParry = true + profileDefault.sumBlock = true + profileDefault.showSpellCritFromInt = false + profileDefault.showAPFromArmor = true + if playerLevel < 40 then + profileDefault.sumIgnoreMail = false + end + profileDefault.sumIgnorePlate = false +elseif class == "DEATHKNIGHT" then + profileDefault.sumMastery = true + profileDefault.ratingPhysical = true + profileDefault.sumHP = true + profileDefault.sumResilience = true + profileDefault.sumAP = true + profileDefault.sumHit = true + profileDefault.sumCrit = true + profileDefault.sumHaste = true + profileDefault.sumExpertise = true + profileDefault.sumDodge = true + profileDefault.sumParry = true + profileDefault.showSpellCritFromInt = false + profileDefault.showParryFromStr = true + profileDefault.showAPFromArmor = true + profileDefault.sumIgnorePlate = false +end + +local defaults = {} +defaults.profile = profileDefault + +--------------------------- +-- Slash Command Options -- +--------------------------- + +local function getProfileOption(info) + return profileDB[info.arg] +end + +local function setProfileOptionAndClearCache(info, value) + profileDB[info.arg] = value + if info.uiType == "cmd" then + RatingBuster:Print(L["|cffffff7f%s|r is now set to |cffffff7f[%s]|r"]:format(info.option.name, tostring(value))) + end + clearCache() +end + +local function getGem(info) + return profileDB[info.arg].gemLink +end + +local function setGem(info, value) + local key = info.arg + if value == "" then + profileDB[key].itemID = nil + profileDB[key].gemID = nil + profileDB[key].gemName = nil + profileDB[key].gemLink = nil + profileDB[key].gemText = nil + clearCache() + return + end + local gemID, gemText = StatLogic:GetGemID(value) + if gemID and gemText then + local name, link = GetItemInfo(value) + local itemID = link:match("item:(%d+)") + profileDB[key].itemID = itemID + profileDB[key].gemID = gemID + profileDB[key].gemName = name + profileDB[key].gemLink = link + -- Trim spaces + gemText = strtrim(gemText) + -- Strip color codes + if strsub(gemText, -2) == "|r" then + gemText = strsub(gemText, 1, -3) + end + if strfind(strsub(gemText, 1, 10), "|c%x%x%x%x%x%x%x%x") then + gemText = strsub(gemText, 11) + end + profileDB[key].gemText = gemText + clearCache() + -- Is option set by AceConfigCmd or AceConfigDialog? + --if not debugstack():find("AceConfigCmd") then + RatingBuster:Print(L["|cffffff7f%s|r is now set to |cffffff7f[%s]|r"]:format(info.option.name, link)) + --end + elseif gemID == false then -- invalid input + RatingBuster:Print(L["Invalid input: %s. ItemID or ItemLink required."]:format(value)) + else -- query sent + RatingBuster:Print(L["Queried server for Gem: %s. Try again in 5 secs."]:format(value)) + end +end + +local selectedGemSet = 1 + +local options = { + type = 'group', + get = getProfileOption, + set = setProfileOptionAndClearCache, + args = { + general = { + type = 'group', + name = L["General Settings"], + cmdInline = true, + order = -1, + args = { + win = { + type = "execute", + name = L["Options Window"], + desc = L["Shows the Options Window"], + func = function() + RatingBuster:ShowConfig() + end, + guiHidden = true, + }, + standby = { + type = 'toggle', + order = 1, + width = "double", + name = L["Enabled"], + desc = L["Suspend/resume this addon"], + get = function() return RatingBuster:IsEnabled() end, + set = function() + if RatingBuster:IsEnabled() then + RatingBuster:Disable() + else + RatingBuster:Enable() + end + end, + }, + hidebzcomp = { + type = 'toggle', + order = 2, + width = "double", + name = L["Hide Blizzard Item Comparisons"], + desc = L["Disable Blizzard stat change summary when using the built-in comparison tooltip"], + arg = "hideBlizzardComparisons", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + statmod = { + type = 'toggle', + order = 3, + width = "double", + name = L["Enable Stat Mods"], + desc = L["Enable support for Stat Mods"], + arg = "enableStatMods", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + avoidancedr = { + type = 'toggle', + order = 4, + width = "double", + name = L["Enable Avoidance Diminishing Returns"], + desc = L["Dodge, Parry, Hit Avoidance values will be calculated using the avoidance deminishing return formula with your current stats"], + arg = "enableAvoidanceDiminishingReturns", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + itemid = { + type = 'toggle', + order = 5, + width = "double", + name = L["Show ItemID"], + desc = L["Show the ItemID in tooltips"], + arg = "showItemID", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + itemlevel = { + type = 'toggle', + order = 6, + width = "double", + name = L["Show ItemLevel"], + desc = L["Show the ItemLevel in tooltips"], + arg = "showItemLevel", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + usereqlv = { + type = 'toggle', + order = 7, + width = "double", + name = L["Use Required Level"], + desc = L["Calculate using the required level if you are below the required level"], + arg = "useRequiredLevel", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + level = { + type = 'range', + order = 8, + width = "double", + name = L["Set Level"], + desc = L["Set the level used in calculations (0 = your level)"], + arg = "customLevel", + get = getProfileOption, + set = setProfileOptionAndClearCache, + min = 0, + max = 83, -- set to level cap + 3 + step = 1, + }, + }, + }, + rating = { + type = 'group', + name = L["Rating"], + desc = L["Options for Rating display"], + args = { + show = { + type = 'select', + order = 1, + name = L["Show Rating Conversions"], + desc = L["Show Rating conversions in tooltips"], + values = { + [0] = L["Always"], + [1] = L["ALT Key"], + [2] = L["CTRL Key"], + [3] = L["SHIFT Key"], + [4] = L["Never"], + }, + arg = "showRatings", + }, + spell = { + type = 'toggle', + order = 2, + width = "double", + name = L["Show Spell Hit/Haste"], + desc = L["Show Spell Hit/Haste from Hit/Haste Rating"], + arg = "ratingSpell", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + physical = { + type = 'toggle', + order = 3, + width = "double", + name = L["Show Physical Hit/Haste"], + desc = L["Show Physical Hit/Haste from Hit/Haste Rating"], + arg = "ratingPhysical", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + detail = { + type = 'toggle', + order = 4, + width = "double", + name = L["Show Detailed Conversions Text"], + desc = L["Show detailed text for Resilience and Expertise conversions"], + arg = "detailedConversionText", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + exp = { + type = 'toggle', + order = 7, + width = "double", + name = L["Expertise Breakdown"], + desc = L["Convert Expertise into Dodge Neglect and Parry Neglect"], + arg = "expBreakDown", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + color = { + type = 'group', + order = 8, + name = L["Change Text Color"], + desc = L["Changes the color of added text"], + guiInline = true, + args = { + enable = { + type = 'toggle', + order = 1, + name = L["Enable Color"], + desc = L["Enable colored text"], + arg = "enableTextColor", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + pick_dialog = { + type = 'color', + order = 2, + cmdHidden = true, + dropdownHidden = true, + name = L["Pick Color"], + desc = L["Pick a color"], + get = function() + return profileDB.textColor.r, profileDB.textColor.g, profileDB.textColor.b, 1.0 + end, + set = function(info, r, g, b, a) + profileDB.textColor.r, profileDB.textColor.g, profileDB.textColor.b = r, g, b + profileDB.textColor.hex = "|cff"..string.format("%02x%02x%02x", profileDB.textColor.r * 255, profileDB.textColor.g * 255, profileDB.textColor.b * 255) + clearCache() + end, + }, + pick = { + type = 'execute', + order = 2, + dialogHidden = true, + name = L["Pick Color"], + desc = L["Pick a color"], + func = function() + CloseMenus() + ColorPickerFrame.func = function() + profileDB.textColor.r, profileDB.textColor.g, profileDB.textColor.b = ColorPickerFrame:GetColorRGB(); + profileDB.textColor.hex = "|cff"..string.format("%02x%02x%02x", profileDB.textColor.r * 255, profileDB.textColor.g * 255, profileDB.textColor.b * 255) + --clear cache + clearCache() + end + ColorPickerFrame:SetColorRGB(profileDB.textColor.r, profileDB.textColor.g, profileDB.textColor.b); + ColorPickerFrame.previousValues = {r = profileDB.textColor.r, g = profileDB.textColor.g, b = profileDB.textColor.b}; + ColorPickerFrame:Show() + end, + }, + }, + }, + }, + }, + stat = { + type = 'group', + name = L["Stat Breakdown"], + desc = L["Changes the display of base stats"], + args = { + show = { + type = 'select', + order = 1, + name = L["Show Base Stat Conversions"], + desc = L["Show base stat conversions in tooltips"], + values = { + [0] = L["Always"], + [1] = L["ALT Key"], + [2] = L["CTRL Key"], + [3] = L["SHIFT Key"], + [4] = L["Never"], + }, + arg = "showStats", + }, + str = { + type = 'group', + order = 2, + name = L["Strength"], + desc = L["Changes the display of Strength"], + args = { + ap = { + type = 'toggle', + width = "full", + name = L["Show Attack Power"], + desc = L["Show Attack Power from Strength"], + arg = "showAPFromStr", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + block = { + type = 'toggle', + width = "full", + name = L["Show Block Value"], + desc = L["Show Block Value from Strength"], + arg = "showBlockValueFromStr", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + }, + }, + agi = { + type = 'group', + order = 3, + name = L["Agility"], + desc = L["Changes the display of Agility"], + args = { + crit = { + type = 'toggle', + width = "full", + name = L["Show Crit"], + desc = L["Show Crit chance from Agility"], + arg = "showCritFromAgi", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + dodge = { + type = 'toggle', + width = "full", + name = L["Show Dodge"], + desc = L["Show Dodge chance from Agility"], + arg = "showDodgeFromAgi", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + ap = { + type = 'toggle', + width = "full", + name = L["Show Attack Power"], + desc = L["Show Attack Power from Agility"], + arg = "showAPFromAgi", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + rap = { + type = 'toggle', + width = "full", + name = L["Show Ranged Attack Power"], + desc = L["Show Ranged Attack Power from Agility"], + arg = "showRAPFromAgi", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + armor = { + type = 'toggle', + width = "full", + name = L["Show Armor"], + desc = L["Show Armor from Agility"], + arg = "showArmorFromAgi", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + }, + }, + sta = { + type = 'group', + order = 4, + name = L["Stamina"], + desc = L["Changes the display of Stamina"], + args = { + hp = { + type = 'toggle', + width = "full", + name = L["Show Health"], + desc = L["Show Health from Stamina"], + arg = "showHealthFromSta", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + }, + }, + int = { + type = 'group', + order = 5, + name = L["Intellect"], + desc = L["Changes the display of Intellect"], + args = { + spellcrit = { + type = 'toggle', + width = "full", + name = L["Show Spell Crit"], + desc = L["Show Spell Crit chance from Intellect"], + arg = "showSpellCritFromInt", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + mp = { + type = 'toggle', + width = "full", + name = L["Show Mana"], + desc = L["Show Mana from Intellect"], + arg = "showManaFromInt", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + mp5 = { + type = 'toggle', + width = "full", + name = L["Show Mana Regen"], + desc = L["Show Mana Regen while casting from Intellect"], + arg = "showMP5FromInt", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + mp5nc = { + type = 'toggle', + width = "full", + name = L["Show Mana Regen while NOT casting"], + desc = L["Show Mana Regen while NOT casting from Intellect"], + arg = "showMP5NCFromInt", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + }, + }, + spi = { + type = 'group', + order = 6, + name = L["Spirit"], + desc = L["Changes the display of Spirit"], + args = { + mp5nc = { + type = 'toggle', + width = "full", + name = L["Show Mana Regen while NOT casting"], + desc = L["Show Mana Regen while NOT casting from Spirit"], + arg = "showMP5NCFromSpi", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + hp5 = { + type = 'toggle', + width = "full", + name = L["Show Health Regen"], + desc = L["Show Health Regen from Spirit"], + arg = "showHP5FromSpi", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + }, + }, + }, + }, + sum = { + type = 'group', + childGroups = "tab", + name = L["Stat Summary"], + desc = L["Options for stat summary"], + args = { + show = { + type = 'select', + order = 1, + name = L["Show Stat Summary"], + desc = L["Show stat summary in tooltips"], + values = { + [0] = L["Always"], + [1] = L["ALT Key"], + [2] = L["CTRL Key"], + [3] = L["SHIFT Key"], + [4] = L["Never"], + }, + arg = "showSum", + }, + diffstyle = { + type = 'select', + order = 2, + name = L["Display Style For Diff Value"], + desc = L["Display diff values in the main tooltip or only in compare tooltips"], + values = {comp = "comp", main = "main"}, + arg = "sumDiffStyle", + }, + ignore = { + type = 'group', + order = 3, + dialogInline = true, + name = L["Ignore Settings"], + desc = L["Ignore stuff when calculating the stat summary"], + args = { + unused = { + type = 'toggle', + order = 1, + width = "double", + name = L["Ignore Undesirable Items"], + desc = L["Hide stat summary for undesirable items"], + arg = "sumIgnoreUnused", + }, + quality = { + type = 'select', + order = 2, + name = L["Minimum Item Quality"], + desc = L["Show stat summary only for selected quality items and up"], + values = { + [0] = "|cff9d9d9d"..ITEM_QUALITY0_DESC.."|r", + [1] = "|cffffffff"..ITEM_QUALITY1_DESC.."|r", + [2] = "|cff1eff00"..ITEM_QUALITY2_DESC.."|r", + [3] = "|cff0070dd"..ITEM_QUALITY3_DESC.."|r", + [4] = "|cffa335ee"..ITEM_QUALITY4_DESC.."|r", + }, + arg = "sumMinQuality", + disabled = function() return not profileDB.sumIgnoreUnused end, + }, + armor = { + type = 'group', + order = 3, + dialogInline = true, + name = L["Armor Types"], + desc = L["Select armor types you want to ignore"], + disabled = function() return not profileDB.sumIgnoreUnused end, + args = { + cloth = { + type = 'toggle', + order = 1, + name = L["Ignore Cloth"], + desc = L["Hide stat summary for all cloth armor"], + arg = "sumIgnoreCloth", + }, + leather = { + type = 'toggle', + order = 2, + name = L["Ignore Leather"], + desc = L["Hide stat summary for all leather armor"], + arg = "sumIgnoreLeather", + }, + mail = { + type = 'toggle', + order = 3, + name = L["Ignore Mail"], + desc = L["Hide stat summary for all mail armor"], + arg = "sumIgnoreMail", + }, + plate = { + type = 'toggle', + order = 4, + name = L["Ignore Plate"], + desc = L["Hide stat summary for all plate armor"], + arg = "sumIgnorePlate", + }, + }, + }, + equipped = { + type = 'toggle', + order = 5, + width = "double", + name = L["Ignore Equipped Items"], + desc = L["Hide stat summary for equipped items"], + arg = "sumIgnoreEquipped", + }, + enchant = { + type = 'toggle', + order = 10, + width = "double", + name = L["Ignore Enchants"], + desc = L["Ignore enchants on items when calculating the stat summary"], + arg = "sumIgnoreEnchant", + }, + prismaticSocket = { + type = 'toggle', + order = 11, + width = "double", + name = L["Ignore Prismatic Sockets"], + desc = L["Ignore gems in prismatic sockets when calculating the stat summary"], + arg = "sumIgnorePris", + }, + gem = { + type = 'toggle', + order = 15, + width = "double", + name = L["Ignore Gems"], + desc = L["Ignore gems on items when calculating the stat summary"], + arg = "sumIgnoreGems", + }, + }, + }, + space = { + type = 'group', + order = 4, + dialogInline = true, + name = L["Add Empty Line"], + desc = L["Add a empty line before or after stat summary"], + args = { + before = { + type = 'toggle', + name = L["Add Before Summary"], + desc = L["Add a empty line before stat summary"], + arg = "sumBlankLine", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + after = { + type = 'toggle', + name = L["Add After Summary"], + desc = L["Add a empty line after stat summary"], + arg = "sumBlankLineAfter", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + }, + }, + icon = { + type = 'toggle', + order = 5, + name = L["Show Icon"], + desc = L["Show the sigma icon before summary listing"], + arg = "sumShowIcon", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + title = { + type = 'toggle', + order = 6, + name = L["Show Title Text"], + desc = L["Show the title text before summary listing"], + arg = "sumShowTitle", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + showzerostat = { + type = 'toggle', + order = 7, + width = "double", + name = L["Show Zero Value Stats"], + desc = L["Show zero value stats in summary for consistancy"], + arg = "showZeroValueStat", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + calcsum = { + type = 'toggle', + order = 8, + name = L["Calculate Stat Sum"], + desc = L["Calculate the total stats for the item"], + arg = "calcSum", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + calcdiff = { + type = 'toggle', + order = 9, + name = L["Calculate Stat Diff"], + desc = L["Calculate the stat difference for the item and equipped items"], + arg = "calcDiff", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + sort = { + type = 'toggle', + name = L["Sort StatSummary Alphabetically"], + order = 10, + width = "double", + desc = L["Enable to sort StatSummary alphabetically, disable to sort according to stat type(basic, physical, spell, tank)"], + arg = "sumSortAlpha", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + avoidhasblock = { + type = 'toggle', + order = 11, + width = "full", + name = L["Include Block Chance In Avoidance Summary"], + desc = L["Enable to include block chance in Avoidance summary, Disable for only dodge, parry, miss"], + arg = "sumAvoidWithBlock", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + basic = { + type = 'group', + dialogInline = true, + name = L["Stat - Basic"], + desc = L["Choose basic stats for summary"], + args = { + hp = { + type = 'toggle', + name = L["Sum Health"], + desc = L["Health <- Health, Stamina"], + arg = "sumHP", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + mp = { + type = 'toggle', + name = L["Sum Mana"], + desc = L["Mana <- Mana, Intellect"], + arg = "sumMP", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + mp5 = { + type = 'toggle', + name = L["Sum Mana Regen"], + desc = L["Mana Regen <- Mana Regen, Spirit"], + arg = "sumMP5", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + mp5nc = { + type = 'toggle', + name = L["Sum Mana Regen while not casting"], + desc = L["Mana Regen while not casting <- Spirit"], + arg = "sumMP5NC", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + hp5 = { + type = 'toggle', + name = L["Sum Health Regen"], + desc = L["Health Regen <- Health Regen"], + arg = "sumHP5", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + hp5oc = { + type = 'toggle', + name = L["Sum Health Regen when out of combat"], + desc = L["Health Regen when out of combat <- Spirit"], + arg = "sumHP5OC", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + str = { + type = 'toggle', + name = L["Sum Strength"], + desc = L["Strength Summary"], + arg = "sumStr", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + agi = { + type = 'toggle', + name = L["Sum Agility"], + desc = L["Agility Summary"], + arg = "sumAgi", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + sta = { + type = 'toggle', + name = L["Sum Stamina"], + desc = L["Stamina Summary"], + arg = "sumSta", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + int = { + type = 'toggle', + name = L["Sum Intellect"], + desc = L["Intellect Summary"], + arg = "sumInt", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + spi = { + type = 'toggle', + name = L["Sum Spirit"], + desc = L["Spirit Summary"], + arg = "sumSpi", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + mastery = { + type = 'toggle', + name = L["Sum Mastery"], + desc = L["Mastery Summary"], + arg = "sumMastery", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + masteryrating = { + type = 'toggle', + name = L["Sum Mastery Rating"], + desc = L["Mastery Rating Summary"], + arg = "sumMasteryRating", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + }, + }, + physical = { + type = 'group', + dialogInline = true, + name = L["Stat - Physical"], + desc = L["Choose physical damage stats for summary"], + args = { + ap = { + type = 'toggle', + name = L["Sum Attack Power"], + desc = L["Attack Power <- Attack Power, Strength, Agility"], + arg = "sumAP", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + rap = { + type = 'toggle', + name = L["Sum Ranged Attack Power"], + desc = L["Ranged Attack Power <- Ranged Attack Power, Intellect, Attack Power, Strength, Agility"], + arg = "sumRAP", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + fap = { + type = 'toggle', + name = L["Sum Feral Attack Power"], + desc = L["Feral Attack Power <- Feral Attack Power, Attack Power, Strength, Agility"], + arg = "sumFAP", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + hit = { + type = 'toggle', + name = L["Sum Hit Chance"], + desc = L["Hit Chance <- Hit Rating"], + arg = "sumHit", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + hitrating = { + type = 'toggle', + name = L["Sum Hit Rating"], + desc = L["Hit Rating Summary"], + arg = "sumHitRating", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + rangedhit = { + type = 'toggle', + name = L["Sum Ranged Hit Chance"], + desc = L["Ranged Hit Chance <- Hit Rating, Ranged Hit Rating"], + arg = "sumRangedHit", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + rangedhitrating = { + type = 'toggle', + name = L["Sum Ranged Hit Rating"], + desc = L["Ranged Hit Rating Summary"], + arg = "sumRangedHitRating", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + crit = { + type = 'toggle', + name = L["Sum Crit Chance"], + desc = L["Crit Chance <- Crit Rating, Agility"], + arg = "sumCrit", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + critrating = { + type = 'toggle', + name = L["Sum Crit Rating"], + desc = L["Crit Rating Summary"], + arg = "sumCritRating", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + rangedcrit = { + type = 'toggle', + name = L["Sum Ranged Crit Chance"], + desc = L["Ranged Crit Chance <- Crit Rating, Agility, Ranged Crit Rating"], + arg = "sumRangedCrit", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + rangedcritrating = { + type = 'toggle', + name = L["Sum Ranged Crit Rating"], + desc = L["Ranged Crit Rating Summary"], + arg = "sumRangedCritRating", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + haste = { + type = 'toggle', + name = L["Sum Haste"], + desc = L["Haste <- Haste Rating"], + arg = "sumHaste", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + hasterating = { + type = 'toggle', + name = L["Sum Haste Rating"], + desc = L["Haste Rating Summary"], + arg = "sumHasteRating", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + rangedhaste = { + type = 'toggle', + name = L["Sum Ranged Haste"], + desc = L["Ranged Haste <- Haste Rating, Ranged Haste Rating"], + arg = "sumRangedHaste", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + rangedhasterating = { + type = 'toggle', + name = L["Sum Ranged Haste Rating"], + desc = L["Ranged Haste Rating Summary"], + arg = "sumRangedHasteRating", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + neglectdodge = { + type = 'toggle', + name = L["Sum Dodge Neglect"], + desc = L["Dodge Neglect <- Expertise"], + arg = "sumDodgeNeglect", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + neglectparry = { + type = 'toggle', + name = L["Sum Parry Neglect"], + desc = L["Parry Neglect <- Expertise"], + arg = "sumParryNeglect", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + exp = { + type = 'toggle', + name = L["Sum Expertise"], + desc = L["Expertise <- Expertise Rating"], + arg = "sumExpertise", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + exprating = { + type = 'toggle', + name = L["Sum Expertise Rating"], + desc = L["Expertise Rating Summary"], + arg = "sumExpertiseRating", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + maxdamage = { + type = 'toggle', + name = L["Sum Weapon Max Damage"], + desc = L["Weapon Max Damage Summary"], + arg = "sumWeaponMaxDamage", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + }, + }, + spell = { + type = 'group', + dialogInline = true, + name = L["Stat - Spell"], + desc = L["Choose spell damage and healing stats for summary"], + args = { + dmg = { + type = 'toggle', + name = L["Sum Spell Damage"], + desc = L["Spell Damage <- Spell Damage, Intellect, Spirit, Stamina"], + arg = "sumSpellDmg", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + dmgholy = { + type = 'toggle', + name = L["Sum Holy Spell Damage"], + desc = L["Holy Spell Damage <- Holy Spell Damage, Spell Damage, Intellect, Spirit"], + arg = "sumHolyDmg", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + dmgarcane = { + type = 'toggle', + name = L["Sum Arcane Spell Damage"], + desc = L["Arcane Spell Damage <- Arcane Spell Damage, Spell Damage, Intellect"], + arg = "sumArcaneDmg", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + dmgfire = { + type = 'toggle', + name = L["Sum Fire Spell Damage"], + desc = L["Fire Spell Damage <- Fire Spell Damage, Spell Damage, Intellect, Stamina"], + arg = "sumFireDmg", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + dmgnature = { + type = 'toggle', + name = L["Sum Nature Spell Damage"], + desc = L["Nature Spell Damage <- Nature Spell Damage, Spell Damage, Intellect"], + arg = "sumNatureDmg", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + dmgfrost = { + type = 'toggle', + name = L["Sum Frost Spell Damage"], + desc = L["Frost Spell Damage <- Frost Spell Damage, Spell Damage, Intellect"], + arg = "sumFrostDmg", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + dmgshadow = { + type = 'toggle', + name = L["Sum Shadow Spell Damage"], + desc = L["Shadow Spell Damage <- Shadow Spell Damage, Spell Damage, Intellect, Spirit, Stamina"], + arg = "sumShadowDmg", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + heal = { + type = 'toggle', + name = L["Sum Healing"], + desc = L["Healing <- Healing, Intellect, Spirit, Agility, Strength"], + arg = "sumHealing", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + hit = { + type = 'toggle', + name = L["Sum Spell Hit Chance"], + desc = L["Spell Hit Chance <- Spell Hit Rating"], + arg = "sumSpellHit", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + hitrating = { + type = 'toggle', + name = L["Sum Spell Hit Rating"], + desc = L["Spell Hit Rating Summary"], + arg = "sumSpellHitRating", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + crit = { + type = 'toggle', + name = L["Sum Spell Crit Chance"], + desc = L["Spell Crit Chance <- Spell Crit Rating, Intellect"], + arg = "sumSpellCrit", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + critrating = { + type = 'toggle', + name = L["Sum Spell Crit Rating"], + desc = L["Spell Crit Rating Summary"], + arg = "sumSpellCritRating", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + haste = { + type = 'toggle', + name = L["Sum Spell Haste"], + desc = L["Spell Haste <- Spell Haste Rating"], + arg = "sumSpellHaste", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + hasterating = { + type = 'toggle', + name = L["Sum Spell Haste Rating"], + desc = L["Spell Haste Rating Summary"], + arg = "sumSpellHasteRating", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + pen = { + type = 'toggle', + name = L["Sum Penetration"], + desc = L["Spell Penetration Summary"], + arg = "sumPenetration", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + }, + }, + tank = { + type = 'group', + dialogInline = true, + name = L["Stat - Tank"], + desc = L["Choose tank stats for summary"], + args = { + armor = { + type = 'toggle', + name = L["Sum Armor"], + desc = L["Armor <- Armor from items and bonuses"], + arg = "sumArmor", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + dodge = { + type = 'toggle', + name = L["Sum Dodge Chance"], + desc = L["Dodge Chance <- Dodge Rating, Agility"], + arg = "sumDodge", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + dodgerating = { + type = 'toggle', + name = L["Sum Dodge Rating"], + desc = L["Dodge Rating Summary"], + arg = "sumDodgeRating", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + parry = { + type = 'toggle', + name = L["Sum Parry Chance"], + desc = L["Parry Chance <- Parry Rating"], + arg = "sumParry", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + parryrating = { + type = 'toggle', + name = L["Sum Parry Rating"], + desc = L["Parry Rating Summary"], + arg = "sumParryRating", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + block = { + type = 'toggle', + name = L["Sum Block Chance"], + desc = L["Block Chance <- Block Rating"], + arg = "sumBlock", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + blockrating = { + type = 'toggle', + name = L["Sum Block Rating"], + desc = L["Block Rating Summary"], + arg = "sumBlockRating", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + res = { + type = 'toggle', + name = L["Sum Resilience"], + desc = L["Resilience Summary"], + arg = "sumResilience", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + resarcane = { + type = 'toggle', + name = L["Sum Arcane Resistance"], + desc = L["Arcane Resistance Summary"], + arg = "sumArcaneResist", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + resfire = { + type = 'toggle', + name = L["Sum Fire Resistance"], + desc = L["Fire Resistance Summary"], + arg = "sumFireResist", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + resnature = { + type = 'toggle', + name = L["Sum Nature Resistance"], + desc = L["Nature Resistance Summary"], + arg = "sumNatureResist", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + resfrost = { + type = 'toggle', + name = L["Sum Frost Resistance"], + desc = L["Frost Resistance Summary"], + arg = "sumFrostResist", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + resshadow = { + type = 'toggle', + name = L["Sum Shadow Resistance"], + desc = L["Shadow Resistance Summary"], + arg = "sumShadowResist", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + avoid = { + type = 'toggle', + name = L["Sum Avoidance"], + desc = L["Avoidance <- Dodge, Parry, MobMiss, Block(Optional)"], + arg = "sumAvoidance", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + }, + }, + gemset = { + type = 'select', + order = 12, + cmdHidden = true, + name = L["Gem Set"], + desc = L["Select a gem set to configure"], + values = { + [1] = L["Default Gem Set 1"], + [2] = L["Default Gem Set 2"], + [3] = L["Default Gem Set 3"], + }, + arg = "selectedGemSet", + get = function() return selectedGemSet end, + set = function(info, value) selectedGemSet = value end, + }, + gem = { + type = 'group', + order = 13, + dialogInline = true, + hidden = function() return selectedGemSet ~= 1 end, + name = L["Default Gem Set 1"], + desc = L["Auto fill empty gem slots"], + args = { + red = { + type = 'input', + order = 1, + width = "double", + name = L["Red Socket"], + desc = L["ItemID or Link of the gem you would like to auto fill"], + usage = L[""], + arg = "sumGemRed", + get = getGem, + set = setGem, + }, + yellow = { + type = 'input', + order = 2, + width = "double", + name = L["Yellow Socket"], + desc = L["ItemID or Link of the gem you would like to auto fill"], + usage = L[""], + arg = "sumGemYellow", + get = getGem, + set = setGem, + }, + blue = { + type = 'input', + order = 3, + width = "double", + name = L["Blue Socket"], + desc = L["ItemID or Link of the gem you would like to auto fill"], + usage = L[""], + arg = "sumGemBlue", + get = getGem, + set = setGem, + }, + meta = { + type = 'input', + order = 4, + width = "double", + name = L["Meta Socket"], + desc = L["ItemID or Link of the gem you would like to auto fill"], + usage = L[""], + arg = "sumGemMeta", + get = getGem, + set = setGem, + }, + }, + }, + gem2 = { + type = 'group', + order = 14, + dialogInline = true, + hidden = function() return selectedGemSet ~= 2 end, + name = L["Default Gem Set 2"], + desc = L["Second set of default gems which can be toggled with a modifier key"], + args = { + key = { + type = 'select', + order = 0, + name = L["Toggle Key"], + desc = L["Use this key to toggle alternate gems"], + values = { + [1] = L["ALT Key"], + [2] = L["CTRL Key"], + [3] = L["SHIFT Key"], + [4] = L["Never"], + }, + arg = "sumGem2Toggle", + get = function() return profileDB.sumGem2Toggle end, + set = function(info, value) + if value ~= 4 and value == profileDB.sumGem3Toggle then + AceConfigRegistry:NotifyChange("RatingBuster") + RatingBuster:Print(L["Can't use the same modifier as Gem Set 3"]) + else + profileDB.sumGem2Toggle = value + end + end, + }, + red = { + type = 'input', + order = 1, + width = "double", + name = L["Red Socket"], + desc = L["ItemID or Link of the gem you would like to auto fill"], + usage = L[""], + arg = "sumGemRed2", + get = getGem, + set = setGem, + disabled = function() return profileDB.sumGem2Toggle == 4 end, + }, + yellow = { + type = 'input', + order = 2, + width = "double", + name = L["Yellow Socket"], + desc = L["ItemID or Link of the gem you would like to auto fill"], + usage = L[""], + arg = "sumGemYellow2", + get = getGem, + set = setGem, + disabled = function() return profileDB.sumGem2Toggle == 4 end, + }, + blue = { + type = 'input', + order = 3, + width = "double", + name = L["Blue Socket"], + desc = L["ItemID or Link of the gem you would like to auto fill"], + usage = L[""], + arg = "sumGemBlue2", + get = getGem, + set = setGem, + disabled = function() return profileDB.sumGem2Toggle == 4 end, + }, + meta = { + type = 'input', + order = 4, + width = "double", + name = L["Meta Socket"], + desc = L["ItemID or Link of the gem you would like to auto fill"], + usage = L[""], + arg = "sumGemMeta2", + get = getGem, + set = setGem, + disabled = function() return profileDB.sumGem2Toggle == 4 end, + }, + }, + }, + gem3 = { + type = 'group', + order = 15, + dialogInline = true, + hidden = function() return selectedGemSet ~= 3 end, + name = L["Default Gem Set 3"], + desc = L["Third set of default gems which can be toggled with a modifier key"], + args = { + key = { + type = 'select', + order = 0, + name = L["Toggle Key"], + desc = L["Use this key to toggle alternate gems"], + values = { + [1] = L["ALT Key"], + [2] = L["CTRL Key"], + [3] = L["SHIFT Key"], + [4] = L["Never"], + }, + arg = "sumGem3Toggle", + get = function() return profileDB.sumGem3Toggle end, + set = function(info, value) + if value ~= 4 and value == profileDB.sumGem2Toggle then + AceConfigRegistry:NotifyChange("RatingBuster") + RatingBuster:Print(L["Can't use the same modifier as Gem Set 2"]) + else + profileDB.sumGem3Toggle = value + end + end, + }, + red = { + type = 'input', + order = 1, + width = "double", + name = L["Red Socket"], + desc = L["ItemID or Link of the gem you would like to auto fill"], + usage = L[""], + arg = "sumGemRed3", + get = getGem, + set = setGem, + disabled = function() return profileDB.sumGem3Toggle == 4 end, + }, + yellow = { + type = 'input', + order = 2, + width = "double", + name = L["Yellow Socket"], + desc = L["ItemID or Link of the gem you would like to auto fill"], + usage = L[""], + arg = "sumGemYellow3", + get = getGem, + set = setGem, + disabled = function() return profileDB.sumGem3Toggle == 4 end, + }, + blue = { + type = 'input', + order = 3, + width = "double", + name = L["Blue Socket"], + desc = L["ItemID or Link of the gem you would like to auto fill"], + usage = L[""], + arg = "sumGemBlue3", + get = getGem, + set = setGem, + disabled = function() return profileDB.sumGem3Toggle == 4 end, + }, + meta = { + type = 'input', + order = 4, + width = "double", + name = L["Meta Socket"], + desc = L["ItemID or Link of the gem you would like to auto fill"], + usage = L[""], + arg = "sumGemMeta3", + get = getGem, + set = setGem, + disabled = function() return profileDB.sumGem3Toggle == 4 end, + }, + }, + }, + }, + }, + }, +} + +-- TankPoints support, version check +local tpSupport +local tpLocale +if TankPoints and (tonumber(strsub(TankPoints.version, 1, 3)) >= 2.6) then + tpSupport = true + tpLocale = AceLibrary("AceLocale-2.2"):new("TankPoints") + options.args.sum.args.tank.args.tp = { + type = 'toggle', + name = L["Sum TankPoints"], + desc = L["TankPoints <- Health, Total Reduction"], + arg = "sumTankPoints", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + options.args.sum.args.tank.args.tr = { + type = 'toggle', + name = L["Sum Total Reduction"], + desc = L["Total Reduction <- Armor, Dodge, Parry, Block, Block Value, Defense, Resilience, MobMiss, MobCrit, MobCrush, DamageTakenMods"], + arg = "sumTotalReduction", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + --[[ + options.args.sum.args.tank.args.avoid = { + type = 'toggle', + name = L["Sum Avoidance"], + desc = L["Avoidance <- Dodge, Parry, MobMiss"], + arg = "sumAvoidance", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + --]] +end + + +-- Class specific options +if class == "DRUID" then + if GetSpellInfo(47180) then + options.args.stat.args.agi.args.heal = { -- Nurturing Instinct (Rank 2) - 2,14 + type = 'toggle', + width = "full", + name = L["Show Healing"].." ("..GetSpellInfo(47180)..")", -- ["Nurturing Instinct"] + desc = L["Show Healing from Agility"].." ("..GetSpellInfo(47180)..")", -- ["Nurturing Instinct"] + arg = "showHealingFromAgi", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end + if GetSpellInfo(33591) then + options.args.stat.args.int.args.dmg = { -- Lunar Guidance (Rank 3) - 1,12 + type = 'toggle', + width = "full", + name = L["Show Spell Damage"].." ("..GetSpellInfo(33591)..")", -- ["Lunar Guidance"] + desc = L["Show Spell Damage from Intellect"].." ("..GetSpellInfo(33591)..")", -- ["Lunar Guidance"] + arg = "showSpellDmgFromInt", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end + if GetSpellInfo(33591) then + options.args.stat.args.int.args.heal = { -- Lunar Guidance (Rank 3) - 1,12 + type = 'toggle', + width = "full", + name = L["Show Healing"].." ("..GetSpellInfo(33591)..")", + desc = L["Show Healing from Intellect"].." ("..GetSpellInfo(33591)..")", + arg = "showHealingFromInt", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end + if GetSpellInfo(35359) then + options.args.stat.args.spi.args.mp5 = { -- Intensity (Rank 3) - 3,6 + type = 'toggle', + width = "full", + name = L["Show Mana Regen"].." ("..GetSpellInfo(35359)..")", + desc = L["Show Mana Regen while casting from Spirit"].." ("..GetSpellInfo(35359)..")", + arg = "showMP5FromSpi", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end + if GetSpellInfo(48384) then + options.args.stat.args.spi.args.dmg = { -- Improved Moonkin Form (Rank 3) - 1,19 + type = 'toggle', + width = "full", + name = L["Show Spell Damage"].." ("..GetSpellInfo(48384)..")", + desc = L["Show Spell Damage from Spirit"].." ("..GetSpellInfo(48384)..")", + arg = "showSpellDmgFromSpi", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end + if GetSpellInfo(48537) then + options.args.stat.args.spi.args.heal = { -- Improved Tree of Life (Rank 3) - 3,24 + type = 'toggle', + width = "full", + name = L["Show Healing"].." ("..GetSpellInfo(48537)..")", + desc = L["Show Healing from Spirit"].." ("..GetSpellInfo(48537)..")", + arg = "showHealingFromSpi", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end +elseif class == "HUNTER" then + if GetSpellInfo(34484) then + options.args.stat.args.int.args.rap = { -- Careful Aim + type = 'toggle', + width = "full", + name = L["Show Ranged Attack Power"].." ("..GetSpellInfo(34484)..")", + desc = L["Show Ranged Attack Power from Intellect"].." ("..GetSpellInfo(34484)..")", + arg = "showRAPFromInt", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end + if GetSpellInfo(56341) then + options.args.stat.args.sta.args.ap = { -- Hunter: Hunter vs. Wild + type = 'toggle', + width = "full", + name = L["Show Attack Power"].." ("..GetSpellInfo(56341)..")", + desc = L["Show Attack Power from Stamina"].." ("..GetSpellInfo(56341)..")", + arg = "showAPFromSta", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end +elseif class == "MAGE" then + if GetSpellInfo(31588) then + options.args.stat.args.int.args.dmg = { -- Mind Mastery (Rank 5) - 1,22 + type = 'toggle', + width = "full", + name = L["Show Spell Damage"].." ("..GetSpellInfo(31588)..")", + desc = L["Show Spell Damage from Intellect"].." ("..GetSpellInfo(31588)..")", + arg = "showSpellDmgFromInt", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end + if GetSpellInfo(28574) then + options.args.stat.args.int.args.armor = { -- Arcane Fortitude - 1,9 + type = 'toggle', + width = "full", + name = L["Show Armor"].." ("..GetSpellInfo(28574)..")", + desc = L["Show Armor from Intellect"].." ("..GetSpellInfo(28574)..")", + arg = "showArmorFromInt", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end + if GetSpellInfo(18464) then + options.args.stat.args.spi.args.mp5 = { -- Arcane Meditation (Rank 3) - 1,12 + type = 'toggle', + width = "full", + name = L["Show Mana Regen"].." ("..GetSpellInfo(18464)..")", + desc = L["Show Mana Regen while casting from Spirit"].." ("..GetSpellInfo(18464)..")", + arg = "showMP5FromSpi", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end + if GetSpellInfo(30482) then + options.args.stat.args.spi.args.spellcrit = { -- Molten Armor + type = 'toggle', + width = "full", + name = L["Show Spell Crit"].." ("..GetSpellInfo(30482)..")", + desc = L["Show Spell Crit chance from Spirit"].." ("..GetSpellInfo(30482)..")", + arg = "showSpellCritFromSpi", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end +elseif class == "PALADIN" then + if GetSpellInfo(31841) then + options.args.stat.args.int.args.dmg = { -- Paladin: Holy Guidance (Rank 5) - 1,19 + type = 'toggle', + width = "full", + name = L["Show Spell Damage"].." ("..GetSpellInfo(31841)..")", + desc = L["Show Spell Damage from Intellect"].." ("..GetSpellInfo(31841)..")", + arg = "showSpellDmgFromInt", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end + if GetSpellInfo(31841) then + options.args.stat.args.int.args.heal = { -- Paladin: Holy Guidance (Rank 5) - 1,19 + type = 'toggle', + width = "full", + name = L["Show Healing"].." ("..GetSpellInfo(31841)..")", + desc = L["Show Healing from Intellect"].." ("..GetSpellInfo(31841)..")", + arg = "showHealingFromInt", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end + if GetSpellInfo(53501) and GetSpellInfo(53592) then + options.args.stat.args.str.args.dmg = { -- Paladin: Sheath of Light, Touched by the Light + type = 'toggle', + width = "full", + name = L["Show Spell Damage"].." ("..GetSpellInfo(53501)..", "..GetSpellInfo(53592)..")", + desc = L["Show Spell Damage from Strength"].." ("..GetSpellInfo(53501)..", "..GetSpellInfo(53592)..")", + arg = "showSpellDmgFromStr", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end + if GetSpellInfo(53501) and GetSpellInfo(53592) then + options.args.stat.args.str.args.heal = { -- Paladin: Sheath of Light, Touched by the Light + type = 'toggle', + width = "full", + name = L["Show Healing"].." ("..GetSpellInfo(53501)..", "..GetSpellInfo(53592)..")", + desc = L["Show Healing from Strength"].." ("..GetSpellInfo(53501)..", "..GetSpellInfo(53592)..")", + arg = "showHealingFromStr", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end +elseif class == "PRIEST" then + if GetSpellInfo(38346) then + options.args.stat.args.spi.args.mp5 = { -- Meditation (Rank 3) - 1,9 + type = 'toggle', + width = "full", + name = L["Show Mana Regen"].." ("..GetSpellInfo(38346)..")", + desc = L["Show Mana Regen while casting from Spirit"].." ("..GetSpellInfo(38346)..")", + arg = "showMP5FromSpi", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end + if GetSpellInfo(15031) and GetSpellInfo(47573) then + options.args.stat.args.spi.args.dmg = { -- Spiritual Guidance (Rank 5) - 2,14, Twisted Faith - 3,26 + type = 'toggle', + width = "full", + name = L["Show Spell Damage"].." ("..GetSpellInfo(15031)..", "..GetSpellInfo(47573)..")", + desc = L["Show Spell Damage from Spirit"].." ("..GetSpellInfo(15031)..", "..GetSpellInfo(47573)..")", + arg = "showSpellDmgFromSpi", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end + if GetSpellInfo(15031) and GetSpellInfo(47573) then + options.args.stat.args.spi.args.heal = { -- Spiritual Guidance (Rank 5) - 2,14, Twisted Faith - 3,26 + type = 'toggle', + width = "full", + name = L["Show Healing"].." ("..GetSpellInfo(15031)..", "..GetSpellInfo(47573)..")", + desc = L["Show Healing from Spirit"].." ("..GetSpellInfo(15031)..", "..GetSpellInfo(47573)..")", + arg = "showHealingFromSpi", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end +elseif class == "ROGUE" then +elseif class == "SHAMAN" then + if GetSpellInfo(30814) then + options.args.stat.args.str.args.dmg = { -- Mental Quickness (Rank 3) - 2,15 + type = 'toggle', + width = "full", + name = L["Show Spell Damage"].." ("..GetSpellInfo(30814)..")", + desc = L["Show Spell Damage from Strength"].." ("..GetSpellInfo(30814)..")", + arg = "showSpellDmgFromStr", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end + if GetSpellInfo(30814) then + options.args.stat.args.str.args.heal = { -- Mental Quickness (Rank 3) - 2,15 + type = 'toggle', + width = "full", + name = L["Show Healing"].." ("..GetSpellInfo(30814)..")", + desc = L["Show Healing from Strength"].." ("..GetSpellInfo(30814)..")", + arg = "showHealingFromStr", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end + if GetSpellInfo(30869) then + options.args.stat.args.int.args.dmg = { -- Nature's Blessing (Rank 3) - 3,18 + type = 'toggle', + width = "full", + name = L["Show Spell Damage"].." ("..GetSpellInfo(30869)..")", + desc = L["Show Spell Damage from Intellect"].." ("..GetSpellInfo(30869)..")", + arg = "showSpellDmgFromInt", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end + if GetSpellInfo(30869) then + options.args.stat.args.int.args.heal = { -- Nature's Blessing (Rank 3) - 3,18 + type = 'toggle', + width = "full", + name = L["Show Healing"].." ("..GetSpellInfo(30869)..")", + desc = L["Show Healing from Intellect"].." ("..GetSpellInfo(30869)..")", + arg = "showHealingFromInt", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end + if GetSpellInfo(51885) then + options.args.stat.args.int.args.ap = { -- Shaman: Mental Dexterity + type = 'toggle', + width = "full", + name = L["Show Attack Power"].." ("..GetSpellInfo(51885)..")", + desc = L["Show Attack Power from Intellect"].." ("..GetSpellInfo(51885)..")", + arg = "showAPFromInt", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end +elseif class == "WARLOCK" then + if GetSpellInfo(35693) then + options.args.stat.args.sta.args.dmg = { -- Demonic Knowledge (Rank 3) - 2,20 - UnitExists("pet") + type = 'toggle', + width = "full", + name = L["Show Spell Damage"].." ("..GetSpellInfo(35693)..")", + desc = L["Show Spell Damage from Stamina"].." ("..GetSpellInfo(35693)..")", + arg = "showSpellDmgFromSta", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end + if GetSpellInfo(35693) then + options.args.stat.args.int.args.dmg = { -- Demonic Knowledge (Rank 3) - 2,20 - UnitExists("pet") + type = 'toggle', + width = "full", + name = L["Show Spell Damage"].." ("..GetSpellInfo(35693)..")", + desc = L["Show Spell Damage from Intellect"].." ("..GetSpellInfo(35693)..")", + arg = "showSpellDmgFromInt", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end + if GetSpellInfo(28176) then + options.args.stat.args.spi.args.dmg = { -- Warlock: Fel Armor + type = 'toggle', + width = "full", + name = L["Show Spell Damage"].." ("..GetSpellInfo(28176)..")", + desc = L["Show Spell Damage from Spirit"].." ("..GetSpellInfo(28176)..")", + arg = "showSpellDmgFromSpi", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end + if GetSpellInfo(28176) then + options.args.stat.args.spi.args.heal = { -- Warlock: Fel Armor + type = 'toggle', + width = "full", + name = L["Show Healing"].." ("..GetSpellInfo(28176)..")", + desc = L["Show Healing from Spirit"].." ("..GetSpellInfo(28176)..")", + arg = "showHealingFromSpi", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end +elseif class == "WARRIOR" then + options.args.stat.args.armor = { -- Armored to the Teeth (Rank 3) - 2,1 + type = 'group', + order = 7, + name = L["Armor"], + desc = L["Changes the display of Armor"], + args = { + ap = { + type = 'toggle', + width = "full", + name = L["Show Attack Power"], + desc = L["Show Attack Power from Armor"], + arg = "showAPFromArmor", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + }, + } +elseif class == "DEATHKNIGHT" then + if GetSpellInfo(49410) then + options.args.stat.args.str.args.parry = { -- Death Knight: Forceful Deflection - Passive + type = 'toggle', + width = "full", + name = L["Show Parry"].." ("..GetSpellInfo(49410)..")", + desc = L["Show Parry from Strength"].." ("..GetSpellInfo(49410)..")", + arg = "showParryFromStr", + get = getProfileOption, + set = setProfileOptionAndClearCache, + } + end + options.args.stat.args.armor = { -- Bladed Armor (Rank 5) - 1,4 + type = 'group', + order = 7, + name = L["Armor"], + desc = L["Changes the display of Armor"], + args = { + ap = { + type = 'toggle', + width = "full", + name = L["Show Attack Power"], + desc = L["Show Attack Power from Armor"], + arg = "showAPFromArmor", + get = getProfileOption, + set = setProfileOptionAndClearCache, + }, + }, + } +end + +function RatingBuster:SetupOptions() + -- Inject profile options + options.args.profile = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db) + options.args.profile.order = -2 + + -- Add dual-spec support + local LibDualSpec = LibStub("LibDualSpec-1.0", true) + if LibDualSpec then + LibDualSpec:EnhanceDatabase(self.db, "RatingBuster") + LibDualSpec:EnhanceOptions(options.args.profile, self.db) + end + + -- Register options table + AceConfig:RegisterOptionsTable("RatingBuster", options, {"rb", "rabu", "ratingbuster"}) + + -- Setup Blizzard option frames + self.optionsFrames = {} + -- The ordering here matters, it determines the order in the Blizzard Interface Options + self.optionsFrames.general = AceConfigDialog:AddToBlizOptions("RatingBuster", nil, nil, "general") + self.optionsFrames.rating = AceConfigDialog:AddToBlizOptions("RatingBuster", L["Rating"], "RatingBuster", "rating") + self.optionsFrames.stat = AceConfigDialog:AddToBlizOptions("RatingBuster", L["Stat Breakdown"], "RatingBuster", "stat") + self.optionsFrames.sum = AceConfigDialog:AddToBlizOptions("RatingBuster", L["Stat Summary"], "RatingBuster", "sum") + self.optionsFrames.profile = AceConfigDialog:AddToBlizOptions("RatingBuster", L["Profiles"], "RatingBuster", "profile") + --self.optionsFrames.help = AceConfigDialog:AddToBlizOptions("RatingBuster", L["Help File"], "RatingBuster", "Help") +end + +function RatingBuster:ShowConfig() + -- Open the profiles tab before, so the menu expands + InterfaceOptionsFrame_OpenToCategory(self.optionsFrames.profile) + InterfaceOptionsFrame_OpenToCategory(self.optionsFrames.general) +end + +----------- +-- Tools -- +----------- +-- copyTable +local function copyTable(to, from) + if to then + for k in pairs(to) do + to[k] = nil + end + setmetatable(to, nil) + else + to = {} + end + for k,v in pairs(from) do + if type(k) == "table" then + k = copyTable({}, k) + end + if type(v) == "table" then + v = copyTable({}, v) + end + to[k] = v + end + setmetatable(to, getmetatable(from)) + return to +end + +------------------------------------ +-- Hide Blizzard Item Comparisons -- +------------------------------------ +local function HookSetHyperlinkCompareItem(shoppingtip) + local old = shoppingtip.SetHyperlinkCompareItem + shoppingtip.SetHyperlinkCompareItem = function(self, link, level, shift, main, ...) + if profileDB.hideBlizzardComparisons then + main = nil + end + return old(self, link, level, shift, main, ...) + end +end + +--------- +-- API -- +--------- +function RatingBuster:GetStatMod(stat, school, talentGroup) + return StatLogic:GetStatMod(stat, school, talentGroup) +end +function RatingBuster:ClearCache() + clearCache() +end + +--------------------- +-- Initializations -- +--------------------- +--[[ Loading Process Event Reference +{ +ADDON_LOADED - When this addon is loaded +VARIABLES_LOADED - When all addons are loaded +PLAYER_LOGIN - Most information about the game world should now be available to the UI +} +--]] + +function RatingBuster:OnProfileChanged(event, database, newProfileKey) + -- this is called every time our profile changes (after the change) + profileDB = database.profile + clearCache() +end + +-- OnInitialize(name) called at ADDON_LOADED +function RatingBuster:OnInitialize() + -- Create DB + self.db = AceDB:New("RatingBusterDB", defaults) + self.db.RegisterCallback(self, "OnProfileChanged", "OnProfileChanged") + self.db.RegisterCallback(self, "OnProfileCopied", "OnProfileChanged") + self.db.RegisterCallback(self, "OnProfileReset", "OnProfileChanged") + + profileDB = self.db.profile + + self:SetupOptions() + + -- Hook ShoppingTooltips to enable options to Hide Blizzard Item Comparisons + HookSetHyperlinkCompareItem(ShoppingTooltip1) + HookSetHyperlinkCompareItem(ShoppingTooltip2) + HookSetHyperlinkCompareItem(ShoppingTooltip3) + HookSetHyperlinkCompareItem(ItemRefShoppingTooltip1) + HookSetHyperlinkCompareItem(ItemRefShoppingTooltip2) + HookSetHyperlinkCompareItem(ItemRefShoppingTooltip3) +end + +-- OnEnable() called at PLAYER_LOGIN +function RatingBuster:OnEnable() + -- Hook item tooltips + TipHooker:Hook(self.ProcessTooltip, "item") + -- Initialize playerLevel + playerLevel = UnitLevel("player") + -- for setting a new level + self:RegisterEvent("PLAYER_LEVEL_UP") + -- Events that require cache clearing + self:RegisterEvent("CHARACTER_POINTS_CHANGED", clearCache) -- talent point changed + self:RegisterEvent("MODIFIER_STATE_CHANGED") -- modifier key press + self:RegisterEvent("UNIT_AURA") -- fire at most once every 1 second +end + +function RatingBuster:OnDisable() + -- Unhook item tooltips + TipHooker:Unhook(self.ProcessTooltip, "item") +end + +-- event = PLAYER_LEVEL_UP +-- arg1 = New player level +function RatingBuster:PLAYER_LEVEL_UP(event, newlevel) + playerLevel = newlevel + clearCache() +end + +-- event = UNIT_AURA +-- arg1 = the UnitID of the entity +function RatingBuster:UNIT_AURA(event, unit) + if unit ~= "player" then return end + clearCache() +end +--local tooltips = {} +function RatingBuster:MODIFIER_STATE_CHANGED(event, key, state) + -- self:Print("MODIFIER_STATE_CHANGED") + -- for tooltip, link in pairs(tooltips) do + -- if tooltip:IsShown() and not strfind(tooltip:GetName(), "ompar") and not strfind(tooltip:GetName(), "Shopping") then + -- tooltip:ClearLines() + -- ShowUIPanel(tooltip) + -- tooltip:SetHyperlink(link) + -- end + -- end + clearCache() +end + +-------------------------- +-- Process Tooltip Core -- +-------------------------- +--[[ +"+15 Agility" +-> "+15 Agility (+0.46% Crit)" +"+15 Crit Rating" +-> "+15 Crit Rating (+1.20%)" +"Equip: Increases your hit rating by 10." +-> "Equip: Increases your hit rating by 10 (+1.20%)." +--]] +-- Empty Sockets +local EMPTY_SOCKET_RED = EMPTY_SOCKET_RED +local EMPTY_SOCKET_YELLOW = EMPTY_SOCKET_YELLOW +local EMPTY_SOCKET_BLUE = EMPTY_SOCKET_BLUE +local EMPTY_SOCKET_META = EMPTY_SOCKET_META +local EmptySocketLookup = { + [EMPTY_SOCKET_RED] = "sumGemRed", -- EMPTY_SOCKET_RED = "Red Socket"; + [EMPTY_SOCKET_YELLOW] = "sumGemYellow", -- EMPTY_SOCKET_YELLOW = "Yellow Socket"; + [EMPTY_SOCKET_BLUE] = "sumGemBlue", -- EMPTY_SOCKET_BLUE = "Blue Socket"; + [EMPTY_SOCKET_META] = "sumGemMeta", -- EMPTY_SOCKET_META = "Meta Socket"; +} +-- Color code (used to fix gem text color) +local currentColorCode +-- Avoidance DR calculation +local summaryFunc = {} +local equippedSum = {} +local equippedDodge, equippedParry, equippedMissed +local processedDodge, processedParry, processedMissed + +-- Modifier Keys +local isModifierKeyDown = { + [0] = function() return true end, + [1] = IsAltKeyDown, + [2] = IsControlKeyDown, + [3] = IsShiftKeyDown, +} +function RatingBuster.ProcessTooltip(tooltip, name, link, ...) + -- Check if we're in standby mode + if not RatingBuster:IsEnabled() then return end + --tooltips[tooltip] = link + --------------------------- + -- Set calculation level -- + --------------------------- + calcLevel = profileDB.customLevel or 0 + if calcLevel == 0 then + calcLevel = playerLevel + end + if profileDB.useRequiredLevel and link then + local _, _, _, _, reqLevel = GetItemInfo(link) + --RatingBuster:Print(link..", "..calcLevel) + if reqLevel and calcLevel < reqLevel then + calcLevel = reqLevel + end + end + --------------------- + -- Tooltip Scanner -- + --------------------- + -- Get equipped item avoidances + if profileDB.enableAvoidanceDiminishingReturns then + local red, yellow, blue, meta + if isModifierKeyDown[profileDB.sumGem2Toggle] and isModifierKeyDown[profileDB.sumGem2Toggle]() then + red = profileDB.sumGemRed2.gemID + yellow = profileDB.sumGemYellow2.gemID + blue = profileDB.sumGemBlue2.gemID + meta = profileDB.sumGemMeta2.gemID + elseif isModifierKeyDown[profileDB.sumGem3Toggle] and isModifierKeyDown[profileDB.sumGem3Toggle]() then + red = profileDB.sumGemRed3.gemID + yellow = profileDB.sumGemYellow3.gemID + blue = profileDB.sumGemBlue3.gemID + meta = profileDB.sumGemMeta3.gemID + else + red = profileDB.sumGemRed.gemID + yellow = profileDB.sumGemYellow.gemID + blue = profileDB.sumGemBlue.gemID + meta = profileDB.sumGemMeta.gemID + end + local _, mainlink, difflink1, difflink2 = StatLogic:GetDiffID(tooltip, profileDB.sumIgnoreEnchant, profileDB.sumIgnoreGems, red, yellow, blue, meta, profileDB.sumIgnorePris) + StatLogic:GetSum(difflink1, equippedSum) + equippedSum["STR"] = (equippedSum["STR"] or 0) * RatingBuster:GetStatMod("MOD_STR") + equippedSum["AGI"] = (equippedSum["AGI"] or 0) * RatingBuster:GetStatMod("MOD_AGI") + equippedDodge = summaryFunc["DODGE_NO_DR"](equippedSum, "sum", difflink1) * -1 + equippedParry = summaryFunc["PARRY_NO_DR"](equippedSum, "sum", difflink1) * -1 + equippedMissed = summaryFunc["MELEE_HIT_AVOID_NO_DR"](equippedSum, "sum", difflink1) * -1 + processedDodge = equippedDodge + processedParry = equippedParry + processedMissed = equippedMissed + else + equippedDodge = 0 + equippedParry = 0 + equippedMissed = 0 + processedDodge = 0 + processedParry = 0 + processedMissed = 0 + end + + if isModifierKeyDown[profileDB.sumGem2Toggle] and isModifierKeyDown[profileDB.sumGem2Toggle]() then + EmptySocketLookup[EMPTY_SOCKET_RED] = "sumGemRed2" + EmptySocketLookup[EMPTY_SOCKET_YELLOW] = "sumGemYellow2" + EmptySocketLookup[EMPTY_SOCKET_BLUE] = "sumGemBlue2" + EmptySocketLookup[EMPTY_SOCKET_META] = "sumGemMeta2" + elseif isModifierKeyDown[profileDB.sumGem3Toggle] and isModifierKeyDown[profileDB.sumGem3Toggle]() then + EmptySocketLookup[EMPTY_SOCKET_RED] = "sumGemRed3" + EmptySocketLookup[EMPTY_SOCKET_YELLOW] = "sumGemYellow3" + EmptySocketLookup[EMPTY_SOCKET_BLUE] = "sumGemBlue3" + EmptySocketLookup[EMPTY_SOCKET_META] = "sumGemMeta3" + else + EmptySocketLookup[EMPTY_SOCKET_RED] = "sumGemRed" + EmptySocketLookup[EMPTY_SOCKET_YELLOW] = "sumGemYellow" + EmptySocketLookup[EMPTY_SOCKET_BLUE] = "sumGemBlue" + EmptySocketLookup[EMPTY_SOCKET_META] = "sumGemMeta" + end + -- Loop through tooltip lines starting at line 2 + local tipTextLeft = tooltip:GetName().."TextLeft" + for i = 2, tooltip:NumLines() do + local fontString = _G[tipTextLeft..i] + local text = fontString:GetText() + if text then + -- Get data from cache if available + local cacheID = text..calcLevel + local cacheText = cache[cacheID] + if cacheText then + if cacheText ~= text then + fontString:SetText(cacheText) + end + elseif EmptySocketLookup[text] and profileDB[EmptySocketLookup[text]].gemText then -- Replace empty sockets with gem text + text = profileDB[EmptySocketLookup[text]].gemText + cache[cacheID] = text + -- SetText + fontString:SetText(text) + elseif strfind(text, "%d") then -- do nothing if we don't find a number + -- Find and set color code (used to fix gem text color) pattern:|cxxxxxxxx + currentColorCode = select(3, strfind(text, "(|c%x%x%x%x%x%x%x%x)")) or "|r" + -- Initial pattern check, do nothing if not found + -- Check for separators and bulid separatorTable + local separatorTable = {} + for _, sep in ipairs(L["separators"]) do + if strfind(text, sep) then + tinsert(separatorTable, sep) + end + end + -- SplitDoJoin + text = RatingBuster:SplitDoJoin(text, separatorTable, tooltip) + cache[cacheID] = text + -- SetText + fontString:SetText(text) + end + end + end + ---------------------------- + -- Item Level and Item ID -- + ---------------------------- + -- Check for ItemLevel addon, do nothing if found + if not ItemLevel_AddInfo and (profileDB.showItemLevel or profileDB.showItemID) and link then + if cache[link] then + tooltip:AddLine(cache[link]) + else + -- Get the Item ID from the link string + local _, link, _, level = GetItemInfo(link) + if link then + local _, _, id = strfind(link, "item:(%d+)") + local newLine = "" + if level and profileDB.showItemLevel then + newLine = newLine..L["ItemLevel: "]..level + end + if id and profileDB.showItemID then + if newLine ~= "" then + newLine = newLine..", " + end + newLine = newLine..L["ItemID: "]..id + end + if newLine ~= "" then + cache[link] = newLine + tooltip:AddLine(newLine) + end + end + end + end + ------------------ + -- Stat Summary -- + ------------------ + --[[ + ---------------- + -- Base Stats -- + ---------------- + -- Health - HEALTH, STA + -- Mana - MANA, INT + -- Attack Power - AP, STR, AGI + -- Ranged Attack Power - RANGED_AP, INT, AP, STR, AGI + -- Feral Attack Power - FERAL_AP, AP, STR, AGI + -- Spell Damage - SPELL_DMG, STA, INT, SPI + -- Holy Damage - HOLY_SPELL_DMG, SPELL_DMG, INT, SPI + -- Arcane Damage - ARCANE_SPELL_DMG, SPELL_DMG, INT + -- Fire Damage - FIRE_SPELL_DMG, SPELL_DMG, STA, INT + -- Nature Damage - NATURE_SPELL_DMG, SPELL_DMG, INT + -- Frost Damage - FROST_SPELL_DMG, SPELL_DMG, INT + -- Shadow Damage - SHADOW_SPELL_DMG, SPELL_DMG, STA, INT, SPI + -- Healing - HEAL, STR, INT, SPI + -- Hit Chance - MELEE_HIT_RATING, WEAPON_RATING + -- Crit Chance - MELEE_CRIT_RATING, WEAPON_RATING, AGI + -- Spell Hit Chance - SPELL_HIT_RATING + -- Spell Crit Chance - SPELL_CRIT_RATING, INT + -- Mana Regen - MANA_REG, SPI + -- Health Regen - HEALTH_REG + -- Mana Regen Not Casting - SPI + -- Health Regen While Casting - SPI + -- Armor - ARMOR, ARMOR_BONUS, AGI, INT + -- Block Value - BLOCK_VALUE, STR + -- Dodge Chance - DODGE_RATING, DEFENSE_RATING, AGI + -- Parry Chance - PARRY_RATING, DEFENSE_RATING + -- Block Chance - BLOCK_RATING, DEFENSE_RATING + -- Hit Avoidance - DEFENSE_RATING, MELEE_HIT_AVOID_RATING + -- Crit Avoidance - DEFENSE_RATING, RESILIENCE_RATING, MELEE_CRIT_AVOID_RATING + -- Dodge Neglect - EXPERTISE_RATING, WEAPON_RATING + -- Parry Neglect - EXPERTISE_RATING, WEAPON_RATING + -- Block Neglect - WEAPON_RATING + --------------------- + -- Composite Stats -- + --------------------- + -- Strength - STR + -- Agility - AGI + -- Stamina - STA + -- Intellect - INT + -- Spirit - SPI + -- Defense - DEFENSE_RATING + -- Weapon Skill - WEAPON_RATING + -- Expertise - EXPERTISE_RATING + --]] + if isModifierKeyDown[profileDB.showSum] and isModifierKeyDown[profileDB.showSum]() then + RatingBuster:StatSummary(tooltip, name, link, ...) + end + --------------------- + -- Repaint tooltip -- + --------------------- + tooltip:Show() +end + +--------------------------------------------------------------------------------- +-- Recursive algorithm that divides a string into pieces using the separators in separatorTable, +-- processes them separately, then joins them back together +--------------------------------------------------------------------------------- +-- text = "+24 Agility/+4 Stamina and +4 Spell Crit/+5 Spirit" +-- separatorTable = {"/", " and ", ","} +-- RatingBuster:SplitDoJoin("+24 Agility/+4 Stamina, +4 Dodge and +4 Spell Crit/+5 Spirit", {"/", " and ", ",", "%. ", " for ", "&"}) +-- RatingBuster:SplitDoJoin("+6法術傷害及5耐力", {"/", "和", ",", "。", " 持續 ", "&", "及",}) +function RatingBuster:SplitDoJoin(text, separatorTable, tooltip) + if type(separatorTable) == "table" and table.maxn(separatorTable) > 0 then + local sep = tremove(separatorTable, 1) + text = gsub(text, sep, "@") + text = {strsplit("@", text)} + local processedText = {} + local tempTable = {} + for _, t in ipairs(text) do + --self:Print(t[1]) + copyTable(tempTable, separatorTable) + tinsert(processedText, self:SplitDoJoin(t, tempTable, tooltip)) + end + -- Join text + return (gsub(strjoin("@", unpack(processedText)), "@", sep)) + else + --self:Print(cacheID) + return self:ProcessText(text, tooltip) + end +end + + +function RatingBuster:ProcessText(text, tooltip) + --self:Print(text) + -- Check if test has a matching pattern + for _, num in ipairs(L["numberPatterns"]) do + -- Convert text to lower so we don't have to worry about same ratings with different cases + local lowerText = string.lower(text) + -- Capture the stat value + local s, e, value, partialtext = strfind(lowerText, num.pattern) + if value then + -- Check and switch captures if needed + if partialtext and tonumber(partialtext) then + value, partialtext = partialtext, value + end + -- Capture the stat name + for _, stat in ipairs(L["statList"]) do + if (not partialtext and strfind(lowerText, stat.pattern)) or (partialtext and strfind(partialtext, stat.pattern)) then + value = tonumber(value) + local infoString = "" + if type(stat.id) == "number" and stat.id >= 1 and stat.id <= 26 and isModifierKeyDown[profileDB.showRatings] and isModifierKeyDown[profileDB.showRatings]() then + -------------------- + -- Combat Ratings -- + -------------------- + -- Calculate stat value + local effect, strID = StatLogic:GetEffectFromRating(value, stat.id, calcLevel) + --self:Print(reversedAmount..", "..amount..", "..v[2]..", "..RatingBuster.targetLevel)-- debug + -- If rating is resilience, add a minus sign + -- (d0.12%, p0.12%, b0.12%, m0.12%, c-0.12%) + if strID == "DODGE" and profileDB.enableAvoidanceDiminishingReturns then + infoString = format("%+.2f%%", StatLogic:GetAvoidanceGainAfterDR("DODGE", processedDodge + effect) - StatLogic:GetAvoidanceGainAfterDR("DODGE", processedDodge)) + processedDodge = processedDodge + effect + elseif strID == "PARRY" and profileDB.enableAvoidanceDiminishingReturns then + infoString = format("%+.2f%%", StatLogic:GetAvoidanceGainAfterDR("PARRY", processedParry + effect) - StatLogic:GetAvoidanceGainAfterDR("PARRY", processedParry)) + processedParry = processedParry + effect + elseif strID == "EXPERTISE" and profileDB.expBreakDown then + effect = effect * -0.25 + if profileDB.detailedConversionText then + infoString = gsub(L["$value to be Dodged/Parried"], "$value", format("%+.2f%%%%", effect)) + else + infoString = format("%+.2f%%", effect) + end + elseif stat.id >= 15 and stat.id <= 17 then -- Resilience + effect = effect * -1 + if profileDB.detailedConversionText then + infoString = gsub(L["$value to be Crit"], "$value", format("%+.2f%%%%", effect))..", "..gsub(L["$value Crit Dmg Taken"], "$value", format("%+.2f%%%%", effect * 2))..", "..gsub(L["$value DOT Dmg Taken"], "$value", format("%+.2f%%%%", effect)) + else + infoString = format("%+.2f%%", effect) + end + -- CR_HIT_MELEE = 6 + -- CR_CRIT_MELEE = 9 + -- CR_HASTE_MELEE = 18 + -- Crit and Haste conversions are the same for melee and haste, only hit is different + elseif stat.id == 6 then + if profileDB.ratingPhysical and profileDB.ratingSpell then + -- stat.id + 2 = SpellID + local effectSpell = StatLogic:GetEffectFromRating(value, stat.id + 2, calcLevel) + infoString = format("%+.2f%%, ", effect)..gsub(L["$value Spell"], "$value", format("%+.2f%%%%", effectSpell)) + elseif profileDB.ratingPhysical then + infoString = format("%+.2f%%", effect) + elseif profileDB.ratingSpell then + local effectSpell = StatLogic:GetEffectFromRating(value, stat.id + 2, calcLevel) + infoString = format("%+.2f%%", effectSpell) + end + -- CR_HASTE_MELEE = 18 + -- shamans7, paladins2, druids10, and death knights6 now receive 30% more melee haste from Haste Rating. + elseif stat.id == 18 then + if profileDB.ratingPhysical and profileDB.ratingSpell then + -- stat.id + 2 = SpellID + local effectSpell = StatLogic:GetEffectFromRating(value, stat.id + 2, calcLevel) + if effectSpell == effect then + infoString = format("%+.2f%%", effect) + else + infoString = format("%+.2f%%, ", effect)..gsub(L["$value Spell"], "$value", format("%+.2f%%%%", effectSpell)) + end + elseif profileDB.ratingPhysical then + infoString = format("%+.2f%%", effect) + elseif profileDB.ratingSpell then + local effectSpell = StatLogic:GetEffectFromRating(value, stat.id + 2, calcLevel) + infoString = format("%+.2f%%", effectSpell) + end + else + --self:Print(text..", "..tostring(effect)..", "..value..", "..stat.id..", "..calcLevel) + -- Build info string + infoString = format("%+.2f", effect) + if (stat.id > 2 and stat.id < 21) or stat.id == 25 then -- if rating is a percentage + infoString = infoString.."%" + end + end + elseif stat.id == SPELL_STAT1_NAME and isModifierKeyDown[profileDB.showStats] and isModifierKeyDown[profileDB.showStats]() then + -------------- + -- Strength -- + -------------- + local statmod = 1 + if profileDB.enableStatMods then + statmod = RatingBuster:GetStatMod("MOD_STR") + value = value * statmod + end + local infoTable = {} + if profileDB.showAPFromStr then + local mod = RatingBuster:GetStatMod("MOD_AP") + local effect = value * StatLogic:GetAPPerStr(class) * mod + if (mod ~= 1 or statmod ~= 1) and floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value AP"], "$value", format("%+.1f", effect)))) + elseif floor(abs(effect) + 0.5) > 0 then -- so we don't get +0 AP when effect < 0.5 + tinsert(infoTable, (gsub(L["$value AP"], "$value", format("%+.0f", effect)))) + end + end + if profileDB.showBlockValueFromStr then + local effect = value * StatLogic:GetBlockValuePerStr(class) * RatingBuster:GetStatMod("MOD_BLOCK_VALUE") + if floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value Block"], "$value", format("%+.1f", effect)))) + end + end + -- Shaman: Mental Quickness (Rank 3) - 2,15 + -- Paladin: Sheath of Light + if profileDB.showSpellDmgFromStr then + local mod = RatingBuster:GetStatMod("MOD_AP") * RatingBuster:GetStatMod("MOD_SPELL_DMG") + local effect = (value * StatLogic:GetAPPerStr(class) * RatingBuster:GetStatMod("ADD_SPELL_DMG_MOD_AP") + + value * RatingBuster:GetStatMod("ADD_SPELL_DMG_MOD_STR")) * mod + if (mod ~= 1 or statmod ~= 1) and floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value Dmg"], "$value", format("%+.1f", effect)))) + elseif floor(abs(effect) + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value Dmg"], "$value", format("%+.0f", effect)))) + end + end + -- Shaman: Mental Quickness (Rank 3) - 2,15 + -- Paladin: Sheath of Light + if profileDB.showHealingFromStr then + local mod = RatingBuster:GetStatMod("MOD_AP") * RatingBuster:GetStatMod("MOD_HEAL") + local effect = (value * StatLogic:GetAPPerStr(class) * RatingBuster:GetStatMod("ADD_HEAL_MOD_AP") + + value * RatingBuster:GetStatMod("ADD_HEAL_MOD_STR")) * mod + if (mod ~= 1 or statmod ~= 1) and floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value Heal"], "$value", format("%+.1f", effect)))) + elseif floor(abs(effect) + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value Heal"], "$value", format("%+.0f", effect)))) + end + end + if profileDB.showParryFromStr then -- Death Knight: Forceful Deflection - Passive + local rating = value * RatingBuster:GetStatMod("ADD_PARRY_RATING_MOD_STR") + local effect = StatLogic:GetEffectFromRating(rating, 4, calcLevel) + if profileDB.enableAvoidanceDiminishingReturns then + local effectNoDR = effect + effect = StatLogic:GetAvoidanceGainAfterDR("PARRY", processedParry + effect) - StatLogic:GetAvoidanceGainAfterDR("PARRY", processedParry) + processedParry = processedParry + effectNoDR + end + if effect > 0 then + tinsert(infoTable, (gsub(L["$value% Parry"], "$value", format("%+.2f", effect)))) + end + else + local rating = value * RatingBuster:GetStatMod("ADD_PARRY_RATING_MOD_STR") + local effect = StatLogic:GetEffectFromRating(rating, 4, calcLevel) + processedParry = processedParry + effect + end + infoString = strjoin(", ", unpack(infoTable)) + elseif stat.id == SPELL_STAT2_NAME and isModifierKeyDown[profileDB.showStats] and isModifierKeyDown[profileDB.showStats]() then + ------------- + -- Agility -- + ------------- + local statmod = 1 + if profileDB.enableStatMods then + statmod = RatingBuster:GetStatMod("MOD_AGI") + value = value * statmod + end + local infoTable = {} + if profileDB.showAPFromAgi then + local mod = RatingBuster:GetStatMod("MOD_AP") + local effect = value * StatLogic:GetAPPerAgi(class) * mod + if (mod ~= 1 or statmod ~= 1) and floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value AP"], "$value", format("%+.1f", effect)))) + elseif floor(abs(effect) + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value AP"], "$value", format("%+.0f", effect)))) + end + end + if profileDB.showRAPFromAgi then + local mod = RatingBuster:GetStatMod("MOD_RANGED_AP") + local effect = value * StatLogic:GetRAPPerAgi(class) * mod + if (mod ~= 1 or statmod ~= 1) and floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value RAP"], "$value", format("%+.1f", effect)))) + elseif floor(abs(effect) + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value RAP"], "$value", format("%+.0f", effect)))) + end + end + if profileDB.showCritFromAgi then + local effect = StatLogic:GetCritFromAgi(value, class, calcLevel) + if effect > 0 then + tinsert(infoTable, (gsub(L["$value% Crit"], "$value", format("%+.2f", effect)))) + end + end + if profileDB.showDodgeFromAgi and (calcLevel == playerLevel) then + local effect = StatLogic:GetDodgeFromAgi(value) + if profileDB.enableAvoidanceDiminishingReturns then + local effectNoDR = effect + effect = StatLogic:GetAvoidanceGainAfterDR("DODGE", processedDodge + effect) - StatLogic:GetAvoidanceGainAfterDR("DODGE", processedDodge) + processedDodge = processedDodge + effectNoDR + end + if effect > 0 then + tinsert(infoTable, (gsub(L["$value% Dodge"], "$value", format("%+.2f", effect)))) + end + else + local effect = StatLogic:GetDodgeFromAgi(value) + processedDodge = processedDodge + effect + end + if profileDB.showArmorFromAgi then + local effect = value * 2 + if effect > 0 then + tinsert(infoTable, (gsub(L["$value Armor"], "$value", format("%+.0f", effect)))) + end + end + if profileDB.showHealingFromAgi then + local mod = RatingBuster:GetStatMod("MOD_HEAL") + local effect = value * RatingBuster:GetStatMod("ADD_HEAL_MOD_AGI") * mod + if floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value Heal"], "$value", format("%+.1f", effect)))) + end + end + infoString = strjoin(", ", unpack(infoTable)) + elseif stat.id == SPELL_STAT3_NAME and isModifierKeyDown[profileDB.showStats] and isModifierKeyDown[profileDB.showStats]() then + ------------- + -- Stamina -- + ------------- + local statmod = 1 + if profileDB.enableStatMods then + statmod = RatingBuster:GetStatMod("MOD_STA") + value = value * statmod + end + local infoTable = {} + if profileDB.showHealthFromSta then + local mod = RatingBuster:GetStatMod("MOD_HEALTH") + local effect = value * 10 * mod -- 10 Health per Sta + if (mod ~= 1 or statmod ~= 1) and floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value HP"], "$value", format("%+.1f", effect)))) + elseif floor(abs(effect) + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value HP"], "$value", format("%+.0f", effect)))) + end + end + -- "ADD_SPELL_DMG_MOD_AP" -- Warlock: Demonic Knowledge + if profileDB.showSpellDmgFromSta then + local mod = RatingBuster:GetStatMod("MOD_SPELL_DMG") + local effect = value * mod * (RatingBuster:GetStatMod("ADD_SPELL_DMG_MOD_STA") + + RatingBuster:GetStatMod("ADD_SPELL_DMG_MOD_PET_STA") * RatingBuster:GetStatMod("ADD_PET_STA_MOD_STA")) + if floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value Dmg"], "$value", format("%+.1f", effect)))) + end + end + -- "ADD_HEAL_MOD_STA" -- Warlock: Demonic Knowledge + if profileDB.showHealingFromSta then + local mod = RatingBuster:GetStatMod("MOD_HEAL") + local effect = value * RatingBuster:GetStatMod("ADD_HEAL_MOD_STA") * mod + if floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value Heal"], "$value", format("%+.1f", effect)))) + end + end + -- "ADD_AP_MOD_STA" -- Hunter: Hunter vs. Wild + if profileDB.showAPFromSta then + local mod = RatingBuster:GetStatMod("MOD_AP") + local effect = value * RatingBuster:GetStatMod("ADD_AP_MOD_STA") * mod + if (mod ~= 1 or statmod ~= 1) and floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value AP"], "$value", format("%+.1f", effect)))) + elseif floor(abs(effect) + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value AP"], "$value", format("%+.0f", effect)))) + end + end + infoString = strjoin(", ", unpack(infoTable)) + elseif stat.id == SPELL_STAT4_NAME and isModifierKeyDown[profileDB.showStats] and isModifierKeyDown[profileDB.showStats]() then + --------------- + -- Intellect -- + --------------- + local statmod = 1 + if profileDB.enableStatMods then + statmod = RatingBuster:GetStatMod("MOD_INT") + value = value * statmod + end + local infoTable = {} + if profileDB.showManaFromInt then + local mod = RatingBuster:GetStatMod("MOD_MANA") + local effect = value * 15 * mod -- 15 Mana per Int + if (mod ~= 1 or statmod ~= 1) and floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value MP"], "$value", format("%+.1f", effect)))) + elseif floor(abs(effect) + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value MP"], "$value", format("%+.0f", effect)))) + end + end + if profileDB.showSpellCritFromInt then + local effect = StatLogic:GetSpellCritFromInt(value, class, calcLevel) + if effect > 0 then + tinsert(infoTable, (gsub(L["$value% Spell Crit"], "$value", format("%+.2f", effect)))) + end + end + if profileDB.showSpellDmgFromInt then + local mod = RatingBuster:GetStatMod("MOD_SPELL_DMG") + local effect = value * mod * (RatingBuster:GetStatMod("ADD_SPELL_DMG_MOD_INT") + + RatingBuster:GetStatMod("ADD_SPELL_DMG_MOD_PET_INT") * RatingBuster:GetStatMod("ADD_PET_INT_MOD_INT")) + if floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value Dmg"], "$value", format("%+.1f", effect)))) + end + end + if profileDB.showHealingFromInt then + local mod = RatingBuster:GetStatMod("MOD_HEAL") + local effect = value * RatingBuster:GetStatMod("ADD_HEAL_MOD_INT") * mod + if floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value Heal"], "$value", format("%+.1f", effect)))) + end + end + if profileDB.showMP5FromInt then + local _, int = UnitStat("player", 4) + local _, spi = UnitStat("player", 5) + local effect = value * RatingBuster:GetStatMod("ADD_MANA_REG_MOD_INT") + + (StatLogic:GetNormalManaRegenFromSpi(spi, int + value, calcLevel) + - StatLogic:GetNormalManaRegenFromSpi(spi, int, calcLevel)) * RatingBuster:GetStatMod("ADD_MANA_REG_MOD_MANA_REG_NOT_CASTING") + + value * 15 * RatingBuster:GetStatMod("MOD_MANA") * RatingBuster:GetStatMod("ADD_MANA_REG_MOD_MANA") -- Replenishment + if floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value MP5"], "$value", format("%+.1f", effect)))) + end + end + if profileDB.showMP5NCFromInt then + local _, int = UnitStat("player", 4) + local _, spi = UnitStat("player", 5) + local effect = value * RatingBuster:GetStatMod("ADD_MANA_REG_MOD_INT") + + StatLogic:GetNormalManaRegenFromSpi(spi, int + value, calcLevel) + - StatLogic:GetNormalManaRegenFromSpi(spi, int, calcLevel) + + value * 15 * RatingBuster:GetStatMod("MOD_MANA") * RatingBuster:GetStatMod("ADD_MANA_REG_MOD_MANA") + if floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value MP5(NC)"], "$value", format("%+.1f", effect)))) + end + end + if profileDB.showRAPFromInt then + local mod = RatingBuster:GetStatMod("MOD_RANGED_AP") + local effect = value * RatingBuster:GetStatMod("ADD_RANGED_AP_MOD_INT") * mod + if floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value RAP"], "$value", format("%+.1f", effect)))) + end + end + if profileDB.showArmorFromInt then + local effect = value * RatingBuster:GetStatMod("ADD_ARMOR_MOD_INT") + if floor(abs(effect) + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value Armor"], "$value", format("%+.0f", effect)))) + end + end + -- "ADD_AP_MOD_INT" -- Shaman: Mental Dexterity + if profileDB.showAPFromInt then + local mod = RatingBuster:GetStatMod("MOD_AP") + local effect = value * RatingBuster:GetStatMod("ADD_AP_MOD_INT") * mod + if (mod ~= 1 or statmod ~= 1) and floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value AP"], "$value", format("%+.1f", effect)))) + elseif floor(abs(effect) + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value AP"], "$value", format("%+.0f", effect)))) + end + end + infoString = strjoin(", ", unpack(infoTable)) + elseif stat.id == SPELL_STAT5_NAME and isModifierKeyDown[profileDB.showStats] and isModifierKeyDown[profileDB.showStats]() then + ------------ + -- Spirit -- + ------------ + local statmod = 1 + if profileDB.enableStatMods then + statmod = RatingBuster:GetStatMod("MOD_SPI") + value = value * statmod + end + local infoTable = {} + if profileDB.showMP5FromSpi then + local mod = RatingBuster:GetStatMod("ADD_MANA_REG_MOD_MANA_REG_NOT_CASTING") + local effect = StatLogic:GetNormalManaRegenFromSpi(value, nil, calcLevel) * mod + if floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value MP5"], "$value", format("%+.1f", effect)))) + end + end + if profileDB.showMP5NCFromSpi then + local effect = StatLogic:GetNormalManaRegenFromSpi(value, nil, calcLevel) + if floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value MP5(NC)"], "$value", format("%+.1f", effect)))) + end + end + if profileDB.showHP5FromSpi then + local effect = StatLogic:GetHealthRegenFromSpi(value, class) + if floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value HP5"], "$value", format("%+.1f", effect)))) + end + end + if profileDB.showSpellDmgFromSpi then + local mod = RatingBuster:GetStatMod("MOD_SPELL_DMG") + local effect = value * (RatingBuster:GetStatMod("ADD_SPELL_DMG_MOD_SPI")) * mod + if floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value Dmg"], "$value", format("%+.1f", effect)))) + end + end + if profileDB.showHealingFromSpi then + local mod = RatingBuster:GetStatMod("MOD_HEAL") + local effect = value * RatingBuster:GetStatMod("ADD_HEAL_MOD_SPI") * mod + if floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value Heal"], "$value", format("%+.1f", effect)))) + end + end + if profileDB.showSpellCritFromSpi then + local mod = RatingBuster:GetStatMod("ADD_SPELL_CRIT_RATING_MOD_SPI") + local effect = StatLogic:GetEffectFromRating(value * mod, CR_CRIT_SPELL, calcLevel) + if effect > 0 then + tinsert(infoTable, (gsub(L["$value% Spell Crit"], "$value", format("%+.2f", effect)))) + end + end + infoString = strjoin(", ", unpack(infoTable)) + elseif profileDB.showAPFromArmor and stat.id == ARMOR and isModifierKeyDown[profileDB.showStats] and isModifierKeyDown[profileDB.showStats]() then + ----------- + -- Armor -- + ----------- + local statmod = 1 + if profileDB.enableStatMods then + local finalArmor = StatLogic:GetFinalArmor(tooltip, lowerText) + if finalArmor then + value = finalArmor + end + end + local infoTable = {} + --if profileDB.showAPFromArmor then + local effect = value * RatingBuster:GetStatMod("ADD_AP_MOD_ARMOR") * RatingBuster:GetStatMod("MOD_AP") + if floor(abs(effect) * 10 + 0.5) > 0 then + tinsert(infoTable, (gsub(L["$value AP"], "$value", format("%+.1f", effect)))) + end + --end + infoString = strjoin(", ", unpack(infoTable)) + end + if infoString ~= "" then + -- Add parenthesis + infoString = "("..infoString..")" + -- Add Color + if profileDB.enableTextColor then + infoString = profileDB.textColor.hex..infoString..currentColorCode + end + -- Build replacement string + if num.addInfo == "AfterNumber" then -- Add after number + infoString = gsub(infoString, "%%", "%%%%%%%%") -- sub "%" with "%%%%" + infoString = gsub(strsub(text, s, e), "%d+", "%0 "..infoString, 1) -- sub "33" with "33 (3.33%)" + else -- Add after stat + infoString = gsub(infoString, "%%", "%%%%") + s, e = strfind(lowerText, stat.pattern) + infoString = "%0 "..infoString + end + -- Insert info into text + RusLocalstr = gsub(strsub(text, s, e),"%(","%%(") + RusLocalstr = gsub(RusLocalstr,"%)","%%)") + --RatingBuster:Print("Итоговая строка состоит из " .. text .. " в котором " .. strsub(text, s, e) .. " меняется на " .. infoString ..", в итоге " .. gsub(text, RusLocalstr, infoString, 1)) + --RatingBuster:Print(RusLocalstr) + --RatingBuster:Print("-----------------------") + return (gsub(text, RusLocalstr, infoString, 1)) -- because gsub has 2 return values, but we only want 1 + end + return text + end + end + end + end + return text +end + + +-- Color Numbers +local GREEN_FONT_COLOR_CODE = GREEN_FONT_COLOR_CODE -- "|cff20ff20" Green +local HIGHLIGHT_FONT_COLOR_CODE = HIGHLIGHT_FONT_COLOR_CODE -- "|cffffffff" White +local RED_FONT_COLOR_CODE = RED_FONT_COLOR_CODE -- "|cffffffff" White +local FONT_COLOR_CODE_CLOSE = FONT_COLOR_CODE_CLOSE -- "|r" +local function colorNum(text, num) + if num > 0 then + return GREEN_FONT_COLOR_CODE..text..FONT_COLOR_CODE_CLOSE + elseif num < 0 then + return RED_FONT_COLOR_CODE..text..FONT_COLOR_CODE_CLOSE + else + return HIGHLIGHT_FONT_COLOR_CODE..text..FONT_COLOR_CODE_CLOSE + end +end + +local armorTypes = { + [BI["Plate"]] = "sumIgnorePlate", + [BI["Mail"]] = "sumIgnoreMail", + [BI["Leather"]] = "sumIgnoreLeather", + [BI["Cloth"]] = "sumIgnoreCloth", +} + +-- Acts as a cache so we only need to check text color once +local canUseItemType = { +} + +-- Druid: Predatory Strikes 2,10: Increases 7%/14%/20% of any attack power on your equipped weapon. +local weaponItemEquipLoc = { + ["INVTYPE_WEAPON"] = true, + ["INVTYPE_2HWEAPON"] = true, + ["INVTYPE_WEAPONMAINHAND"] = true, + ["INVTYPE_WEAPONOFFHAND"] = true, +} + +local summaryCalcData = { + ----------- + -- Basic -- + ----------- + -- Strength - STR + { + option = "sumStr", + name = "STR", + func = function(sum, sumType, link) return sum["STR"] end, + }, + -- Agility - AGI + { + option = "sumAgi", + name = "AGI", + func = function(sum, sumType, link) return sum["AGI"] end, + }, + -- Stamina - STA + { + option = "sumSta", + name = "STA", + func = function(sum, sumType, link) return sum["STA"] end, + }, + -- Health - HEALTH, STA + { + option = "sumHP", + name = "HEALTH", + func = function(sum, sumType, link) return ((sum["HEALTH"] or 0) + (sum["STA"] * 10)) * RatingBuster:GetStatMod("MOD_HEALTH") end, + }, + -- Intellect - INT + { + option = "sumInt", + name = "INT", + func = function(sum, sumType, link) return sum["INT"] end, + }, + -- Mana - MANA, INT + { + option = "sumMP", + name = "MANA", + func = function(sum, sumType, link) return ((sum["MANA"] or 0) + (sum["INT"] * 15)) * RatingBuster:GetStatMod("MOD_MANA") end, + }, + -- Spirit - SPI + { + option = "sumSpi", + name = "SPI", + func = function(sum, sumType, link) return sum["SPI"] end, + }, + -- Health Regen - HEALTH_REG + { + option = "sumHP5", + name = "HEALTH_REG", + func = function(sum, sumType, link) return (sum["HEALTH_REG"] or 0) end, + }, + -- Health Regen while Out of Combat - HEALTH_REG, SPI + { + option = "sumHP5OC", + name = "HEALTH_REG_OUT_OF_COMBAT", + func = function(sum, sumType, link) return (sum["HEALTH_REG"] or 0) + StatLogic:GetHealthRegenFromSpi(sum["SPI"], class) end, + }, + -- Mana Regen - MANA_REG, SPI, INT + { + option = "sumMP5", + name = "MANA_REG", + func = function(sum, sumType, link) + local _, int = UnitStat("player", 4) + local _, spi = UnitStat("player", 5) + return (sum["MANA_REG"] or 0) + + (sum["INT"] * RatingBuster:GetStatMod("ADD_MANA_REG_MOD_INT")) + + (StatLogic:GetNormalManaRegenFromSpi(spi + sum["SPI"], int + sum["INT"], calcLevel) + - StatLogic:GetNormalManaRegenFromSpi(spi, int, calcLevel)) * RatingBuster:GetStatMod("ADD_MANA_REG_MOD_MANA_REG_NOT_CASTING") + + summaryFunc["MANA"](sum, sumType, link) * RatingBuster:GetStatMod("ADD_MANA_REG_MOD_MANA") + end, + }, + -- Mana Regen while Not casting - MANA_REG, SPI, INT + { + option = "sumMP5NC", + name = "MANA_REG_NOT_CASTING", + func = function(sum, sumType, link) + local _, int = UnitStat("player", 4) + local _, spi = UnitStat("player", 5) + return (sum["MANA_REG"] or 0) + + (sum["INT"] * RatingBuster:GetStatMod("ADD_MANA_REG_MOD_INT")) + + StatLogic:GetNormalManaRegenFromSpi(spi + sum["SPI"], int + sum["INT"], calcLevel) + - StatLogic:GetNormalManaRegenFromSpi(spi, int, calcLevel) + + summaryFunc["MANA"](sum, sumType, link) * RatingBuster:GetStatMod("ADD_MANA_REG_MOD_MANA") + end, + }, + --------------------- + -- Physical Damage -- + --------------------- + -- Attack Power - AP, STR, AGI. + -- "ADD_AP_MOD_STA" -- Hunter: Hunter vs. Wild + -- "ADD_AP_MOD_ARMOR" -- Death Knight: Bladed Armor + -- "ADD_AP_MOD_INT" -- Shaman: Mental Dexterity + { + option = "sumAP", + name = "AP", + func = function(sum, sumType, link) + local ap = (sum["AP"] or 0) + + (sum["STR"] * StatLogic:GetAPPerStr(class)) + + (sum["AGI"] * StatLogic:GetAPPerAgi(class)) + if RatingBuster:GetStatMod("ADD_AP_MOD_STA") ~= 0 then + ap = ap + (sum["STA"] * RatingBuster:GetStatMod("ADD_AP_MOD_STA")) + end + if RatingBuster:GetStatMod("ADD_AP_MOD_ARMOR") ~= 0 then + ap = ap + (summaryFunc["ARMOR"](sum, sumType, link) * RatingBuster:GetStatMod("ADD_AP_MOD_ARMOR")) + end + if RatingBuster:GetStatMod("ADD_AP_MOD_INT") ~= 0 then + ap = ap + (sum["INT"] * RatingBuster:GetStatMod("ADD_AP_MOD_INT")) + end + -- Druid: Predatory Strikes 2,10: Increases 7%/14%/20% of any attack power on your equipped weapon. + local p = 0 + if class == "DRUID" and select(5, GetTalentInfo(2, 10)) > 0 and weaponItemEquipLoc[select(9, GetItemInfo(link))] then + local r = select(5, GetTalentInfo(2, 10)) + if r == 1 then + p = 0.07 + elseif r == 2 then + p = 0.14 + elseif r == 3 then + p = 0.2 + end + end + local mod = RatingBuster:GetStatMod("MOD_AP") + p + return ap * mod + end, + }, + -- Ranged Attack Power - RANGED_AP, AP, AGI, INT + { + option = "sumRAP", + name = "RANGED_AP", + func = function(sum, sumType, link) + local rap = (sum["RANGED_AP"] or 0) + + (sum["AP"] or 0) + + (sum["AGI"] * StatLogic:GetRAPPerAgi(class)) + if RatingBuster:GetStatMod("ADD_RANGED_AP_MOD_INT") ~= 0 then + rap = rap + (sum["INT"] * RatingBuster:GetStatMod("ADD_RANGED_AP_MOD_INT")) + end + if RatingBuster:GetStatMod("ADD_AP_MOD_STA") ~= 0 then + rap = rap + (sum["STA"] * RatingBuster:GetStatMod("ADD_AP_MOD_STA")) + end + if RatingBuster:GetStatMod("ADD_AP_MOD_ARMOR") ~= 0 then + rap = rap + (summaryFunc["ARMOR"](sum, sumType, link) * RatingBuster:GetStatMod("ADD_AP_MOD_ARMOR")) + end + if RatingBuster:GetStatMod("ADD_AP_MOD_INT") ~= 0 then + rap = rap + (sum["INT"] * RatingBuster:GetStatMod("ADD_AP_MOD_INT")) + end + return rap * (RatingBuster:GetStatMod("MOD_RANGED_AP") + RatingBuster:GetStatMod("MOD_AP") - 1) + end, + }, + -- Feral Attack Power - FERAL_AP, AP, STR, AGI + { + option = "sumFAP", + name = "FERAL_AP", + func = function(sum, sumType, link) + -- Druid: Predatory Strikes 2,10: Increases 7%/14%/20% of any attack power on your equipped weapon. + local p = 0 + if class == "DRUID" and select(5, GetTalentInfo(2, 10)) > 0 and weaponItemEquipLoc[select(9, GetItemInfo(link))] then + local r = select(5, GetTalentInfo(2, 10)) + if r == 1 then + p = 0.07 + elseif r == 2 then + p = 0.14 + elseif r == 3 then + p = 0.2 + end + end + local mod = RatingBuster:GetStatMod("MOD_AP") + p + local fap = summaryFunc["AP"](sum, sumType, link) + (sum["FERAL_AP"] or 0) * mod + return fap + end, + }, + -- Hit Chance - MELEE_HIT_RATING + { + option = "sumHit", + name = "MELEE_HIT", + func = function(sum, sumType, link) + local s = 0 + return s + StatLogic:GetEffectFromRating((sum["MELEE_HIT_RATING"] or 0), "MELEE_HIT_RATING", calcLevel) + end, + ispercent = true, + }, + -- Hit Rating - MELEE_HIT_RATING + { + option = "sumHitRating", + name = "MELEE_HIT_RATING", + func = function(sum, sumType, link) return (sum["MELEE_HIT_RATING"] or 0) end, + }, + -- Ranged Hit Chance - MELEE_HIT_RATING, RANGED_HIT_RATING + { + option = "sumRangedHit", + name = "RANGED_HIT", + func = function(sum, sumType, link) + local s = 0 + return s + StatLogic:GetEffectFromRating((sum["MELEE_HIT_RATING"] or 0), "MELEE_HIT_RATING", calcLevel) + + StatLogic:GetEffectFromRating((sum["RANGED_HIT_RATING"] or 0), "RANGED_HIT_RATING", calcLevel) + end, + ispercent = true, + }, + -- Ranged Hit Rating - MELEE_HIT_RATING, RANGED_HIT_RATING + { + option = "sumRangedHitRating", + name = "RANGED_HIT_RATING", + func = function(sum, sumType, link) return (sum["MELEE_HIT_RATING"] or 0) + (sum["RANGED_HIT_RATING"] or 0) end, + }, + -- Crit Chance - MELEE_CRIT_RATING, AGI + { + option = "sumCrit", + name = "MELEE_CRIT", + func = function(sum, sumType, link) + local s = 0 + return s + StatLogic:GetEffectFromRating((sum["MELEE_CRIT_RATING"] or 0), "MELEE_CRIT_RATING", calcLevel) + + StatLogic:GetCritFromAgi(sum["AGI"], class, calcLevel) + end, + ispercent = true, + }, + -- Crit Rating - MELEE_CRIT_RATING + { + option = "sumCritRating", + name = "MELEE_CRIT_RATING", + func = function(sum, sumType, link) return (sum["MELEE_CRIT_RATING"] or 0) end, + }, + -- Ranged Crit Chance - MELEE_CRIT_RATING, AGI, RANGED_CRIT_RATING + { + option = "sumRangedCrit", + name = "RANGED_CRIT", + func = function(sum, sumType, link) + local s = 0 + return s + StatLogic:GetEffectFromRating((sum["MELEE_CRIT_RATING"] or 0), "MELEE_CRIT_RATING", calcLevel) + + StatLogic:GetEffectFromRating((sum["RANGED_CRIT_RATING"] or 0), "RANGED_CRIT_RATING", calcLevel) + + StatLogic:GetCritFromAgi(sum["AGI"], class, calcLevel) + end, + ispercent = true, + }, + -- Ranged Crit Rating - MELEE_CRIT_RATING, RANGED_CRIT_RATING + { + option = "sumRangedCritRating", + name = "RANGED_CRIT_RATING", + func = function(sum, sumType, link) return (sum["MELEE_CRIT_RATING"] or 0) + (sum["RANGED_CRIT_RATING"] or 0) end, + }, + -- Haste - MELEE_HASTE_RATING + { + option = "sumHaste", + name = "MELEE_HASTE", + func = function(sum, sumType, link) return StatLogic:GetEffectFromRating((sum["MELEE_HASTE_RATING"] or 0), "MELEE_HASTE_RATING", calcLevel) end, + ispercent = true, + }, + -- Haste Rating - MELEE_HASTE_RATING + { + option = "sumHasteRating", + name = "MELEE_HASTE_RATING", + func = function(sum, sumType, link) return (sum["MELEE_HASTE_RATING"] or 0) end, + }, + -- Ranged Haste - MELEE_HASTE_RATING, RANGED_HASTE_RATING + { + option = "sumRangedHaste", + name = "RANGED_HASTE", + func = function(sum, sumType, link) + return StatLogic:GetEffectFromRating((sum["MELEE_HASTE_RATING"] or 0), "MELEE_HASTE_RATING", calcLevel) + + StatLogic:GetEffectFromRating((sum["RANGED_HASTE_RATING"] or 0), "RANGED_HASTE_RATING", calcLevel) + end, + ispercent = true, + }, + -- Ranged Haste Rating - MELEE_HASTE_RATING, RANGED_HASTE_RATING + { + option = "sumRangedHasteRating", + name = "RANGED_HASTE_RATING", + func = function(sum, sumType, link) return (sum["MELEE_HASTE_RATING"] or 0) + (sum["RANGED_HASTE_RATING"] or 0) end, + }, + -- Expertise - EXPERTISE_RATING + { + option = "sumExpertise", + name = "EXPERTISE", + func = function(sum, sumType, link) return StatLogic:GetEffectFromRating((sum["EXPERTISE_RATING"] or 0), "EXPERTISE_RATING", calcLevel) end, + }, + -- Expertise Rating - EXPERTISE_RATING + { + option = "sumExpertiseRating", + name = "EXPERTISE_RATING", + func = function(sum, sumType, link) return (sum["EXPERTISE_RATING"] or 0) end, + }, + -- Mastery - MASTERY_RATING + { + option = "sumMastery", + name = "MASTERY", + func = function(sum, sumType, link) return StatLogic:GetEffectFromRating((sum["MASTERY_RATING"] or 0), "MASTERY_RATING", calcLevel) end, + }, + -- Mastery Rating - MASTERY_RATING + { + option = "sumMasteryRating", + name = "MASTERY_RATING", + func = function(sum, sumType, link) return (sum["MASTERY_RATING"] or 0) end, + }, + -- Dodge Neglect - EXPERTISE_RATING + { + option = "sumDodgeNeglect", + name = "DODGE_NEGLECT", + func = function(sum, sumType, link) + local s = StatLogic:GetEffectFromRating((sum["EXPERTISE_RATING"] or 0), "EXPERTISE_RATING", calcLevel) * 0.25 + return s + end, + ispercent = true, + }, + -- Parry Neglect - EXPERTISE_RATING + { + option = "sumParryNeglect", + name = "PARRY_NEGLECT", + func = function(sum, sumType, link) + local s = StatLogic:GetEffectFromRating((sum["EXPERTISE_RATING"] or 0), "EXPERTISE_RATING", calcLevel) * 0.25 + return s + end, + ispercent = true, + }, + -- Weapon Max Damage - MAX_DAMAGE + { + option = "sumWeaponMaxDamage", + name = "MAX_DAMAGE", + func = function(sum, sumType, link) return (sum["MAX_DAMAGE"] or 0) end, + }, + ------------------------------ + -- Spell Damage and Healing -- + ------------------------------ + -- Spell Damage - SPELL_DMG, ADD_SPELL_DMG_MOD_STA, ADD_SPELL_DMG_MOD_INT, ADD_SPELL_DMG_MOD_SPI, ADD_SPELL_DMG_MOD_AP + { + option = "sumSpellDmg", + name = "SPELL_DMG", + func = function(sum, sumType, link) + local spellDmg = (sum["SPELL_DMG"] or 0) + if RatingBuster:GetStatMod("ADD_SPELL_DMG_MOD_STR") ~= 0 then + spellDmg = spellDmg + (sum["STR"] * RatingBuster:GetStatMod("ADD_SPELL_DMG_MOD_STR")) + end + if RatingBuster:GetStatMod("ADD_SPELL_DMG_MOD_STA") ~= 0 then + spellDmg = spellDmg + (sum["STA"] * RatingBuster:GetStatMod("ADD_SPELL_DMG_MOD_STA")) + end + if RatingBuster:GetStatMod("ADD_SPELL_DMG_MOD_INT") ~= 0 then + spellDmg = spellDmg + (sum["INT"] * RatingBuster:GetStatMod("ADD_SPELL_DMG_MOD_INT")) + end + if RatingBuster:GetStatMod("ADD_SPELL_DMG_MOD_SPI") ~= 0 then + spellDmg = spellDmg + (sum["SPI"] * RatingBuster:GetStatMod("ADD_SPELL_DMG_MOD_SPI")) + end + if RatingBuster:GetStatMod("ADD_SPELL_DMG_MOD_AP") ~= 0 then + spellDmg = spellDmg + (summaryFunc["AP"](sum, sumType, link) * RatingBuster:GetStatMod("ADD_SPELL_DMG_MOD_AP")) + end + if RatingBuster:GetStatMod("ADD_PET_STA_MOD_STA") ~= 0 then + spellDmg = spellDmg + (sum["STA"] * RatingBuster:GetStatMod("ADD_SPELL_DMG_MOD_PET_STA") * RatingBuster:GetStatMod("ADD_PET_STA_MOD_STA")) + spellDmg = spellDmg + (sum["INT"] * RatingBuster:GetStatMod("ADD_SPELL_DMG_MOD_PET_INT") * RatingBuster:GetStatMod("ADD_PET_INT_MOD_INT")) + end + return spellDmg * RatingBuster:GetStatMod("MOD_SPELL_DMG") + end, + }, + -- Holy Damage - HOLY_SPELL_DMG, SPELL_DMG, + { + option = "sumHolyDmg", + name = "HOLY_SPELL_DMG", + func = function(sum, sumType, link) + return summaryFunc["SPELL_DMG"](sum, sumType, link) + + ((sum["HOLY_SPELL_DMG"] or 0)) + * RatingBuster:GetStatMod("MOD_SPELL_DMG") + end, + }, + -- Arcane Damage - ARCANE_SPELL_DMG, SPELL_DMG, + { + option = "sumArcaneDmg", + name = "ARCANE_SPELL_DMG", + func = function(sum, sumType, link) + return summaryFunc["SPELL_DMG"](sum, sumType, link) + + ((sum["ARCANE_SPELL_DMG"] or 0)) + * RatingBuster:GetStatMod("MOD_SPELL_DMG") + end, + }, + -- Fire Damage - FIRE_SPELL_DMG, SPELL_DMG, + { + option = "sumFireDmg", + name = "FIRE_SPELL_DMG", + func = function(sum, sumType, link) + return summaryFunc["SPELL_DMG"](sum, sumType, link) + + ((sum["FIRE_SPELL_DMG"] or 0)) + * RatingBuster:GetStatMod("MOD_SPELL_DMG") + end, + }, + -- Nature Damage - NATURE_SPELL_DMG, SPELL_DMG, + { + option = "sumNatureDmg", + name = "NATURE_SPELL_DMG", + func = function(sum, sumType, link) + return summaryFunc["SPELL_DMG"](sum, sumType, link) + + ((sum["NATURE_SPELL_DMG"] or 0)) + * RatingBuster:GetStatMod("MOD_SPELL_DMG") + end, + }, + -- Frost Damage - FROST_SPELL_DMG, SPELL_DMG, + { + option = "sumFrostDmg", + name = "FROST_SPELL_DMG", + func = function(sum, sumType, link) + return summaryFunc["SPELL_DMG"](sum, sumType, link) + + ((sum["FROST_SPELL_DMG"] or 0)) + * RatingBuster:GetStatMod("MOD_SPELL_DMG") + end, + }, + -- Shadow Damage - SHADOW_SPELL_DMG, SPELL_DMG + { + option = "sumShadowDmg", + name = "SHADOW_SPELL_DMG", + func = function(sum, sumType, link) + return summaryFunc["SPELL_DMG"](sum, sumType, link) + + ((sum["SHADOW_SPELL_DMG"] or 0)) + * RatingBuster:GetStatMod("MOD_SPELL_DMG") + end, + }, + -- Healing - HEAL, AGI, STR, INT, SPI + -- "ADD_HEAL_MOD_STR" -- Paladin: Touched by the Light + -- "ADD_HEAL_MOD_AGI" -- Druid: Nurturing Instinct + -- "ADD_HEAL_MOD_STA" + -- "ADD_HEAL_MOD_INT" + -- "ADD_HEAL_MOD_SPI" + -- "ADD_HEAL_MOD_AP" -- Shaman: Mental Quickness + { + option = "sumHealing", + name = "HEAL", + func = function(sum, sumType, link) + local heal = (sum["HEAL"] or 0) + if RatingBuster:GetStatMod("ADD_HEAL_MOD_STR") ~= 0 then + heal = heal + (sum["STR"] * RatingBuster:GetStatMod("ADD_HEAL_MOD_STR")) + end + if RatingBuster:GetStatMod("ADD_HEAL_MOD_AGI") ~= 0 then + heal = heal + (sum["AGI"] * RatingBuster:GetStatMod("ADD_HEAL_MOD_AGI")) + end + if RatingBuster:GetStatMod("ADD_HEAL_MOD_STA") ~= 0 then + heal = heal + (sum["STA"] * RatingBuster:GetStatMod("ADD_HEAL_MOD_STA")) + end + if RatingBuster:GetStatMod("ADD_HEAL_MOD_INT") ~= 0 then + heal = heal + (sum["INT"] * RatingBuster:GetStatMod("ADD_HEAL_MOD_INT")) + end + if RatingBuster:GetStatMod("ADD_HEAL_MOD_SPI") ~= 0 then + heal = heal + (sum["SPI"] * RatingBuster:GetStatMod("ADD_HEAL_MOD_SPI")) + end + if RatingBuster:GetStatMod("ADD_HEAL_MOD_AP") ~= 0 then + heal = heal + (summaryFunc["AP"](sum, sumType, link) * RatingBuster:GetStatMod("ADD_HEAL_MOD_AP")) + end + return heal * RatingBuster:GetStatMod("MOD_HEAL") + end, + }, + -- Spell Hit Chance - SPELL_HIT_RATING + { + option = "sumSpellHit", + name = "SPELL_HIT", + func = function(sum, sumType, link) return StatLogic:GetEffectFromRating((sum["SPELL_HIT_RATING"] or 0), "SPELL_HIT_RATING", calcLevel) end, + ispercent = true, + }, + -- Spell Hit Rating - SPELL_HIT_RATING + { + option = "sumSpellHitRating", + name = "SPELL_HIT_RATING", + func = function(sum, sumType, link) return (sum["SPELL_HIT_RATING"] or 0) end, + }, + -- Spell Crit Chance - SPELL_CRIT_RATING, INT + { + option = "sumSpellCrit", + name = "SPELL_CRIT", + func = function(sum, sumType, link) + return StatLogic:GetEffectFromRating((sum["SPELL_CRIT_RATING"] or 0) + sum["SPI"] * RatingBuster:GetStatMod("ADD_SPELL_CRIT_RATING_MOD_SPI"), "SPELL_CRIT_RATING", calcLevel) + + StatLogic:GetSpellCritFromInt(sum["INT"], class, calcLevel) + end, + ispercent = true, + }, + -- Spell Crit Rating - SPELL_CRIT_RATING + { + option = "sumSpellCritRating", + name = "SPELL_CRIT_RATING", + func = function(sum, sumType, link) return (sum["SPELL_CRIT_RATING"] or 0) + sum["SPI"] * RatingBuster:GetStatMod("ADD_SPELL_CRIT_RATING_MOD_SPI") end, + }, + -- Spell Haste - SPELL_HASTE_RATING + { + option = "sumSpellHaste", + name = "SPELL_HASTE", + func = function(sum, sumType, link) return StatLogic:GetEffectFromRating((sum["SPELL_HASTE_RATING"] or 0), "SPELL_HASTE_RATING", calcLevel) end, + ispercent = true, + }, + -- Spell Haste Rating - SPELL_HASTE_RATING + { + option = "sumSpellHasteRating", + name = "SPELL_HASTE_RATING", + func = function(sum, sumType, link) return (sum["SPELL_HASTE_RATING"] or 0) end, + }, + -- Spell Penetration - SPELLPEN + { + option = "sumPenetration", + name = "SPELLPEN", + func = function(sum, sumType, link) return (sum["SPELLPEN"] or 0) end, + }, + ---------- + -- Tank -- + ---------- + -- Armor - ARMOR, ARMOR_BONUS, AGI, INT + { + option = "sumArmor", + name = "ARMOR", + func = function(sum, sumType, link) + -- Bonus armor beyond the base armor of an item will no longer be multiplied, + -- this includes armor from Necks, Rings, Trinkets, Weapons + -- Commented out because StatLogic now handles this + -- local itemType = select(9, GetItemInfo(link)) + -- local mod = 1 + -- if not modFreeArmorItemEquipLoc[itemType] then + -- mod = RatingBuster:GetStatMod("MOD_ARMOR") + -- end + return (sum["ARMOR"] or 0) * RatingBuster:GetStatMod("MOD_ARMOR") + + (sum["ARMOR_BONUS"] or 0) + end, + }, + -- Dodge Chance Before DR - DODGE_RATING, AGI + { + option = "sumDodgeBeforeDR", + name = "DODGE_NO_DR", + func = function(sum, sumType, link) + local dodge = StatLogic:GetEffectFromRating((sum["DODGE_RATING"] or 0), "DODGE_RATING", calcLevel) + + StatLogic:GetDodgeFromAgi(sum["AGI"] or 0) + return dodge + end, + ispercent = true, + }, + -- Dodge Chance - DODGE_RATING, AGI + { + option = "sumDodge", + name = "DODGE", + func = function(sum, sumType, link) + local dodge = summaryFunc["DODGE_NO_DR"](sum, sumType, link) + if profileDB.enableAvoidanceDiminishingReturns then + if (sumType == "diff1") or (sumType == "diff2") then + dodge = StatLogic:GetAvoidanceGainAfterDR("DODGE", dodge) + elseif sumType == "sum" then + dodge = StatLogic:GetAvoidanceGainAfterDR("DODGE", equippedDodge + dodge) - StatLogic:GetAvoidanceGainAfterDR("DODGE", equippedDodge) + end + end + return dodge + end, + ispercent = true, + }, + -- Dodge Rating - DODGE_RATING + { + option = "sumDodgeRating", + name = "DODGE_RATING", + func = function(sum, sumType, link) return (sum["DODGE_RATING"] or 0) end, + }, + -- Parry Chance Before DR - PARRY_RATING + { + option = "sumParryBeforeDR", + name = "PARRY_NO_DR", + func = function(sum, sumType, link) + if GetParryChance() == 0 then return 0 end + local parryRating = (sum["PARRY_RATING"] or 0) + if RatingBuster:GetStatMod("ADD_PARRY_RATING_MOD_STR") ~= 0 then + if(sumType == "diff1" or sumType == "diff2") then + local str = UnitStat("player", 1) + local newStr = (sum["STR"] or 0) + str + parryRating = parryRating + floor(newStr * RatingBuster:GetStatMod("ADD_PARRY_RATING_MOD_STR")) - floor(str * RatingBuster:GetStatMod("ADD_PARRY_RATING_MOD_STR")) + else + parryRating = parryRating + (sum["STR"] or 0) * RatingBuster:GetStatMod("ADD_PARRY_RATING_MOD_STR") + end + end + local parry = StatLogic:GetEffectFromRating(parryRating, "PARRY_RATING", calcLevel) + return parry + end, + ispercent = true, + }, + -- Parry Chance - PARRY_RATING + { + option = "sumParry", + name = "PARRY", + func = function(sum, sumType, link) + local parry = summaryFunc["PARRY_NO_DR"](sum, sumType, link) + if profileDB.enableAvoidanceDiminishingReturns then + if (sumType == "diff1") or (sumType == "diff2") then + parry = StatLogic:GetAvoidanceGainAfterDR("PARRY", parry) + elseif sumType == "sum" then + parry = StatLogic:GetAvoidanceGainAfterDR("PARRY", equippedParry + parry) - StatLogic:GetAvoidanceGainAfterDR("PARRY", equippedParry) + end + end + return parry + end, + ispercent = true, + }, + -- Parry Rating - PARRY_RATING + -- "ADD_PARRY_RATING_MOD_STR" -- Death Knight: Forceful Deflection - Passive + { + option = "sumParryRating", + name = "PARRY_RATING", + func = function(sum, sumType, link) return (sum["PARRY_RATING"] or 0) + (sum["STR"] * RatingBuster:GetStatMod("ADD_PARRY_RATING_MOD_STR")) end, + }, + -- Block Chance - BLOCK_RATING + { + option = "sumBlock", + name = "BLOCK", + func = function(sum, sumType, link) + if GetBlockChance() == 0 then return 0 end + return StatLogic:GetEffectFromRating((sum["BLOCK_RATING"] or 0), "BLOCK_RATING", calcLevel) + end, + ispercent = true, + }, + -- Block Rating - BLOCK_RATING + { + option = "sumBlockRating", + name = "BLOCK_RATING", + func = function(sum, sumType, link) return (sum["BLOCK_RATING"] or 0) end, + }, + -- Hit Avoidance Before DR - MELEE_HIT_AVOID_RATING + { + option = "sumHitAvoidBeforeDR", + name = "MELEE_HIT_AVOID_NO_DR", + func = function(sum, sumType, link) return StatLogic:GetEffectFromRating((sum["MELEE_HIT_AVOID_RATING"] or 0), "MELEE_HIT_AVOID_RATING", calcLevel) end, + ispercent = true, + }, + -- Hit Avoidance Before DR - MELEE_HIT_AVOID_RATING + { + option = "sumHitAvoid", + name = "MELEE_HIT_AVOID", + func = function(sum, sumType, link) + local missed = summaryFunc["MELEE_HIT_AVOID_NO_DR"](sum, sumType, link) + if profileDB.enableAvoidanceDiminishingReturns then + if (sumType == "diff1") or (sumType == "diff2") then + missed = StatLogic:GetAvoidanceGainAfterDR("MELEE_HIT_AVOID", missed) + elseif sumType == "sum" then + missed = StatLogic:GetAvoidanceGainAfterDR("MELEE_HIT_AVOID", equippedMissed + missed) - StatLogic:GetAvoidanceGainAfterDR("MELEE_HIT_AVOID", equippedMissed) + end + end + return missed + end, + ispercent = true, + }, + -- Crit Avoidance - RESILIENCE_RATING, MELEE_CRIT_AVOID_RATING + { + option = "sumCritAvoid", + name = "MELEE_CRIT_AVOID", + func = function(sum, sumType, link) return StatLogic:GetEffectFromRating((sum["MELEE_CRIT_AVOID_RATING"] or 0), "MELEE_CRIT_AVOID_RATING", calcLevel) + + StatLogic:GetEffectFromRating((sum["RESILIENCE_RATING"] or 0), "RESILIENCE_RATING", calcLevel) end, + ispercent = true, + }, + -- Resilience - RESILIENCE_RATING + { + option = "sumResilience", + name = "RESILIENCE_RATING", + func = function(sum, sumType, link) return (sum["RESILIENCE_RATING"] or 0) end, + }, + -- Arcane Resistance - ARCANE_RES + { + option = "sumArcaneResist", + name = "ARCANE_RES", + func = function(sum, sumType, link) return (sum["ARCANE_RES"] or 0) end, + }, + -- Fire Resistance - FIRE_RES + { + option = "sumFireResist", + name = "FIRE_RES", + func = function(sum, sumType, link) return (sum["FIRE_RES"] or 0) end, + }, + -- Nature Resistance - NATURE_RES + { + option = "sumNatureResist", + name = "NATURE_RES", + func = function(sum, sumType, link) return (sum["NATURE_RES"] or 0) end, + }, + -- Frost Resistance - FROST_RES + { + option = "sumFrostResist", + name = "FROST_RES", + func = function(sum, sumType, link) return (sum["FROST_RES"] or 0) end, + }, + -- Shadow Resistance - SHADOW_RES + { + option = "sumShadowResist", + name = "SHADOW_RES", + func = function(sum, sumType, link) return (sum["SHADOW_RES"] or 0) end, + }, + -- Avoidance - DODGE, PARRY, MELEE_HIT_AVOID, BLOCK(Optional) + { + option = "sumAvoidance", + name = "AVOIDANCE", + ispercent = true, + func = function(sum, sumType, link) + local dodge, parry, mobMiss, block + dodge = summaryFunc["DODGE"](sum, sumType, link) + parry = summaryFunc["PARRY"](sum, sumType, link) + mobMiss = summaryFunc["MELEE_HIT_AVOID"](sum, sumType, link) + block = 0 + if profileDB.sumAvoidWithBlock then + block = summaryFunc["BLOCK"](sum, sumType, link) + end + return parry + dodge + mobMiss + block + end, + ispercent = true, + }, +} +if tpSupport == true then + -- TankPoints + tinsert(summaryCalcData, { + option = "sumTankPoints", + name = "TANKPOINTS", + func = function(diffTable1, sumType) + if sumType == "sum" then return nil end + -- Item type + local itemType = diffTable1.itemType + -- Calculate current TankPoints + local tpSource = {} + local TP = TankPoints + local TPTips = TankPointsTooltips + TP:GetSourceData(tpSource, TP_MELEE) + local tpResults = {} + copyTable(tpResults, tpSource) + TP:GetTankPoints(tpResults, TP_MELEE) + -- Update if different + if floor(TP.resultsTable.tankPoints[TP_MELEE]) ~= floor(tpResults.tankPoints[TP_MELEE]) then + copyTable(TP.sourceTable, tpSource) + copyTable(TP.resultsTable, tpResults) + end + ---------------------------------------------------- + -- Calculate TP difference with 1st equipped item -- + ---------------------------------------------------- + local tpTable = {} + -- Set the forceShield arg + local forceShield + -- if not equipped shield and item is shield then force on + -- if not equipped shield and item is not shield then nil + -- if equipped shield and item is shield then nil + -- if equipped shield and item is not shield then force off + if ((diffTable1.diffItemType1 ~= "INVTYPE_SHIELD") and (diffTable1.diffItemType2 ~= "INVTYPE_SHIELD")) and (itemType == "INVTYPE_SHIELD") then + forceShield = true + elseif ((diffTable1.diffItemType1 == "INVTYPE_SHIELD") or (diffTable1.diffItemType2 == "INVTYPE_SHIELD")) and (itemType ~= "INVTYPE_SHIELD") then + forceShield = false + end + -- Get the tp table + TP:GetSourceData(tpTable, TP_MELEE, forceShield) + -- Build changes table + local changes = TPTips:BuildChanges({}, diffTable1) + -- Alter tp table + TP:AlterSourceData(tpTable, changes, forceShield) + -- Calculate TankPoints from tpTable + TP:GetTankPoints(tpTable, TP_MELEE, forceShield) + -- Calculate tp difference + local diff = floor(tpTable.tankPoints[TP_MELEE]) - floor(TP.resultsTable.tankPoints[TP_MELEE]) + + return diff + end, + }) + -- Total Reduction + tinsert(summaryCalcData, { + option = "sumTotalReduction", + name = "TOTALREDUCTION", + ispercent = true, + func = function(diffTable1, sumType) + if sumType == "sum" then return nil end + -- Item type + local itemType = diffTable1.itemType + local right + -- Calculate current TankPoints + local tpSource = {} + local TP = TankPoints + local TPTips = TankPointsTooltips + TP:GetSourceData(tpSource, TP_MELEE) + local tpResults = {} + copyTable(tpResults, tpSource) + TP:GetTankPoints(tpResults, TP_MELEE) + -- Update if different + if floor(TP.resultsTable.tankPoints[TP_MELEE]) ~= floor(tpResults.tankPoints[TP_MELEE]) then + copyTable(TP.sourceTable, tpSource) + copyTable(TP.resultsTable, tpResults) + end + ---------------------------------------------------- + -- Calculate TP difference with 1st equipped item -- + ---------------------------------------------------- + local tpTable = {} + -- Set the forceShield arg + local forceShield + -- if not equipped shield and item is shield then force on + -- if not equipped shield and item is not shield then nil + -- if equipped shield and item is shield then nil + -- if equipped shield and item is not shield then force off + if ((diffTable1.diffItemType1 ~= "INVTYPE_SHIELD") and (diffTable1.diffItemType2 ~= "INVTYPE_SHIELD")) and (itemType == "INVTYPE_SHIELD") then + forceShield = true + elseif ((diffTable1.diffItemType1 == "INVTYPE_SHIELD") or (diffTable1.diffItemType2 == "INVTYPE_SHIELD")) and (itemType ~= "INVTYPE_SHIELD") then + forceShield = false + end + -- Get the tp table + TP:GetSourceData(tpTable, TP_MELEE, forceShield) + -- Build changes table + local changes = TPTips:BuildChanges({}, diffTable1) + -- Alter tp table + TP:AlterSourceData(tpTable, changes, forceShield) + -- Calculate TankPoints from tpTable + TP:GetTankPoints(tpTable, TP_MELEE, forceShield) + -- Calculate tp difference + local diff = tpTable.totalReduction[TP_MELEE] - TP.resultsTable.totalReduction[TP_MELEE] + + return diff * 100 + end, + }) + --[[ + -- Avoidance + tinsert(summaryCalcData, { + option = "sumAvoidance", + name = "AVOIDANCE", + ispercent = true, + func = function(diffTable1) + -- Item type + local itemType = diffTable1.itemType + local right + -- Calculate current TankPoints + local tpSource = {} + local TP = TankPoints + local TPTips = TankPointsTooltips + TP:GetSourceData(tpSource, TP_MELEE) + local tpResults = {} + copyTable(tpResults, tpSource) + TP:GetTankPoints(tpResults, TP_MELEE) + -- Update if different + if floor(TP.resultsTable.tankPoints[TP_MELEE]) ~= floor(tpResults.tankPoints[TP_MELEE]) then + copyTable(TP.sourceTable, tpSource) + copyTable(TP.resultsTable, tpResults) + end + ---------------------------------------------------- + -- Calculate TP difference with 1st equipped item -- + ---------------------------------------------------- + local tpTable = {} + -- Set the forceShield arg + local forceShield + -- if not equipped shield and item is shield then force on + -- if not equipped shield and item is not shield then nil + -- if equipped shield and item is shield then nil + -- if equipped shield and item is not shield then force off + if ((diffTable1.diffItemType1 ~= "INVTYPE_SHIELD") and (diffTable1.diffItemType2 ~= "INVTYPE_SHIELD")) and (itemType == "INVTYPE_SHIELD") then + forceShield = true + elseif ((diffTable1.diffItemType1 == "INVTYPE_SHIELD") or (diffTable1.diffItemType2 == "INVTYPE_SHIELD")) and (itemType ~= "INVTYPE_SHIELD") then + forceShield = false + end + -- Get the tp table + TP:GetSourceData(tpTable, TP_MELEE, forceShield) + -- Build changes table + local changes = TPTips:BuildChanges({}, diffTable1) + -- Alter tp table + TP:AlterSourceData(tpTable, changes, forceShield) + -- Calculate TankPoints from tpTable + TP:GetTankPoints(tpTable, TP_MELEE, forceShield) + -- Calculate tp difference + local diff = tpTable.mobMissChance + tpTable.dodgeChance + tpTable.parryChance - TP.resultsTable.mobMissChance - TP.resultsTable.dodgeChance - TP.resultsTable.parryChance + + return diff * 100 + end, + }) + --]] +end + +-- Build summaryFunc +for _, calcData in pairs(summaryCalcData) do + summaryFunc[calcData.name] = calcData.func +end + + +function sumSortAlphaComp(a, b) + return a[1] < b[1] +end + +function RatingBuster:StatSummary(tooltip, name, link, ...) + -- Hide stat summary for equipped items + if profileDB.sumIgnoreEquipped and IsEquippedItem(link) then return end + + -- Show stat summary only for highest level armor type and items you can use with uncommon quality and up + if profileDB.sumIgnoreUnused then + local _, _, itemRarity, _, _, _, itemSubType, _, itemEquipLoc = GetItemInfo(link) + -- Check rarity + if not itemRarity or itemRarity < profileDB.sumMinQuality then return end + -- Check armor type + if armorTypes[itemSubType] and profileDB[armorTypes[itemSubType]] and itemEquipLoc ~= "INVTYPE_CLOAK" then + --self:Print("Check armor type", itemSubType) + return + end + -- Check for Red item types + if canUseItemType[itemSubType] == false then + return + elseif canUseItemType[itemSubType] == nil then + local tName = tooltip:GetName() + if (_G[tName.."TextRight3"]:GetText() and select(2, _G[tName.."TextRight3"]:GetTextColor()) < 0.2) or + (_G[tName.."TextRight4"]:GetText() and select(2, _G[tName.."TextRight4"]:GetTextColor()) < 0.2) or + (_G[tName.."TextRight5"]:GetText() and select(2, _G[tName.."TextRight5"]:GetTextColor()) < 0.2) or + select(2, _G[tName.."TextLeft3"]:GetTextColor()) < 0.2 or select(2, _G[tName.."TextLeft4"]:GetTextColor()) < 0.2 or + select(2, _G[tName.."TextLeft5"]:GetTextColor()) < 0.2 then + canUseItemType[itemSubType] = false + return + else + canUseItemType[itemSubType] = true + end + end + end + + -- Ignore enchants and gems on items when calculating the stat summarythen + local red, yellow, blue, meta + if isModifierKeyDown[profileDB.sumGem2Toggle] and isModifierKeyDown[profileDB.sumGem2Toggle]() then + red = profileDB.sumGemRed2.gemID + yellow = profileDB.sumGemYellow2.gemID + blue = profileDB.sumGemBlue2.gemID + meta = profileDB.sumGemMeta2.gemID + elseif isModifierKeyDown[profileDB.sumGem3Toggle] and isModifierKeyDown[profileDB.sumGem3Toggle]() then + red = profileDB.sumGemRed3.gemID + yellow = profileDB.sumGemYellow3.gemID + blue = profileDB.sumGemBlue3.gemID + meta = profileDB.sumGemMeta3.gemID + else + red = profileDB.sumGemRed.gemID + yellow = profileDB.sumGemYellow.gemID + blue = profileDB.sumGemBlue.gemID + meta = profileDB.sumGemMeta.gemID + end + + if profileDB.sumIgnoreEnchant then + link = StatLogic:RemoveEnchant(link) + end + if profileDB.sumIgnorePris then + link = StatLogic:RemoveExtraSocketGem(link) + end + if profileDB.sumIgnoreGems then + link = StatLogic:RemoveGem(link) + else + link = StatLogic:BuildGemmedTooltip(link, red, yellow, blue, meta) + end + + -- Diff Display Style + -- Main Tooltip: tooltipLevel = 0 + -- Compare Tooltip 1: tooltipLevel = 1 + -- Compare Tooltip 2: tooltipLevel = 2 + local id + local tooltipLevel = 0 + local mainTooltip = tooltip + -- Determine tooltipLevel and id + if profileDB.calcDiff and (profileDB.sumDiffStyle == "comp") then + -- Obtain main tooltip + -- Detemine tooltip level + if mainTooltip:GetOwner():GetObjectType() == "GameTooltip" then + mainTooltip = mainTooltip:GetOwner() + -- This is a comparison tooltip + local _, level = ... + if type(level) == "number" then + tooltipLevel = level + else + tooltipLevel = 1 + end + if mainTooltip:GetOwner():GetObjectType() == "GameTooltip" then + mainTooltip = mainTooltip:GetOwner() + if type(level) ~= "number" then + tooltipLevel = 2 + end + end + end + local _, mainlink = StatLogic:GetDiffID(mainTooltip, profileDB.sumIgnoreEnchant, profileDB.sumIgnoreGems, red, yellow, blue, meta, profileDB.sumIgnorePris) + if not mainlink then return end + -- Construct id + if tooltipLevel > 0 then + id = link..mainlink + else + id = "sum"..link + end + else + id = StatLogic:GetDiffID(link, profileDB.sumIgnoreEnchant, profileDB.sumIgnoreGems, red, yellow, blue, meta, profileDB.sumIgnorePris) + if not id then return end + end + + -- Check Cache + if cache[id] then + if #cache[id] == 0 then return end + -- Write Tooltip + if profileDB.sumBlankLine then + tooltip:AddLine(" ") + end + if profileDB.sumShowTitle then + tooltip:AddLine(HIGHLIGHT_FONT_COLOR_CODE..L["Stat Summary"]..FONT_COLOR_CODE_CLOSE) + if profileDB.sumShowIcon then + tooltip:AddTexture("Interface\\AddOns\\RatingBuster\\images\\Sigma") + end + end + -- local left, right = "", "" + -- for _, o in ipairs(cache[id]) do + -- left = left..o[1].."\n" + -- right = right..o[2].."\n" + -- end + -- left = strsub(left, 1, -3) + -- right = strsub(right, 1, -3) + -- tooltip:AddDoubleLine(left, right) + for _, o in ipairs(cache[id]) do + tooltip:AddDoubleLine(o[1], o[2]) + end + if profileDB.sumBlankLineAfter then + tooltip:AddLine(" ") + end + return + end + + ------------------------- + -- Build Summary Table -- + local statData = {} + statData.sum = StatLogic:GetSum(link) + if not statData.sum then return end + if not profileDB.calcSum then + statData.sum = nil + end + + -- Ignore bags + if not StatLogic:GetDiff(link) then return end + + -- Get Diff Data + if profileDB.calcDiff then + if profileDB.sumDiffStyle == "comp" then + if tooltipLevel > 0 then + statData.diff1 = select(tooltipLevel, StatLogic:GetDiff(mainTooltip, nil, nil, profileDB.sumIgnoreEnchant, profileDB.sumIgnoreGems, red, yellow, blue, meta, profileDB.sumIgnorePris)) + end + else + statData.diff1, statData.diff2 = StatLogic:GetDiff(link, nil, nil, profileDB.sumIgnoreEnchant, profileDB.sumIgnoreGems, red, yellow, blue, meta, profileDB.sumIgnorePris) + end + end + -- Apply Base Stat Mods + for _, v in pairs(statData) do + v["STR"] = (v["STR"] or 0) + v["AGI"] = (v["AGI"] or 0) + v["STA"] = (v["STA"] or 0) + v["INT"] = (v["INT"] or 0) + v["SPI"] = (v["SPI"] or 0) + end + if profileDB.enableStatMods then + for _, v in pairs(statData) do + v["STR"] = v["STR"] * RatingBuster:GetStatMod("MOD_STR") + v["AGI"] = v["AGI"] * RatingBuster:GetStatMod("MOD_AGI") + v["STA"] = v["STA"] * RatingBuster:GetStatMod("MOD_STA") + v["INT"] = v["INT"] * RatingBuster:GetStatMod("MOD_INT") + v["SPI"] = v["SPI"] * RatingBuster:GetStatMod("MOD_SPI") + end + end + -- Summary Table + --[[ + local statData = { + sum = {}, + diff1 = {}, + diff2 = {}, + } + if profileDB.sumHP then + local d = {name = "HEALTH"} + for k, sum in pairs(data) do + d[k] = ((sum["HEALTH"] or 0) + (sum["STA"] * 10)) * RatingBuster:GetStatMod("MOD_HEALTH") + end + tinsert(summary, d) + end + local summaryCalcData = { + -- Health - HEALTH, STA + sumHP = { + name = "HEALTH", + func = function(sum, sumType, link) return ((sum["HEALTH"] or 0) + (sum["STA"] * 10)) * RatingBuster:GetStatMod("MOD_HEALTH") end, + ispercent = false, + }, + } + --]] + local summary = {} + for _, calcData in pairs(summaryCalcData) do + if profileDB[calcData.option] then + local entry = { + name = calcData.name, + ispercent = calcData.ispercent, + } + for sumType, statTable in pairs(statData) do + entry[sumType] = calcData.func(statTable, sumType, link) + end + tinsert(summary, entry) + end + end + + local calcSum = profileDB.calcSum + local calcDiff = profileDB.calcDiff + + local showZeroValueStat = profileDB.showZeroValueStat + ------------------------ + -- Build Output Table -- + local output = {} + for _, t in ipairs(summary) do + local n, s, d1, d2, ispercent = t.name, t.sum, t.diff1, t.diff2, t.ispercent + local right, left + local skip + if not showZeroValueStat then + -- Don't show this line if sum, diff1, diff2 are all 0 + if (s == 0 or not s) and (d1 == 0 or not d1) and (d2 == 0 or not d2) then + skip = true + end + end + if not skip then + if calcSum and calcDiff then + local d = ((not s) or ((s - floor(s)) == 0)) and ((not d1) or ((d1 - floor(d1)) == 0)) and ((not d2) or ((d2 - floor(d2)) == 0)) + if s then + if d then + s = format("%d", s) + elseif ispercent then + s = format("%.2f%%", s) + else + s = format("%.1f", s) + end + if d1 then + if d then + d1 = colorNum(format("%+d", d1), d1) + elseif ispercent then + d1 = colorNum(format("%+.2f%%", d1), d1) + else + d1 = colorNum(format("%+.1f", d1), d1) + end + if d2 then + if d then + d2 = colorNum(format("%+d", d2), d2) + elseif ispercent then + d2 = colorNum(format("%+.2f%%", d2), d2) + else + d2 = colorNum(format("%+.1f", d2), d2) + end + right = format("%s (%s||%s)", s, d1, d2) + else + right = format("%s (%s)", s, d1) + end + else + right = s + end + else + if d1 then + if d then + d1 = colorNum(format("%+d", d1), d1) + elseif ispercent then + d1 = colorNum(format("%+.2f%%", d1), d1) + else + d1 = colorNum(format("%+.1f", d1), d1) + end + if d2 then + if d then + d2 = colorNum(format("%+d", d2), d2) + elseif ispercent then + d2 = colorNum(format("%+.2f%%", d2), d2) + else + d2 = colorNum(format("%+.1f", d2), d2) + end + right = format("(%s||%s)", d1, d2) + else + right = format("(%s)", d1) + end + end + end + elseif calcSum then + if s then + if (s - floor(s)) == 0 then + s = format("%d", s) + elseif ispercent then + s = format("%.2f%%", s) + else + s = format("%.1f", s) + end + right = s + end + elseif calcDiff then + local d = ((not d1) or (d1 - floor(d1)) == 0) and ((not d2) or ((d2 - floor(d2)) == 0)) + if d1 then + if d then + d1 = colorNum(format("%+d", d1), d1) + elseif ispercent then + d1 = colorNum(format("%+.2f%%", d1), d1) + else + d1 = colorNum(format("%+.1f", d1), d1) + end + if d2 then + if d then + d2 = colorNum(format("%+d", d2), d2) + elseif ispercent then + d2 = colorNum(format("%+.2f%%", d2), d2) + else + d2 = colorNum(format("%+.1f", d2), d2) + end + right = format("%s||%s", d1, d2) + else + right = d1 + end + end + end + if right then + if n == "TANKPOINTS" then + if tpSupport then + left = tpLocale["TankPoints"] + else + left = "TankPoints" + end + elseif n == "TOTALREDUCTION" then + if tpSupport then + left = tpLocale["Total Reduction"] + else + left = "Total Reduction" + end + else + left = StatLogic:GetStatNameFromID(n) + end + tinsert(output, {left, right}) + end + end + end + -- sort alphabetically if option enabled + if profileDB.sumSortAlpha then + tsort(output, sumSortAlphaComp) + end + -- Write cache + cache[id] = output + if #output == 0 then return end + ------------------- + -- Write Tooltip -- + if profileDB.sumBlankLine then + tooltip:AddLine(" ") + end + if profileDB.sumShowTitle then + tooltip:AddLine(HIGHLIGHT_FONT_COLOR_CODE..L["Stat Summary"]..FONT_COLOR_CODE_CLOSE) + if profileDB.sumShowIcon then + tooltip:AddTexture("Interface\\AddOns\\RatingBuster\\images\\Sigma") + end + end + for _, o in ipairs(output) do + tooltip:AddDoubleLine(o[1], o[2]) + end + if profileDB.sumBlankLineAfter then + tooltip:AddLine(" ") + end +end + + +-- RatingBuster:Bench(1000) +--------- +-- self:SplitDoJoin("+24 Agility/+4 Stamina, +4 Dodge and +4 Spell Crit/+5 Spirit", {"/", " and ", ","}) +-- 1000 times: 0.16 - 0.18 without Compost +-- 1000 times: 0.22 - 0.24 with Compost +--------- +-- RatingBuster.ProcessTooltip(ItemRefTooltip, link) +-- 1000 times: 0.31 sec - 0.7.6 +-- 1000 times: 0.29 sec - 0. +-- 1000 times: 0.24 sec - 0.8.58.0 +--------- +-- strjoin 1000000 times: 0.46 +-- .. 1000000 times: 0.27 +-------------- +function RatingBuster:Bench(k) + local t1 = GetTime() + local link = GetInventoryItemLink("player", 12) + for i = 1, k, 1 do + --------------------------------------------------------------------------- + --self:SplitDoJoin("+24 Agility/+4 Stamina, +4 Dodge and +4 Spell Crit/+5 Spirit", {"/", " and ", ","}) + --------------------------------------------------------------------------- + ItemRefTooltip:SetInventoryItem("player", 12) + RatingBuster.ProcessTooltip(ItemRefTooltip, link) + --------------------------------------------------------------------------- + --ItemRefTooltip:SetScript("OnTooltipSetItem", function(frame, ...) RatingBuster:Print("OnTooltipSetItem") end) + ---------------------------------------------------------------------- + --local h = strjoin("", "test", "123") + --local h = "test".."123" + -------------------------------------------------------------------------------- + end + return GetTime() - t1 +end diff --git a/RatingBuster/RatingBuster.toc b/RatingBuster/RatingBuster.toc new file mode 100644 index 0000000..ee86dae --- /dev/null +++ b/RatingBuster/RatingBuster.toc @@ -0,0 +1,39 @@ +## Interface: 30300 +## Title: RatingBuster +## Notes: Item stat breakdown, analysis and comparison +## Notes-zhTW: 裝備數值解析與比較 +## Author: Whitetooth +## X-eMail: hotdogee [at] gmail [dot] com +## SavedVariables: RatingBusterDB +## OptionalDeps: Ace3, LibTipHooker-1.1, LibStatLogic-1.2, UTF8, LibBabble-Inventory-3.0, LibDualSpec-1.0, TankPoints +## X-Embeds: Ace3, LibTipHooker-1.1, LibStatLogic-1.2, UTF8, LibBabble-Inventory-3.0, LibDualSpec-1.0 +## X-Category: Interface Enhancements +## X-RelSite-WoWI: 5819 +## X-RelSite-Curse: 4991 +## X-License: GPL v2 +## X-Encoding: UTF-8 +## X-Curse-Packaged-Version: r295 +## X-Curse-Project-Name: RatingBuster +## X-Curse-Project-ID: rating-buster +## X-Curse-Repository-ID: wow/rating-buster/mainline + +# Non-Ace Libraries # +UTF8\utf8data.lua +UTF8\utf8.lua + +#@no-lib-strip@ +embeds.xml +#@end-no-lib-strip@ + +# Localization Files # +RatingBuster-Locale-enUS.lua +RatingBuster-Locale-ruRU.lua +RatingBuster-Locale-zhCN.lua +RatingBuster-Locale-zhTW.lua +RatingBuster-Locale-deDE.lua +RatingBuster-Locale-frFR.lua +RatingBuster-Locale-koKR.lua +RatingBuster-Locale-esES.lua + +# Core # +RatingBuster.lua \ No newline at end of file diff --git a/RatingBuster/UTF8/utf8.lua b/RatingBuster/UTF8/utf8.lua new file mode 100644 index 0000000..86dddb0 --- /dev/null +++ b/RatingBuster/UTF8/utf8.lua @@ -0,0 +1,327 @@ +-- $Id: utf8.lua 147 2007-01-04 00:57:00Z pasta $ +-- +-- Provides UTF-8 aware string functions implemented in pure lua: +-- * string.utf8len(s) +-- * string.utf8sub(s, i, j) +-- * string.utf8reverse(s) +-- +-- If utf8data.lua (containing the lower<->upper case mappings) is loaded, these +-- additional functions are available: +-- * string.utf8upper(s) +-- * string.utf8lower(s) +-- +-- All functions behave as their non UTF-8 aware counterparts with the exception +-- that UTF-8 characters are used instead of bytes for all units. + +--[[ +Copyright (c) 2006-2007, Kyle Smith +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--]] + +-- ABNF from RFC 3629 +-- +-- UTF8-octets = *( UTF8-char ) +-- UTF8-char = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4 +-- UTF8-1 = %x00-7F +-- UTF8-2 = %xC2-DF UTF8-tail +-- UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) / +-- %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail ) +-- UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) / +-- %xF4 %x80-8F 2( UTF8-tail ) +-- UTF8-tail = %x80-BF +-- + +-- returns the number of bytes used by the UTF-8 character at byte i in s +-- also doubles as a UTF-8 character validator +local function utf8charbytes (s, i) + -- argument defaults + i = i or 1 + + -- argument checking + if type(s) ~= "string" then + error("bad argument #1 to 'utf8charbytes' (string expected, got ".. type(s).. ")") + end + if type(i) ~= "number" then + error("bad argument #2 to 'utf8charbytes' (number expected, got ".. type(i).. ")") + end + + local c = s:byte(i) + + -- determine bytes needed for character, based on RFC 3629 + -- validate byte 1 + if c > 0 and c <= 127 then + -- UTF8-1 + return 1 + + elseif c >= 194 and c <= 223 then + -- UTF8-2 + local c2 = s:byte(i + 1) + + if not c2 then + error("UTF-8 string terminated early") + end + + -- validate byte 2 + if c2 < 128 or c2 > 191 then + error("Invalid UTF-8 character") + end + + return 2 + + elseif c >= 224 and c <= 239 then + -- UTF8-3 + local c2 = s:byte(i + 1) + local c3 = s:byte(i + 2) + + if not c2 or not c3 then + error("UTF-8 string terminated early") + end + + -- validate byte 2 + if c == 224 and (c2 < 160 or c2 > 191) then + error("Invalid UTF-8 character") + elseif c == 237 and (c2 < 128 or c2 > 159) then + error("Invalid UTF-8 character") + elseif c2 < 128 or c2 > 191 then + error("Invalid UTF-8 character") + end + + -- validate byte 3 + if c3 < 128 or c3 > 191 then + error("Invalid UTF-8 character") + end + + return 3 + + elseif c >= 240 and c <= 244 then + -- UTF8-4 + local c2 = s:byte(i + 1) + local c3 = s:byte(i + 2) + local c4 = s:byte(i + 3) + + if not c2 or not c3 or not c4 then + error("UTF-8 string terminated early") + end + + -- validate byte 2 + if c == 240 and (c2 < 144 or c2 > 191) then + error("Invalid UTF-8 character") + elseif c == 244 and (c2 < 128 or c2 > 143) then + error("Invalid UTF-8 character") + elseif c2 < 128 or c2 > 191 then + error("Invalid UTF-8 character") + end + + -- validate byte 3 + if c3 < 128 or c3 > 191 then + error("Invalid UTF-8 character") + end + + -- validate byte 4 + if c4 < 128 or c4 > 191 then + error("Invalid UTF-8 character") + end + + return 4 + + else + error("Invalid UTF-8 character") + end +end + + +-- returns the number of characters in a UTF-8 string +local function utf8len (s) + -- argument checking + if type(s) ~= "string" then + error("bad argument #1 to 'utf8len' (string expected, got ".. type(s).. ")") + end + + local pos = 1 + local bytes = s:len() + local len = 0 + + while pos <= bytes and len ~= chars do + local c = s:byte(pos) + len = len + 1 + + pos = pos + utf8charbytes(s, pos) + end + + if chars ~= nil then + return pos - 1 + end + + return len +end + +-- install in the string library +if not string.utf8len then + string.utf8len = utf8len +end + + +-- functions identically to string.sub except that i and j are UTF-8 characters +-- instead of bytes +local function utf8sub (s, i, j) + -- argument defaults + j = j or -1 + + -- argument checking + if type(s) ~= "string" then + error("bad argument #1 to 'utf8sub' (string expected, got ".. type(s).. ")") + end + if type(i) ~= "number" then + error("bad argument #2 to 'utf8sub' (number expected, got ".. type(i).. ")") + end + if type(j) ~= "number" then + error("bad argument #3 to 'utf8sub' (number expected, got ".. type(j).. ")") + end + + local pos = 1 + local bytes = s:len() + local len = 0 + + -- only set l if i or j is negative + local l = (i >= 0 and j >= 0) or utf8len(s) + local startChar = (i >= 0) and i or l + i + 1 + local endChar = (j >= 0) and j or l + j + 1 + + -- can't have start before end! + if startChar > endChar then + return "" + end + + -- byte offsets to pass to string.sub + local startByte, endByte = 1, bytes + + while pos <= bytes do + len = len + 1 + + if len == startChar then + startByte = pos + end + + pos = pos + utf8charbytes(s, pos) + + if len == endChar then + endByte = pos - 1 + break + end + end + + return s:sub(startByte, endByte) +end + +-- install in the string library +if not string.utf8sub then + string.utf8sub = utf8sub +end + + +-- replace UTF-8 characters based on a mapping table +local function utf8replace (s, mapping) + -- argument checking + if type(s) ~= "string" then + error("bad argument #1 to 'utf8replace' (string expected, got ".. type(s).. ")") + end + if type(mapping) ~= "table" then + error("bad argument #2 to 'utf8replace' (table expected, got ".. type(mapping).. ")") + end + + local pos = 1 + local bytes = s:len() + local charbytes + local newstr = "" + + while pos <= bytes do + charbytes = utf8charbytes(s, pos) + local c = s:sub(pos, pos + charbytes - 1) + + newstr = newstr .. (mapping[c] or c) + + pos = pos + charbytes + end + + return newstr +end + + +-- identical to string.upper except it knows about unicode simple case conversions +local function utf8upper (s) + return utf8replace(s, utf8_lc_uc) +end + +-- install in the string library +if not string.utf8upper and utf8_lc_uc then + string.utf8upper = utf8upper +end + + +-- identical to string.lower except it knows about unicode simple case conversions +local function utf8lower (s) + return utf8replace(s, utf8_uc_lc) +end + +-- install in the string library +if not string.utf8lower and utf8_uc_lc then + string.utf8lower = utf8lower +end + + +-- identical to string.reverse except that it supports UTF-8 +local function utf8reverse (s) + -- argument checking + if type(s) ~= "string" then + error("bad argument #1 to 'utf8reverse' (string expected, got ".. type(s).. ")") + end + + local bytes = s:len() + local pos = bytes + local charbytes + local newstr = "" + + while pos > 0 do + c = s:byte(pos) + while c >= 128 and c <= 191 do + pos = pos - 1 + c = s:byte(pos) + end + + charbytes = utf8charbytes(s, pos) + + newstr = newstr .. s:sub(pos, pos + charbytes - 1) + + pos = pos - 1 + end + + return newstr +end + +-- install in the string library +if not string.utf8reverse then + string.utf8reverse = utf8reverse +end diff --git a/RatingBuster/UTF8/utf8data.lua b/RatingBuster/UTF8/utf8data.lua new file mode 100644 index 0000000..655f719 --- /dev/null +++ b/RatingBuster/UTF8/utf8data.lua @@ -0,0 +1,1860 @@ +utf8_lc_uc = { + ["a"] = "A", + ["b"] = "B", + ["c"] = "C", + ["d"] = "D", + ["e"] = "E", + ["f"] = "F", + ["g"] = "G", + ["h"] = "H", + ["i"] = "I", + ["j"] = "J", + ["k"] = "K", + ["l"] = "L", + ["m"] = "M", + ["n"] = "N", + ["o"] = "O", + ["p"] = "P", + ["q"] = "Q", + ["r"] = "R", + ["s"] = "S", + ["t"] = "T", + ["u"] = "U", + ["v"] = "V", + ["w"] = "W", + ["x"] = "X", + ["y"] = "Y", + ["z"] = "Z", + ["µ"] = "Μ", + ["à"] = "À", + ["á"] = "Á", + ["â"] = "Â", + ["ã"] = "Ã", + ["ä"] = "Ä", + ["å"] = "Å", + ["æ"] = "Æ", + ["ç"] = "Ç", + ["è"] = "È", + ["é"] = "É", + ["ê"] = "Ê", + ["ë"] = "Ë", + ["ì"] = "Ì", + ["í"] = "Í", + ["î"] = "Î", + ["ï"] = "Ï", + ["ð"] = "Ð", + ["ñ"] = "Ñ", + ["ò"] = "Ò", + ["ó"] = "Ó", + ["ô"] = "Ô", + ["õ"] = "Õ", + ["ö"] = "Ö", + ["ø"] = "Ø", + ["ù"] = "Ù", + ["ú"] = "Ú", + ["û"] = "Û", + ["ü"] = "Ü", + ["ý"] = "Ý", + ["þ"] = "Þ", + ["ÿ"] = "Ÿ", + ["ā"] = "Ā", + ["ă"] = "Ă", + ["ą"] = "Ą", + ["ć"] = "Ć", + ["ĉ"] = "Ĉ", + ["ċ"] = "Ċ", + ["č"] = "Č", + ["ď"] = "Ď", + ["đ"] = "Đ", + ["ē"] = "Ē", + ["ĕ"] = "Ĕ", + ["ė"] = "Ė", + ["ę"] = "Ę", + ["ě"] = "Ě", + ["ĝ"] = "Ĝ", + ["ğ"] = "Ğ", + ["ġ"] = "Ġ", + ["ģ"] = "Ģ", + ["ĥ"] = "Ĥ", + ["ħ"] = "Ħ", + ["ĩ"] = "Ĩ", + ["ī"] = "Ī", + ["ĭ"] = "Ĭ", + ["į"] = "Į", + ["ı"] = "I", + ["ij"] = "IJ", + ["ĵ"] = "Ĵ", + ["ķ"] = "Ķ", + ["ĺ"] = "Ĺ", + ["ļ"] = "Ļ", + ["ľ"] = "Ľ", + ["ŀ"] = "Ŀ", + ["ł"] = "Ł", + ["ń"] = "Ń", + ["ņ"] = "Ņ", + ["ň"] = "Ň", + ["ŋ"] = "Ŋ", + ["ō"] = "Ō", + ["ŏ"] = "Ŏ", + ["ő"] = "Ő", + ["œ"] = "Œ", + ["ŕ"] = "Ŕ", + ["ŗ"] = "Ŗ", + ["ř"] = "Ř", + ["ś"] = "Ś", + ["ŝ"] = "Ŝ", + ["ş"] = "Ş", + ["š"] = "Š", + ["ţ"] = "Ţ", + ["ť"] = "Ť", + ["ŧ"] = "Ŧ", + ["ũ"] = "Ũ", + ["ū"] = "Ū", + ["ŭ"] = "Ŭ", + ["ů"] = "Ů", + ["ű"] = "Ű", + ["ų"] = "Ų", + ["ŵ"] = "Ŵ", + ["ŷ"] = "Ŷ", + ["ź"] = "Ź", + ["ż"] = "Ż", + ["ž"] = "Ž", + ["ſ"] = "S", + ["ƀ"] = "Ƀ", + ["ƃ"] = "Ƃ", + ["ƅ"] = "Ƅ", + ["ƈ"] = "Ƈ", + ["ƌ"] = "Ƌ", + ["ƒ"] = "Ƒ", + ["ƕ"] = "Ƕ", + ["ƙ"] = "Ƙ", + ["ƚ"] = "Ƚ", + ["ƞ"] = "Ƞ", + ["ơ"] = "Ơ", + ["ƣ"] = "Ƣ", + ["ƥ"] = "Ƥ", + ["ƨ"] = "Ƨ", + ["ƭ"] = "Ƭ", + ["ư"] = "Ư", + ["ƴ"] = "Ƴ", + ["ƶ"] = "Ƶ", + ["ƹ"] = "Ƹ", + ["ƽ"] = "Ƽ", + ["ƿ"] = "Ƿ", + ["Dž"] = "DŽ", + ["dž"] = "DŽ", + ["Lj"] = "LJ", + ["lj"] = "LJ", + ["Nj"] = "NJ", + ["nj"] = "NJ", + ["ǎ"] = "Ǎ", + ["ǐ"] = "Ǐ", + ["ǒ"] = "Ǒ", + ["ǔ"] = "Ǔ", + ["ǖ"] = "Ǖ", + ["ǘ"] = "Ǘ", + ["ǚ"] = "Ǚ", + ["ǜ"] = "Ǜ", + ["ǝ"] = "Ǝ", + ["ǟ"] = "Ǟ", + ["ǡ"] = "Ǡ", + ["ǣ"] = "Ǣ", + ["ǥ"] = "Ǥ", + ["ǧ"] = "Ǧ", + ["ǩ"] = "Ǩ", + ["ǫ"] = "Ǫ", + ["ǭ"] = "Ǭ", + ["ǯ"] = "Ǯ", + ["Dz"] = "DZ", + ["dz"] = "DZ", + ["ǵ"] = "Ǵ", + ["ǹ"] = "Ǹ", + ["ǻ"] = "Ǻ", + ["ǽ"] = "Ǽ", + ["ǿ"] = "Ǿ", + ["ȁ"] = "Ȁ", + ["ȃ"] = "Ȃ", + ["ȅ"] = "Ȅ", + ["ȇ"] = "Ȇ", + ["ȉ"] = "Ȉ", + ["ȋ"] = "Ȋ", + ["ȍ"] = "Ȍ", + ["ȏ"] = "Ȏ", + ["ȑ"] = "Ȑ", + ["ȓ"] = "Ȓ", + ["ȕ"] = "Ȕ", + ["ȗ"] = "Ȗ", + ["ș"] = "Ș", + ["ț"] = "Ț", + ["ȝ"] = "Ȝ", + ["ȟ"] = "Ȟ", + ["ȣ"] = "Ȣ", + ["ȥ"] = "Ȥ", + ["ȧ"] = "Ȧ", + ["ȩ"] = "Ȩ", + ["ȫ"] = "Ȫ", + ["ȭ"] = "Ȭ", + ["ȯ"] = "Ȯ", + ["ȱ"] = "Ȱ", + ["ȳ"] = "Ȳ", + ["ȼ"] = "Ȼ", + ["ɂ"] = "Ɂ", + ["ɇ"] = "Ɇ", + ["ɉ"] = "Ɉ", + ["ɋ"] = "Ɋ", + ["ɍ"] = "Ɍ", + ["ɏ"] = "Ɏ", + ["ɓ"] = "Ɓ", + ["ɔ"] = "Ɔ", + ["ɖ"] = "Ɖ", + ["ɗ"] = "Ɗ", + ["ə"] = "Ə", + ["ɛ"] = "Ɛ", + ["ɠ"] = "Ɠ", + ["ɣ"] = "Ɣ", + ["ɨ"] = "Ɨ", + ["ɩ"] = "Ɩ", + ["ɫ"] = "Ɫ", + ["ɯ"] = "Ɯ", + ["ɲ"] = "Ɲ", + ["ɵ"] = "Ɵ", + ["ɽ"] = "Ɽ", + ["ʀ"] = "Ʀ", + ["ʃ"] = "Ʃ", + ["ʈ"] = "Ʈ", + ["ʉ"] = "Ʉ", + ["ʊ"] = "Ʊ", + ["ʋ"] = "Ʋ", + ["ʌ"] = "Ʌ", + ["ʒ"] = "Ʒ", + ["ͅ"] = "Ι", + ["ͻ"] = "Ͻ", + ["ͼ"] = "Ͼ", + ["ͽ"] = "Ͽ", + ["ά"] = "Ά", + ["έ"] = "Έ", + ["ή"] = "Ή", + ["ί"] = "Ί", + ["α"] = "Α", + ["β"] = "Β", + ["γ"] = "Γ", + ["δ"] = "Δ", + ["ε"] = "Ε", + ["ζ"] = "Ζ", + ["η"] = "Η", + ["θ"] = "Θ", + ["ι"] = "Ι", + ["κ"] = "Κ", + ["λ"] = "Λ", + ["μ"] = "Μ", + ["ν"] = "Ν", + ["ξ"] = "Ξ", + ["ο"] = "Ο", + ["π"] = "Π", + ["ρ"] = "Ρ", + ["ς"] = "Σ", + ["σ"] = "Σ", + ["τ"] = "Τ", + ["υ"] = "Υ", + ["φ"] = "Φ", + ["χ"] = "Χ", + ["ψ"] = "Ψ", + ["ω"] = "Ω", + ["ϊ"] = "Ϊ", + ["ϋ"] = "Ϋ", + ["ό"] = "Ό", + ["ύ"] = "Ύ", + ["ώ"] = "Ώ", + ["ϐ"] = "Β", + ["ϑ"] = "Θ", + ["ϕ"] = "Φ", + ["ϖ"] = "Π", + ["ϙ"] = "Ϙ", + ["ϛ"] = "Ϛ", + ["ϝ"] = "Ϝ", + ["ϟ"] = "Ϟ", + ["ϡ"] = "Ϡ", + ["ϣ"] = "Ϣ", + ["ϥ"] = "Ϥ", + ["ϧ"] = "Ϧ", + ["ϩ"] = "Ϩ", + ["ϫ"] = "Ϫ", + ["ϭ"] = "Ϭ", + ["ϯ"] = "Ϯ", + ["ϰ"] = "Κ", + ["ϱ"] = "Ρ", + ["ϲ"] = "Ϲ", + ["ϵ"] = "Ε", + ["ϸ"] = "Ϸ", + ["ϻ"] = "Ϻ", + ["а"] = "А", + ["б"] = "Б", + ["в"] = "В", + ["г"] = "Г", + ["д"] = "Д", + ["е"] = "Е", + ["ж"] = "Ж", + ["з"] = "З", + ["и"] = "И", + ["й"] = "Й", + ["к"] = "К", + ["л"] = "Л", + ["м"] = "М", + ["н"] = "Н", + ["о"] = "О", + ["п"] = "П", + ["р"] = "Р", + ["с"] = "С", + ["т"] = "Т", + ["у"] = "У", + ["ф"] = "Ф", + ["х"] = "Х", + ["ц"] = "Ц", + ["ч"] = "Ч", + ["ш"] = "Ш", + ["щ"] = "Щ", + ["ъ"] = "Ъ", + ["ы"] = "Ы", + ["ь"] = "Ь", + ["э"] = "Э", + ["ю"] = "Ю", + ["я"] = "Я", + ["ѐ"] = "Ѐ", + ["ё"] = "Ё", + ["ђ"] = "Ђ", + ["ѓ"] = "Ѓ", + ["є"] = "Є", + ["ѕ"] = "Ѕ", + ["і"] = "І", + ["ї"] = "Ї", + ["ј"] = "Ј", + ["љ"] = "Љ", + ["њ"] = "Њ", + ["ћ"] = "Ћ", + ["ќ"] = "Ќ", + ["ѝ"] = "Ѝ", + ["ў"] = "Ў", + ["џ"] = "Џ", + ["ѡ"] = "Ѡ", + ["ѣ"] = "Ѣ", + ["ѥ"] = "Ѥ", + ["ѧ"] = "Ѧ", + ["ѩ"] = "Ѩ", + ["ѫ"] = "Ѫ", + ["ѭ"] = "Ѭ", + ["ѯ"] = "Ѯ", + ["ѱ"] = "Ѱ", + ["ѳ"] = "Ѳ", + ["ѵ"] = "Ѵ", + ["ѷ"] = "Ѷ", + ["ѹ"] = "Ѹ", + ["ѻ"] = "Ѻ", + ["ѽ"] = "Ѽ", + ["ѿ"] = "Ѿ", + ["ҁ"] = "Ҁ", + ["ҋ"] = "Ҋ", + ["ҍ"] = "Ҍ", + ["ҏ"] = "Ҏ", + ["ґ"] = "Ґ", + ["ғ"] = "Ғ", + ["ҕ"] = "Ҕ", + ["җ"] = "Җ", + ["ҙ"] = "Ҙ", + ["қ"] = "Қ", + ["ҝ"] = "Ҝ", + ["ҟ"] = "Ҟ", + ["ҡ"] = "Ҡ", + ["ң"] = "Ң", + ["ҥ"] = "Ҥ", + ["ҧ"] = "Ҧ", + ["ҩ"] = "Ҩ", + ["ҫ"] = "Ҫ", + ["ҭ"] = "Ҭ", + ["ү"] = "Ү", + ["ұ"] = "Ұ", + ["ҳ"] = "Ҳ", + ["ҵ"] = "Ҵ", + ["ҷ"] = "Ҷ", + ["ҹ"] = "Ҹ", + ["һ"] = "Һ", + ["ҽ"] = "Ҽ", + ["ҿ"] = "Ҿ", + ["ӂ"] = "Ӂ", + ["ӄ"] = "Ӄ", + ["ӆ"] = "Ӆ", + ["ӈ"] = "Ӈ", + ["ӊ"] = "Ӊ", + ["ӌ"] = "Ӌ", + ["ӎ"] = "Ӎ", + ["ӏ"] = "Ӏ", + ["ӑ"] = "Ӑ", + ["ӓ"] = "Ӓ", + ["ӕ"] = "Ӕ", + ["ӗ"] = "Ӗ", + ["ә"] = "Ә", + ["ӛ"] = "Ӛ", + ["ӝ"] = "Ӝ", + ["ӟ"] = "Ӟ", + ["ӡ"] = "Ӡ", + ["ӣ"] = "Ӣ", + ["ӥ"] = "Ӥ", + ["ӧ"] = "Ӧ", + ["ө"] = "Ө", + ["ӫ"] = "Ӫ", + ["ӭ"] = "Ӭ", + ["ӯ"] = "Ӯ", + ["ӱ"] = "Ӱ", + ["ӳ"] = "Ӳ", + ["ӵ"] = "Ӵ", + ["ӷ"] = "Ӷ", + ["ӹ"] = "Ӹ", + ["ӻ"] = "Ӻ", + ["ӽ"] = "Ӽ", + ["ӿ"] = "Ӿ", + ["ԁ"] = "Ԁ", + ["ԃ"] = "Ԃ", + ["ԅ"] = "Ԅ", + ["ԇ"] = "Ԇ", + ["ԉ"] = "Ԉ", + ["ԋ"] = "Ԋ", + ["ԍ"] = "Ԍ", + ["ԏ"] = "Ԏ", + ["ԑ"] = "Ԑ", + ["ԓ"] = "Ԓ", + ["ա"] = "Ա", + ["բ"] = "Բ", + ["գ"] = "Գ", + ["դ"] = "Դ", + ["ե"] = "Ե", + ["զ"] = "Զ", + ["է"] = "Է", + ["ը"] = "Ը", + ["թ"] = "Թ", + ["ժ"] = "Ժ", + ["ի"] = "Ի", + ["լ"] = "Լ", + ["խ"] = "Խ", + ["ծ"] = "Ծ", + ["կ"] = "Կ", + ["հ"] = "Հ", + ["ձ"] = "Ձ", + ["ղ"] = "Ղ", + ["ճ"] = "Ճ", + ["մ"] = "Մ", + ["յ"] = "Յ", + ["ն"] = "Ն", + ["շ"] = "Շ", + ["ո"] = "Ո", + ["չ"] = "Չ", + ["պ"] = "Պ", + ["ջ"] = "Ջ", + ["ռ"] = "Ռ", + ["ս"] = "Ս", + ["վ"] = "Վ", + ["տ"] = "Տ", + ["ր"] = "Ր", + ["ց"] = "Ց", + ["ւ"] = "Ւ", + ["փ"] = "Փ", + ["ք"] = "Ք", + ["օ"] = "Օ", + ["ֆ"] = "Ֆ", + ["ᵽ"] = "Ᵽ", + ["ḁ"] = "Ḁ", + ["ḃ"] = "Ḃ", + ["ḅ"] = "Ḅ", + ["ḇ"] = "Ḇ", + ["ḉ"] = "Ḉ", + ["ḋ"] = "Ḋ", + ["ḍ"] = "Ḍ", + ["ḏ"] = "Ḏ", + ["ḑ"] = "Ḑ", + ["ḓ"] = "Ḓ", + ["ḕ"] = "Ḕ", + ["ḗ"] = "Ḗ", + ["ḙ"] = "Ḙ", + ["ḛ"] = "Ḛ", + ["ḝ"] = "Ḝ", + ["ḟ"] = "Ḟ", + ["ḡ"] = "Ḡ", + ["ḣ"] = "Ḣ", + ["ḥ"] = "Ḥ", + ["ḧ"] = "Ḧ", + ["ḩ"] = "Ḩ", + ["ḫ"] = "Ḫ", + ["ḭ"] = "Ḭ", + ["ḯ"] = "Ḯ", + ["ḱ"] = "Ḱ", + ["ḳ"] = "Ḳ", + ["ḵ"] = "Ḵ", + ["ḷ"] = "Ḷ", + ["ḹ"] = "Ḹ", + ["ḻ"] = "Ḻ", + ["ḽ"] = "Ḽ", + ["ḿ"] = "Ḿ", + ["ṁ"] = "Ṁ", + ["ṃ"] = "Ṃ", + ["ṅ"] = "Ṅ", + ["ṇ"] = "Ṇ", + ["ṉ"] = "Ṉ", + ["ṋ"] = "Ṋ", + ["ṍ"] = "Ṍ", + ["ṏ"] = "Ṏ", + ["ṑ"] = "Ṑ", + ["ṓ"] = "Ṓ", + ["ṕ"] = "Ṕ", + ["ṗ"] = "Ṗ", + ["ṙ"] = "Ṙ", + ["ṛ"] = "Ṛ", + ["ṝ"] = "Ṝ", + ["ṟ"] = "Ṟ", + ["ṡ"] = "Ṡ", + ["ṣ"] = "Ṣ", + ["ṥ"] = "Ṥ", + ["ṧ"] = "Ṧ", + ["ṩ"] = "Ṩ", + ["ṫ"] = "Ṫ", + ["ṭ"] = "Ṭ", + ["ṯ"] = "Ṯ", + ["ṱ"] = "Ṱ", + ["ṳ"] = "Ṳ", + ["ṵ"] = "Ṵ", + ["ṷ"] = "Ṷ", + ["ṹ"] = "Ṹ", + ["ṻ"] = "Ṻ", + ["ṽ"] = "Ṽ", + ["ṿ"] = "Ṿ", + ["ẁ"] = "Ẁ", + ["ẃ"] = "Ẃ", + ["ẅ"] = "Ẅ", + ["ẇ"] = "Ẇ", + ["ẉ"] = "Ẉ", + ["ẋ"] = "Ẋ", + ["ẍ"] = "Ẍ", + ["ẏ"] = "Ẏ", + ["ẑ"] = "Ẑ", + ["ẓ"] = "Ẓ", + ["ẕ"] = "Ẕ", + ["ẛ"] = "Ṡ", + ["ạ"] = "Ạ", + ["ả"] = "Ả", + ["ấ"] = "Ấ", + ["ầ"] = "Ầ", + ["ẩ"] = "Ẩ", + ["ẫ"] = "Ẫ", + ["ậ"] = "Ậ", + ["ắ"] = "Ắ", + ["ằ"] = "Ằ", + ["ẳ"] = "Ẳ", + ["ẵ"] = "Ẵ", + ["ặ"] = "Ặ", + ["ẹ"] = "Ẹ", + ["ẻ"] = "Ẻ", + ["ẽ"] = "Ẽ", + ["ế"] = "Ế", + ["ề"] = "Ề", + ["ể"] = "Ể", + ["ễ"] = "Ễ", + ["ệ"] = "Ệ", + ["ỉ"] = "Ỉ", + ["ị"] = "Ị", + ["ọ"] = "Ọ", + ["ỏ"] = "Ỏ", + ["ố"] = "Ố", + ["ồ"] = "Ồ", + ["ổ"] = "Ổ", + ["ỗ"] = "Ỗ", + ["ộ"] = "Ộ", + ["ớ"] = "Ớ", + ["ờ"] = "Ờ", + ["ở"] = "Ở", + ["ỡ"] = "Ỡ", + ["ợ"] = "Ợ", + ["ụ"] = "Ụ", + ["ủ"] = "Ủ", + ["ứ"] = "Ứ", + ["ừ"] = "Ừ", + ["ử"] = "Ử", + ["ữ"] = "Ữ", + ["ự"] = "Ự", + ["ỳ"] = "Ỳ", + ["ỵ"] = "Ỵ", + ["ỷ"] = "Ỷ", + ["ỹ"] = "Ỹ", + ["ἀ"] = "Ἀ", + ["ἁ"] = "Ἁ", + ["ἂ"] = "Ἂ", + ["ἃ"] = "Ἃ", + ["ἄ"] = "Ἄ", + ["ἅ"] = "Ἅ", + ["ἆ"] = "Ἆ", + ["ἇ"] = "Ἇ", + ["ἐ"] = "Ἐ", + ["ἑ"] = "Ἑ", + ["ἒ"] = "Ἒ", + ["ἓ"] = "Ἓ", + ["ἔ"] = "Ἔ", + ["ἕ"] = "Ἕ", + ["ἠ"] = "Ἠ", + ["ἡ"] = "Ἡ", + ["ἢ"] = "Ἢ", + ["ἣ"] = "Ἣ", + ["ἤ"] = "Ἤ", + ["ἥ"] = "Ἥ", + ["ἦ"] = "Ἦ", + ["ἧ"] = "Ἧ", + ["ἰ"] = "Ἰ", + ["ἱ"] = "Ἱ", + ["ἲ"] = "Ἲ", + ["ἳ"] = "Ἳ", + ["ἴ"] = "Ἴ", + ["ἵ"] = "Ἵ", + ["ἶ"] = "Ἶ", + ["ἷ"] = "Ἷ", + ["ὀ"] = "Ὀ", + ["ὁ"] = "Ὁ", + ["ὂ"] = "Ὂ", + ["ὃ"] = "Ὃ", + ["ὄ"] = "Ὄ", + ["ὅ"] = "Ὅ", + ["ὑ"] = "Ὑ", + ["ὓ"] = "Ὓ", + ["ὕ"] = "Ὕ", + ["ὗ"] = "Ὗ", + ["ὠ"] = "Ὠ", + ["ὡ"] = "Ὡ", + ["ὢ"] = "Ὢ", + ["ὣ"] = "Ὣ", + ["ὤ"] = "Ὤ", + ["ὥ"] = "Ὥ", + ["ὦ"] = "Ὦ", + ["ὧ"] = "Ὧ", + ["ὰ"] = "Ὰ", + ["ά"] = "Ά", + ["ὲ"] = "Ὲ", + ["έ"] = "Έ", + ["ὴ"] = "Ὴ", + ["ή"] = "Ή", + ["ὶ"] = "Ὶ", + ["ί"] = "Ί", + ["ὸ"] = "Ὸ", + ["ό"] = "Ό", + ["ὺ"] = "Ὺ", + ["ύ"] = "Ύ", + ["ὼ"] = "Ὼ", + ["ώ"] = "Ώ", + ["ᾀ"] = "ᾈ", + ["ᾁ"] = "ᾉ", + ["ᾂ"] = "ᾊ", + ["ᾃ"] = "ᾋ", + ["ᾄ"] = "ᾌ", + ["ᾅ"] = "ᾍ", + ["ᾆ"] = "ᾎ", + ["ᾇ"] = "ᾏ", + ["ᾐ"] = "ᾘ", + ["ᾑ"] = "ᾙ", + ["ᾒ"] = "ᾚ", + ["ᾓ"] = "ᾛ", + ["ᾔ"] = "ᾜ", + ["ᾕ"] = "ᾝ", + ["ᾖ"] = "ᾞ", + ["ᾗ"] = "ᾟ", + ["ᾠ"] = "ᾨ", + ["ᾡ"] = "ᾩ", + ["ᾢ"] = "ᾪ", + ["ᾣ"] = "ᾫ", + ["ᾤ"] = "ᾬ", + ["ᾥ"] = "ᾭ", + ["ᾦ"] = "ᾮ", + ["ᾧ"] = "ᾯ", + ["ᾰ"] = "Ᾰ", + ["ᾱ"] = "Ᾱ", + ["ᾳ"] = "ᾼ", + ["ι"] = "Ι", + ["ῃ"] = "ῌ", + ["ῐ"] = "Ῐ", + ["ῑ"] = "Ῑ", + ["ῠ"] = "Ῠ", + ["ῡ"] = "Ῡ", + ["ῥ"] = "Ῥ", + ["ῳ"] = "ῼ", + ["ⅎ"] = "Ⅎ", + ["ⅰ"] = "Ⅰ", + ["ⅱ"] = "Ⅱ", + ["ⅲ"] = "Ⅲ", + ["ⅳ"] = "Ⅳ", + ["ⅴ"] = "Ⅴ", + ["ⅵ"] = "Ⅵ", + ["ⅶ"] = "Ⅶ", + ["ⅷ"] = "Ⅷ", + ["ⅸ"] = "Ⅸ", + ["ⅹ"] = "Ⅹ", + ["ⅺ"] = "Ⅺ", + ["ⅻ"] = "Ⅻ", + ["ⅼ"] = "Ⅼ", + ["ⅽ"] = "Ⅽ", + ["ⅾ"] = "Ⅾ", + ["ⅿ"] = "Ⅿ", + ["ↄ"] = "Ↄ", + ["ⓐ"] = "Ⓐ", + ["ⓑ"] = "Ⓑ", + ["ⓒ"] = "Ⓒ", + ["ⓓ"] = "Ⓓ", + ["ⓔ"] = "Ⓔ", + ["ⓕ"] = "Ⓕ", + ["ⓖ"] = "Ⓖ", + ["ⓗ"] = "Ⓗ", + ["ⓘ"] = "Ⓘ", + ["ⓙ"] = "Ⓙ", + ["ⓚ"] = "Ⓚ", + ["ⓛ"] = "Ⓛ", + ["ⓜ"] = "Ⓜ", + ["ⓝ"] = "Ⓝ", + ["ⓞ"] = "Ⓞ", + ["ⓟ"] = "Ⓟ", + ["ⓠ"] = "Ⓠ", + ["ⓡ"] = "Ⓡ", + ["ⓢ"] = "Ⓢ", + ["ⓣ"] = "Ⓣ", + ["ⓤ"] = "Ⓤ", + ["ⓥ"] = "Ⓥ", + ["ⓦ"] = "Ⓦ", + ["ⓧ"] = "Ⓧ", + ["ⓨ"] = "Ⓨ", + ["ⓩ"] = "Ⓩ", + ["ⰰ"] = "Ⰰ", + ["ⰱ"] = "Ⰱ", + ["ⰲ"] = "Ⰲ", + ["ⰳ"] = "Ⰳ", + ["ⰴ"] = "Ⰴ", + ["ⰵ"] = "Ⰵ", + ["ⰶ"] = "Ⰶ", + ["ⰷ"] = "Ⰷ", + ["ⰸ"] = "Ⰸ", + ["ⰹ"] = "Ⰹ", + ["ⰺ"] = "Ⰺ", + ["ⰻ"] = "Ⰻ", + ["ⰼ"] = "Ⰼ", + ["ⰽ"] = "Ⰽ", + ["ⰾ"] = "Ⰾ", + ["ⰿ"] = "Ⰿ", + ["ⱀ"] = "Ⱀ", + ["ⱁ"] = "Ⱁ", + ["ⱂ"] = "Ⱂ", + ["ⱃ"] = "Ⱃ", + ["ⱄ"] = "Ⱄ", + ["ⱅ"] = "Ⱅ", + ["ⱆ"] = "Ⱆ", + ["ⱇ"] = "Ⱇ", + ["ⱈ"] = "Ⱈ", + ["ⱉ"] = "Ⱉ", + ["ⱊ"] = "Ⱊ", + ["ⱋ"] = "Ⱋ", + ["ⱌ"] = "Ⱌ", + ["ⱍ"] = "Ⱍ", + ["ⱎ"] = "Ⱎ", + ["ⱏ"] = "Ⱏ", + ["ⱐ"] = "Ⱐ", + ["ⱑ"] = "Ⱑ", + ["ⱒ"] = "Ⱒ", + ["ⱓ"] = "Ⱓ", + ["ⱔ"] = "Ⱔ", + ["ⱕ"] = "Ⱕ", + ["ⱖ"] = "Ⱖ", + ["ⱗ"] = "Ⱗ", + ["ⱘ"] = "Ⱘ", + ["ⱙ"] = "Ⱙ", + ["ⱚ"] = "Ⱚ", + ["ⱛ"] = "Ⱛ", + ["ⱜ"] = "Ⱜ", + ["ⱝ"] = "Ⱝ", + ["ⱞ"] = "Ⱞ", + ["ⱡ"] = "Ⱡ", + ["ⱥ"] = "Ⱥ", + ["ⱦ"] = "Ⱦ", + ["ⱨ"] = "Ⱨ", + ["ⱪ"] = "Ⱪ", + ["ⱬ"] = "Ⱬ", + ["ⱶ"] = "Ⱶ", + ["ⲁ"] = "Ⲁ", + ["ⲃ"] = "Ⲃ", + ["ⲅ"] = "Ⲅ", + ["ⲇ"] = "Ⲇ", + ["ⲉ"] = "Ⲉ", + ["ⲋ"] = "Ⲋ", + ["ⲍ"] = "Ⲍ", + ["ⲏ"] = "Ⲏ", + ["ⲑ"] = "Ⲑ", + ["ⲓ"] = "Ⲓ", + ["ⲕ"] = "Ⲕ", + ["ⲗ"] = "Ⲗ", + ["ⲙ"] = "Ⲙ", + ["ⲛ"] = "Ⲛ", + ["ⲝ"] = "Ⲝ", + ["ⲟ"] = "Ⲟ", + ["ⲡ"] = "Ⲡ", + ["ⲣ"] = "Ⲣ", + ["ⲥ"] = "Ⲥ", + ["ⲧ"] = "Ⲧ", + ["ⲩ"] = "Ⲩ", + ["ⲫ"] = "Ⲫ", + ["ⲭ"] = "Ⲭ", + ["ⲯ"] = "Ⲯ", + ["ⲱ"] = "Ⲱ", + ["ⲳ"] = "Ⲳ", + ["ⲵ"] = "Ⲵ", + ["ⲷ"] = "Ⲷ", + ["ⲹ"] = "Ⲹ", + ["ⲻ"] = "Ⲻ", + ["ⲽ"] = "Ⲽ", + ["ⲿ"] = "Ⲿ", + ["ⳁ"] = "Ⳁ", + ["ⳃ"] = "Ⳃ", + ["ⳅ"] = "Ⳅ", + ["ⳇ"] = "Ⳇ", + ["ⳉ"] = "Ⳉ", + ["ⳋ"] = "Ⳋ", + ["ⳍ"] = "Ⳍ", + ["ⳏ"] = "Ⳏ", + ["ⳑ"] = "Ⳑ", + ["ⳓ"] = "Ⳓ", + ["ⳕ"] = "Ⳕ", + ["ⳗ"] = "Ⳗ", + ["ⳙ"] = "Ⳙ", + ["ⳛ"] = "Ⳛ", + ["ⳝ"] = "Ⳝ", + ["ⳟ"] = "Ⳟ", + ["ⳡ"] = "Ⳡ", + ["ⳣ"] = "Ⳣ", + ["ⴀ"] = "Ⴀ", + ["ⴁ"] = "Ⴁ", + ["ⴂ"] = "Ⴂ", + ["ⴃ"] = "Ⴃ", + ["ⴄ"] = "Ⴄ", + ["ⴅ"] = "Ⴅ", + ["ⴆ"] = "Ⴆ", + ["ⴇ"] = "Ⴇ", + ["ⴈ"] = "Ⴈ", + ["ⴉ"] = "Ⴉ", + ["ⴊ"] = "Ⴊ", + ["ⴋ"] = "Ⴋ", + ["ⴌ"] = "Ⴌ", + ["ⴍ"] = "Ⴍ", + ["ⴎ"] = "Ⴎ", + ["ⴏ"] = "Ⴏ", + ["ⴐ"] = "Ⴐ", + ["ⴑ"] = "Ⴑ", + ["ⴒ"] = "Ⴒ", + ["ⴓ"] = "Ⴓ", + ["ⴔ"] = "Ⴔ", + ["ⴕ"] = "Ⴕ", + ["ⴖ"] = "Ⴖ", + ["ⴗ"] = "Ⴗ", + ["ⴘ"] = "Ⴘ", + ["ⴙ"] = "Ⴙ", + ["ⴚ"] = "Ⴚ", + ["ⴛ"] = "Ⴛ", + ["ⴜ"] = "Ⴜ", + ["ⴝ"] = "Ⴝ", + ["ⴞ"] = "Ⴞ", + ["ⴟ"] = "Ⴟ", + ["ⴠ"] = "Ⴠ", + ["ⴡ"] = "Ⴡ", + ["ⴢ"] = "Ⴢ", + ["ⴣ"] = "Ⴣ", + ["ⴤ"] = "Ⴤ", + ["ⴥ"] = "Ⴥ", + ["a"] = "A", + ["b"] = "B", + ["c"] = "C", + ["d"] = "D", + ["e"] = "E", + ["f"] = "F", + ["g"] = "G", + ["h"] = "H", + ["i"] = "I", + ["j"] = "J", + ["k"] = "K", + ["l"] = "L", + ["m"] = "M", + ["n"] = "N", + ["o"] = "O", + ["p"] = "P", + ["q"] = "Q", + ["r"] = "R", + ["s"] = "S", + ["t"] = "T", + ["u"] = "U", + ["v"] = "V", + ["w"] = "W", + ["x"] = "X", + ["y"] = "Y", + ["z"] = "Z", + ["𐐨"] = "𐐀", + ["𐐩"] = "𐐁", + ["𐐪"] = "𐐂", + ["𐐫"] = "𐐃", + ["𐐬"] = "𐐄", + ["𐐭"] = "𐐅", + ["𐐮"] = "𐐆", + ["𐐯"] = "𐐇", + ["𐐰"] = "𐐈", + ["𐐱"] = "𐐉", + ["𐐲"] = "𐐊", + ["𐐳"] = "𐐋", + ["𐐴"] = "𐐌", + ["𐐵"] = "𐐍", + ["𐐶"] = "𐐎", + ["𐐷"] = "𐐏", + ["𐐸"] = "𐐐", + ["𐐹"] = "𐐑", + ["𐐺"] = "𐐒", + ["𐐻"] = "𐐓", + ["𐐼"] = "𐐔", + ["𐐽"] = "𐐕", + ["𐐾"] = "𐐖", + ["𐐿"] = "𐐗", + ["𐑀"] = "𐐘", + ["𐑁"] = "𐐙", + ["𐑂"] = "𐐚", + ["𐑃"] = "𐐛", + ["𐑄"] = "𐐜", + ["𐑅"] = "𐐝", + ["𐑆"] = "𐐞", + ["𐑇"] = "𐐟", + ["𐑈"] = "𐐠", + ["𐑉"] = "𐐡", + ["𐑊"] = "𐐢", + ["𐑋"] = "𐐣", + ["𐑌"] = "𐐤", + ["𐑍"] = "𐐥", + ["𐑎"] = "𐐦", + ["𐑏"] = "𐐧", +} + + +utf8_uc_lc = { + ["A"] = "a", + ["B"] = "b", + ["C"] = "c", + ["D"] = "d", + ["E"] = "e", + ["F"] = "f", + ["G"] = "g", + ["H"] = "h", + ["I"] = "i", + ["J"] = "j", + ["K"] = "k", + ["L"] = "l", + ["M"] = "m", + ["N"] = "n", + ["O"] = "o", + ["P"] = "p", + ["Q"] = "q", + ["R"] = "r", + ["S"] = "s", + ["T"] = "t", + ["U"] = "u", + ["V"] = "v", + ["W"] = "w", + ["X"] = "x", + ["Y"] = "y", + ["Z"] = "z", + ["À"] = "à", + ["Á"] = "á", + ["Â"] = "â", + ["Ã"] = "ã", + ["Ä"] = "ä", + ["Å"] = "å", + ["Æ"] = "æ", + ["Ç"] = "ç", + ["È"] = "è", + ["É"] = "é", + ["Ê"] = "ê", + ["Ë"] = "ë", + ["Ì"] = "ì", + ["Í"] = "í", + ["Î"] = "î", + ["Ï"] = "ï", + ["Ð"] = "ð", + ["Ñ"] = "ñ", + ["Ò"] = "ò", + ["Ó"] = "ó", + ["Ô"] = "ô", + ["Õ"] = "õ", + ["Ö"] = "ö", + ["Ø"] = "ø", + ["Ù"] = "ù", + ["Ú"] = "ú", + ["Û"] = "û", + ["Ü"] = "ü", + ["Ý"] = "ý", + ["Þ"] = "þ", + ["Ā"] = "ā", + ["Ă"] = "ă", + ["Ą"] = "ą", + ["Ć"] = "ć", + ["Ĉ"] = "ĉ", + ["Ċ"] = "ċ", + ["Č"] = "č", + ["Ď"] = "ď", + ["Đ"] = "đ", + ["Ē"] = "ē", + ["Ĕ"] = "ĕ", + ["Ė"] = "ė", + ["Ę"] = "ę", + ["Ě"] = "ě", + ["Ĝ"] = "ĝ", + ["Ğ"] = "ğ", + ["Ġ"] = "ġ", + ["Ģ"] = "ģ", + ["Ĥ"] = "ĥ", + ["Ħ"] = "ħ", + ["Ĩ"] = "ĩ", + ["Ī"] = "ī", + ["Ĭ"] = "ĭ", + ["Į"] = "į", + ["İ"] = "i", + ["IJ"] = "ij", + ["Ĵ"] = "ĵ", + ["Ķ"] = "ķ", + ["Ĺ"] = "ĺ", + ["Ļ"] = "ļ", + ["Ľ"] = "ľ", + ["Ŀ"] = "ŀ", + ["Ł"] = "ł", + ["Ń"] = "ń", + ["Ņ"] = "ņ", + ["Ň"] = "ň", + ["Ŋ"] = "ŋ", + ["Ō"] = "ō", + ["Ŏ"] = "ŏ", + ["Ő"] = "ő", + ["Œ"] = "œ", + ["Ŕ"] = "ŕ", + ["Ŗ"] = "ŗ", + ["Ř"] = "ř", + ["Ś"] = "ś", + ["Ŝ"] = "ŝ", + ["Ş"] = "ş", + ["Š"] = "š", + ["Ţ"] = "ţ", + ["Ť"] = "ť", + ["Ŧ"] = "ŧ", + ["Ũ"] = "ũ", + ["Ū"] = "ū", + ["Ŭ"] = "ŭ", + ["Ů"] = "ů", + ["Ű"] = "ű", + ["Ų"] = "ų", + ["Ŵ"] = "ŵ", + ["Ŷ"] = "ŷ", + ["Ÿ"] = "ÿ", + ["Ź"] = "ź", + ["Ż"] = "ż", + ["Ž"] = "ž", + ["Ɓ"] = "ɓ", + ["Ƃ"] = "ƃ", + ["Ƅ"] = "ƅ", + ["Ɔ"] = "ɔ", + ["Ƈ"] = "ƈ", + ["Ɖ"] = "ɖ", + ["Ɗ"] = "ɗ", + ["Ƌ"] = "ƌ", + ["Ǝ"] = "ǝ", + ["Ə"] = "ə", + ["Ɛ"] = "ɛ", + ["Ƒ"] = "ƒ", + ["Ɠ"] = "ɠ", + ["Ɣ"] = "ɣ", + ["Ɩ"] = "ɩ", + ["Ɨ"] = "ɨ", + ["Ƙ"] = "ƙ", + ["Ɯ"] = "ɯ", + ["Ɲ"] = "ɲ", + ["Ɵ"] = "ɵ", + ["Ơ"] = "ơ", + ["Ƣ"] = "ƣ", + ["Ƥ"] = "ƥ", + ["Ʀ"] = "ʀ", + ["Ƨ"] = "ƨ", + ["Ʃ"] = "ʃ", + ["Ƭ"] = "ƭ", + ["Ʈ"] = "ʈ", + ["Ư"] = "ư", + ["Ʊ"] = "ʊ", + ["Ʋ"] = "ʋ", + ["Ƴ"] = "ƴ", + ["Ƶ"] = "ƶ", + ["Ʒ"] = "ʒ", + ["Ƹ"] = "ƹ", + ["Ƽ"] = "ƽ", + ["DŽ"] = "dž", + ["Dž"] = "dž", + ["LJ"] = "lj", + ["Lj"] = "lj", + ["NJ"] = "nj", + ["Nj"] = "nj", + ["Ǎ"] = "ǎ", + ["Ǐ"] = "ǐ", + ["Ǒ"] = "ǒ", + ["Ǔ"] = "ǔ", + ["Ǖ"] = "ǖ", + ["Ǘ"] = "ǘ", + ["Ǚ"] = "ǚ", + ["Ǜ"] = "ǜ", + ["Ǟ"] = "ǟ", + ["Ǡ"] = "ǡ", + ["Ǣ"] = "ǣ", + ["Ǥ"] = "ǥ", + ["Ǧ"] = "ǧ", + ["Ǩ"] = "ǩ", + ["Ǫ"] = "ǫ", + ["Ǭ"] = "ǭ", + ["Ǯ"] = "ǯ", + ["DZ"] = "dz", + ["Dz"] = "dz", + ["Ǵ"] = "ǵ", + ["Ƕ"] = "ƕ", + ["Ƿ"] = "ƿ", + ["Ǹ"] = "ǹ", + ["Ǻ"] = "ǻ", + ["Ǽ"] = "ǽ", + ["Ǿ"] = "ǿ", + ["Ȁ"] = "ȁ", + ["Ȃ"] = "ȃ", + ["Ȅ"] = "ȅ", + ["Ȇ"] = "ȇ", + ["Ȉ"] = "ȉ", + ["Ȋ"] = "ȋ", + ["Ȍ"] = "ȍ", + ["Ȏ"] = "ȏ", + ["Ȑ"] = "ȑ", + ["Ȓ"] = "ȓ", + ["Ȕ"] = "ȕ", + ["Ȗ"] = "ȗ", + ["Ș"] = "ș", + ["Ț"] = "ț", + ["Ȝ"] = "ȝ", + ["Ȟ"] = "ȟ", + ["Ƞ"] = "ƞ", + ["Ȣ"] = "ȣ", + ["Ȥ"] = "ȥ", + ["Ȧ"] = "ȧ", + ["Ȩ"] = "ȩ", + ["Ȫ"] = "ȫ", + ["Ȭ"] = "ȭ", + ["Ȯ"] = "ȯ", + ["Ȱ"] = "ȱ", + ["Ȳ"] = "ȳ", + ["Ⱥ"] = "ⱥ", + ["Ȼ"] = "ȼ", + ["Ƚ"] = "ƚ", + ["Ⱦ"] = "ⱦ", + ["Ɂ"] = "ɂ", + ["Ƀ"] = "ƀ", + ["Ʉ"] = "ʉ", + ["Ʌ"] = "ʌ", + ["Ɇ"] = "ɇ", + ["Ɉ"] = "ɉ", + ["Ɋ"] = "ɋ", + ["Ɍ"] = "ɍ", + ["Ɏ"] = "ɏ", + ["Ά"] = "ά", + ["Έ"] = "έ", + ["Ή"] = "ή", + ["Ί"] = "ί", + ["Ό"] = "ό", + ["Ύ"] = "ύ", + ["Ώ"] = "ώ", + ["Α"] = "α", + ["Β"] = "β", + ["Γ"] = "γ", + ["Δ"] = "δ", + ["Ε"] = "ε", + ["Ζ"] = "ζ", + ["Η"] = "η", + ["Θ"] = "θ", + ["Ι"] = "ι", + ["Κ"] = "κ", + ["Λ"] = "λ", + ["Μ"] = "μ", + ["Ν"] = "ν", + ["Ξ"] = "ξ", + ["Ο"] = "ο", + ["Π"] = "π", + ["Ρ"] = "ρ", + ["Σ"] = "σ", + ["Τ"] = "τ", + ["Υ"] = "υ", + ["Φ"] = "φ", + ["Χ"] = "χ", + ["Ψ"] = "ψ", + ["Ω"] = "ω", + ["Ϊ"] = "ϊ", + ["Ϋ"] = "ϋ", + ["Ϙ"] = "ϙ", + ["Ϛ"] = "ϛ", + ["Ϝ"] = "ϝ", + ["Ϟ"] = "ϟ", + ["Ϡ"] = "ϡ", + ["Ϣ"] = "ϣ", + ["Ϥ"] = "ϥ", + ["Ϧ"] = "ϧ", + ["Ϩ"] = "ϩ", + ["Ϫ"] = "ϫ", + ["Ϭ"] = "ϭ", + ["Ϯ"] = "ϯ", + ["ϴ"] = "θ", + ["Ϸ"] = "ϸ", + ["Ϲ"] = "ϲ", + ["Ϻ"] = "ϻ", + ["Ͻ"] = "ͻ", + ["Ͼ"] = "ͼ", + ["Ͽ"] = "ͽ", + ["Ѐ"] = "ѐ", + ["Ё"] = "ё", + ["Ђ"] = "ђ", + ["Ѓ"] = "ѓ", + ["Є"] = "є", + ["Ѕ"] = "ѕ", + ["І"] = "і", + ["Ї"] = "ї", + ["Ј"] = "ј", + ["Љ"] = "љ", + ["Њ"] = "њ", + ["Ћ"] = "ћ", + ["Ќ"] = "ќ", + ["Ѝ"] = "ѝ", + ["Ў"] = "ў", + ["Џ"] = "џ", + ["А"] = "а", + ["Б"] = "б", + ["В"] = "в", + ["Г"] = "г", + ["Д"] = "д", + ["Е"] = "е", + ["Ж"] = "ж", + ["З"] = "з", + ["И"] = "и", + ["Й"] = "й", + ["К"] = "к", + ["Л"] = "л", + ["М"] = "м", + ["Н"] = "н", + ["О"] = "о", + ["П"] = "п", + ["Р"] = "р", + ["С"] = "с", + ["Т"] = "т", + ["У"] = "у", + ["Ф"] = "ф", + ["Х"] = "х", + ["Ц"] = "ц", + ["Ч"] = "ч", + ["Ш"] = "ш", + ["Щ"] = "щ", + ["Ъ"] = "ъ", + ["Ы"] = "ы", + ["Ь"] = "ь", + ["Э"] = "э", + ["Ю"] = "ю", + ["Я"] = "я", + ["Ѡ"] = "ѡ", + ["Ѣ"] = "ѣ", + ["Ѥ"] = "ѥ", + ["Ѧ"] = "ѧ", + ["Ѩ"] = "ѩ", + ["Ѫ"] = "ѫ", + ["Ѭ"] = "ѭ", + ["Ѯ"] = "ѯ", + ["Ѱ"] = "ѱ", + ["Ѳ"] = "ѳ", + ["Ѵ"] = "ѵ", + ["Ѷ"] = "ѷ", + ["Ѹ"] = "ѹ", + ["Ѻ"] = "ѻ", + ["Ѽ"] = "ѽ", + ["Ѿ"] = "ѿ", + ["Ҁ"] = "ҁ", + ["Ҋ"] = "ҋ", + ["Ҍ"] = "ҍ", + ["Ҏ"] = "ҏ", + ["Ґ"] = "ґ", + ["Ғ"] = "ғ", + ["Ҕ"] = "ҕ", + ["Җ"] = "җ", + ["Ҙ"] = "ҙ", + ["Қ"] = "қ", + ["Ҝ"] = "ҝ", + ["Ҟ"] = "ҟ", + ["Ҡ"] = "ҡ", + ["Ң"] = "ң", + ["Ҥ"] = "ҥ", + ["Ҧ"] = "ҧ", + ["Ҩ"] = "ҩ", + ["Ҫ"] = "ҫ", + ["Ҭ"] = "ҭ", + ["Ү"] = "ү", + ["Ұ"] = "ұ", + ["Ҳ"] = "ҳ", + ["Ҵ"] = "ҵ", + ["Ҷ"] = "ҷ", + ["Ҹ"] = "ҹ", + ["Һ"] = "һ", + ["Ҽ"] = "ҽ", + ["Ҿ"] = "ҿ", + ["Ӏ"] = "ӏ", + ["Ӂ"] = "ӂ", + ["Ӄ"] = "ӄ", + ["Ӆ"] = "ӆ", + ["Ӈ"] = "ӈ", + ["Ӊ"] = "ӊ", + ["Ӌ"] = "ӌ", + ["Ӎ"] = "ӎ", + ["Ӑ"] = "ӑ", + ["Ӓ"] = "ӓ", + ["Ӕ"] = "ӕ", + ["Ӗ"] = "ӗ", + ["Ә"] = "ә", + ["Ӛ"] = "ӛ", + ["Ӝ"] = "ӝ", + ["Ӟ"] = "ӟ", + ["Ӡ"] = "ӡ", + ["Ӣ"] = "ӣ", + ["Ӥ"] = "ӥ", + ["Ӧ"] = "ӧ", + ["Ө"] = "ө", + ["Ӫ"] = "ӫ", + ["Ӭ"] = "ӭ", + ["Ӯ"] = "ӯ", + ["Ӱ"] = "ӱ", + ["Ӳ"] = "ӳ", + ["Ӵ"] = "ӵ", + ["Ӷ"] = "ӷ", + ["Ӹ"] = "ӹ", + ["Ӻ"] = "ӻ", + ["Ӽ"] = "ӽ", + ["Ӿ"] = "ӿ", + ["Ԁ"] = "ԁ", + ["Ԃ"] = "ԃ", + ["Ԅ"] = "ԅ", + ["Ԇ"] = "ԇ", + ["Ԉ"] = "ԉ", + ["Ԋ"] = "ԋ", + ["Ԍ"] = "ԍ", + ["Ԏ"] = "ԏ", + ["Ԑ"] = "ԑ", + ["Ԓ"] = "ԓ", + ["Ա"] = "ա", + ["Բ"] = "բ", + ["Գ"] = "գ", + ["Դ"] = "դ", + ["Ե"] = "ե", + ["Զ"] = "զ", + ["Է"] = "է", + ["Ը"] = "ը", + ["Թ"] = "թ", + ["Ժ"] = "ժ", + ["Ի"] = "ի", + ["Լ"] = "լ", + ["Խ"] = "խ", + ["Ծ"] = "ծ", + ["Կ"] = "կ", + ["Հ"] = "հ", + ["Ձ"] = "ձ", + ["Ղ"] = "ղ", + ["Ճ"] = "ճ", + ["Մ"] = "մ", + ["Յ"] = "յ", + ["Ն"] = "ն", + ["Շ"] = "շ", + ["Ո"] = "ո", + ["Չ"] = "չ", + ["Պ"] = "պ", + ["Ջ"] = "ջ", + ["Ռ"] = "ռ", + ["Ս"] = "ս", + ["Վ"] = "վ", + ["Տ"] = "տ", + ["Ր"] = "ր", + ["Ց"] = "ց", + ["Ւ"] = "ւ", + ["Փ"] = "փ", + ["Ք"] = "ք", + ["Օ"] = "օ", + ["Ֆ"] = "ֆ", + ["Ⴀ"] = "ⴀ", + ["Ⴁ"] = "ⴁ", + ["Ⴂ"] = "ⴂ", + ["Ⴃ"] = "ⴃ", + ["Ⴄ"] = "ⴄ", + ["Ⴅ"] = "ⴅ", + ["Ⴆ"] = "ⴆ", + ["Ⴇ"] = "ⴇ", + ["Ⴈ"] = "ⴈ", + ["Ⴉ"] = "ⴉ", + ["Ⴊ"] = "ⴊ", + ["Ⴋ"] = "ⴋ", + ["Ⴌ"] = "ⴌ", + ["Ⴍ"] = "ⴍ", + ["Ⴎ"] = "ⴎ", + ["Ⴏ"] = "ⴏ", + ["Ⴐ"] = "ⴐ", + ["Ⴑ"] = "ⴑ", + ["Ⴒ"] = "ⴒ", + ["Ⴓ"] = "ⴓ", + ["Ⴔ"] = "ⴔ", + ["Ⴕ"] = "ⴕ", + ["Ⴖ"] = "ⴖ", + ["Ⴗ"] = "ⴗ", + ["Ⴘ"] = "ⴘ", + ["Ⴙ"] = "ⴙ", + ["Ⴚ"] = "ⴚ", + ["Ⴛ"] = "ⴛ", + ["Ⴜ"] = "ⴜ", + ["Ⴝ"] = "ⴝ", + ["Ⴞ"] = "ⴞ", + ["Ⴟ"] = "ⴟ", + ["Ⴠ"] = "ⴠ", + ["Ⴡ"] = "ⴡ", + ["Ⴢ"] = "ⴢ", + ["Ⴣ"] = "ⴣ", + ["Ⴤ"] = "ⴤ", + ["Ⴥ"] = "ⴥ", + ["Ḁ"] = "ḁ", + ["Ḃ"] = "ḃ", + ["Ḅ"] = "ḅ", + ["Ḇ"] = "ḇ", + ["Ḉ"] = "ḉ", + ["Ḋ"] = "ḋ", + ["Ḍ"] = "ḍ", + ["Ḏ"] = "ḏ", + ["Ḑ"] = "ḑ", + ["Ḓ"] = "ḓ", + ["Ḕ"] = "ḕ", + ["Ḗ"] = "ḗ", + ["Ḙ"] = "ḙ", + ["Ḛ"] = "ḛ", + ["Ḝ"] = "ḝ", + ["Ḟ"] = "ḟ", + ["Ḡ"] = "ḡ", + ["Ḣ"] = "ḣ", + ["Ḥ"] = "ḥ", + ["Ḧ"] = "ḧ", + ["Ḩ"] = "ḩ", + ["Ḫ"] = "ḫ", + ["Ḭ"] = "ḭ", + ["Ḯ"] = "ḯ", + ["Ḱ"] = "ḱ", + ["Ḳ"] = "ḳ", + ["Ḵ"] = "ḵ", + ["Ḷ"] = "ḷ", + ["Ḹ"] = "ḹ", + ["Ḻ"] = "ḻ", + ["Ḽ"] = "ḽ", + ["Ḿ"] = "ḿ", + ["Ṁ"] = "ṁ", + ["Ṃ"] = "ṃ", + ["Ṅ"] = "ṅ", + ["Ṇ"] = "ṇ", + ["Ṉ"] = "ṉ", + ["Ṋ"] = "ṋ", + ["Ṍ"] = "ṍ", + ["Ṏ"] = "ṏ", + ["Ṑ"] = "ṑ", + ["Ṓ"] = "ṓ", + ["Ṕ"] = "ṕ", + ["Ṗ"] = "ṗ", + ["Ṙ"] = "ṙ", + ["Ṛ"] = "ṛ", + ["Ṝ"] = "ṝ", + ["Ṟ"] = "ṟ", + ["Ṡ"] = "ṡ", + ["Ṣ"] = "ṣ", + ["Ṥ"] = "ṥ", + ["Ṧ"] = "ṧ", + ["Ṩ"] = "ṩ", + ["Ṫ"] = "ṫ", + ["Ṭ"] = "ṭ", + ["Ṯ"] = "ṯ", + ["Ṱ"] = "ṱ", + ["Ṳ"] = "ṳ", + ["Ṵ"] = "ṵ", + ["Ṷ"] = "ṷ", + ["Ṹ"] = "ṹ", + ["Ṻ"] = "ṻ", + ["Ṽ"] = "ṽ", + ["Ṿ"] = "ṿ", + ["Ẁ"] = "ẁ", + ["Ẃ"] = "ẃ", + ["Ẅ"] = "ẅ", + ["Ẇ"] = "ẇ", + ["Ẉ"] = "ẉ", + ["Ẋ"] = "ẋ", + ["Ẍ"] = "ẍ", + ["Ẏ"] = "ẏ", + ["Ẑ"] = "ẑ", + ["Ẓ"] = "ẓ", + ["Ẕ"] = "ẕ", + ["Ạ"] = "ạ", + ["Ả"] = "ả", + ["Ấ"] = "ấ", + ["Ầ"] = "ầ", + ["Ẩ"] = "ẩ", + ["Ẫ"] = "ẫ", + ["Ậ"] = "ậ", + ["Ắ"] = "ắ", + ["Ằ"] = "ằ", + ["Ẳ"] = "ẳ", + ["Ẵ"] = "ẵ", + ["Ặ"] = "ặ", + ["Ẹ"] = "ẹ", + ["Ẻ"] = "ẻ", + ["Ẽ"] = "ẽ", + ["Ế"] = "ế", + ["Ề"] = "ề", + ["Ể"] = "ể", + ["Ễ"] = "ễ", + ["Ệ"] = "ệ", + ["Ỉ"] = "ỉ", + ["Ị"] = "ị", + ["Ọ"] = "ọ", + ["Ỏ"] = "ỏ", + ["Ố"] = "ố", + ["Ồ"] = "ồ", + ["Ổ"] = "ổ", + ["Ỗ"] = "ỗ", + ["Ộ"] = "ộ", + ["Ớ"] = "ớ", + ["Ờ"] = "ờ", + ["Ở"] = "ở", + ["Ỡ"] = "ỡ", + ["Ợ"] = "ợ", + ["Ụ"] = "ụ", + ["Ủ"] = "ủ", + ["Ứ"] = "ứ", + ["Ừ"] = "ừ", + ["Ử"] = "ử", + ["Ữ"] = "ữ", + ["Ự"] = "ự", + ["Ỳ"] = "ỳ", + ["Ỵ"] = "ỵ", + ["Ỷ"] = "ỷ", + ["Ỹ"] = "ỹ", + ["Ἀ"] = "ἀ", + ["Ἁ"] = "ἁ", + ["Ἂ"] = "ἂ", + ["Ἃ"] = "ἃ", + ["Ἄ"] = "ἄ", + ["Ἅ"] = "ἅ", + ["Ἆ"] = "ἆ", + ["Ἇ"] = "ἇ", + ["Ἐ"] = "ἐ", + ["Ἑ"] = "ἑ", + ["Ἒ"] = "ἒ", + ["Ἓ"] = "ἓ", + ["Ἔ"] = "ἔ", + ["Ἕ"] = "ἕ", + ["Ἠ"] = "ἠ", + ["Ἡ"] = "ἡ", + ["Ἢ"] = "ἢ", + ["Ἣ"] = "ἣ", + ["Ἤ"] = "ἤ", + ["Ἥ"] = "ἥ", + ["Ἦ"] = "ἦ", + ["Ἧ"] = "ἧ", + ["Ἰ"] = "ἰ", + ["Ἱ"] = "ἱ", + ["Ἲ"] = "ἲ", + ["Ἳ"] = "ἳ", + ["Ἴ"] = "ἴ", + ["Ἵ"] = "ἵ", + ["Ἶ"] = "ἶ", + ["Ἷ"] = "ἷ", + ["Ὀ"] = "ὀ", + ["Ὁ"] = "ὁ", + ["Ὂ"] = "ὂ", + ["Ὃ"] = "ὃ", + ["Ὄ"] = "ὄ", + ["Ὅ"] = "ὅ", + ["Ὑ"] = "ὑ", + ["Ὓ"] = "ὓ", + ["Ὕ"] = "ὕ", + ["Ὗ"] = "ὗ", + ["Ὠ"] = "ὠ", + ["Ὡ"] = "ὡ", + ["Ὢ"] = "ὢ", + ["Ὣ"] = "ὣ", + ["Ὤ"] = "ὤ", + ["Ὥ"] = "ὥ", + ["Ὦ"] = "ὦ", + ["Ὧ"] = "ὧ", + ["ᾈ"] = "ᾀ", + ["ᾉ"] = "ᾁ", + ["ᾊ"] = "ᾂ", + ["ᾋ"] = "ᾃ", + ["ᾌ"] = "ᾄ", + ["ᾍ"] = "ᾅ", + ["ᾎ"] = "ᾆ", + ["ᾏ"] = "ᾇ", + ["ᾘ"] = "ᾐ", + ["ᾙ"] = "ᾑ", + ["ᾚ"] = "ᾒ", + ["ᾛ"] = "ᾓ", + ["ᾜ"] = "ᾔ", + ["ᾝ"] = "ᾕ", + ["ᾞ"] = "ᾖ", + ["ᾟ"] = "ᾗ", + ["ᾨ"] = "ᾠ", + ["ᾩ"] = "ᾡ", + ["ᾪ"] = "ᾢ", + ["ᾫ"] = "ᾣ", + ["ᾬ"] = "ᾤ", + ["ᾭ"] = "ᾥ", + ["ᾮ"] = "ᾦ", + ["ᾯ"] = "ᾧ", + ["Ᾰ"] = "ᾰ", + ["Ᾱ"] = "ᾱ", + ["Ὰ"] = "ὰ", + ["Ά"] = "ά", + ["ᾼ"] = "ᾳ", + ["Ὲ"] = "ὲ", + ["Έ"] = "έ", + ["Ὴ"] = "ὴ", + ["Ή"] = "ή", + ["ῌ"] = "ῃ", + ["Ῐ"] = "ῐ", + ["Ῑ"] = "ῑ", + ["Ὶ"] = "ὶ", + ["Ί"] = "ί", + ["Ῠ"] = "ῠ", + ["Ῡ"] = "ῡ", + ["Ὺ"] = "ὺ", + ["Ύ"] = "ύ", + ["Ῥ"] = "ῥ", + ["Ὸ"] = "ὸ", + ["Ό"] = "ό", + ["Ὼ"] = "ὼ", + ["Ώ"] = "ώ", + ["ῼ"] = "ῳ", + ["Ω"] = "ω", + ["K"] = "k", + ["Å"] = "å", + ["Ⅎ"] = "ⅎ", + ["Ⅰ"] = "ⅰ", + ["Ⅱ"] = "ⅱ", + ["Ⅲ"] = "ⅲ", + ["Ⅳ"] = "ⅳ", + ["Ⅴ"] = "ⅴ", + ["Ⅵ"] = "ⅵ", + ["Ⅶ"] = "ⅶ", + ["Ⅷ"] = "ⅷ", + ["Ⅸ"] = "ⅸ", + ["Ⅹ"] = "ⅹ", + ["Ⅺ"] = "ⅺ", + ["Ⅻ"] = "ⅻ", + ["Ⅼ"] = "ⅼ", + ["Ⅽ"] = "ⅽ", + ["Ⅾ"] = "ⅾ", + ["Ⅿ"] = "ⅿ", + ["Ↄ"] = "ↄ", + ["Ⓐ"] = "ⓐ", + ["Ⓑ"] = "ⓑ", + ["Ⓒ"] = "ⓒ", + ["Ⓓ"] = "ⓓ", + ["Ⓔ"] = "ⓔ", + ["Ⓕ"] = "ⓕ", + ["Ⓖ"] = "ⓖ", + ["Ⓗ"] = "ⓗ", + ["Ⓘ"] = "ⓘ", + ["Ⓙ"] = "ⓙ", + ["Ⓚ"] = "ⓚ", + ["Ⓛ"] = "ⓛ", + ["Ⓜ"] = "ⓜ", + ["Ⓝ"] = "ⓝ", + ["Ⓞ"] = "ⓞ", + ["Ⓟ"] = "ⓟ", + ["Ⓠ"] = "ⓠ", + ["Ⓡ"] = "ⓡ", + ["Ⓢ"] = "ⓢ", + ["Ⓣ"] = "ⓣ", + ["Ⓤ"] = "ⓤ", + ["Ⓥ"] = "ⓥ", + ["Ⓦ"] = "ⓦ", + ["Ⓧ"] = "ⓧ", + ["Ⓨ"] = "ⓨ", + ["Ⓩ"] = "ⓩ", + ["Ⰰ"] = "ⰰ", + ["Ⰱ"] = "ⰱ", + ["Ⰲ"] = "ⰲ", + ["Ⰳ"] = "ⰳ", + ["Ⰴ"] = "ⰴ", + ["Ⰵ"] = "ⰵ", + ["Ⰶ"] = "ⰶ", + ["Ⰷ"] = "ⰷ", + ["Ⰸ"] = "ⰸ", + ["Ⰹ"] = "ⰹ", + ["Ⰺ"] = "ⰺ", + ["Ⰻ"] = "ⰻ", + ["Ⰼ"] = "ⰼ", + ["Ⰽ"] = "ⰽ", + ["Ⰾ"] = "ⰾ", + ["Ⰿ"] = "ⰿ", + ["Ⱀ"] = "ⱀ", + ["Ⱁ"] = "ⱁ", + ["Ⱂ"] = "ⱂ", + ["Ⱃ"] = "ⱃ", + ["Ⱄ"] = "ⱄ", + ["Ⱅ"] = "ⱅ", + ["Ⱆ"] = "ⱆ", + ["Ⱇ"] = "ⱇ", + ["Ⱈ"] = "ⱈ", + ["Ⱉ"] = "ⱉ", + ["Ⱊ"] = "ⱊ", + ["Ⱋ"] = "ⱋ", + ["Ⱌ"] = "ⱌ", + ["Ⱍ"] = "ⱍ", + ["Ⱎ"] = "ⱎ", + ["Ⱏ"] = "ⱏ", + ["Ⱐ"] = "ⱐ", + ["Ⱑ"] = "ⱑ", + ["Ⱒ"] = "ⱒ", + ["Ⱓ"] = "ⱓ", + ["Ⱔ"] = "ⱔ", + ["Ⱕ"] = "ⱕ", + ["Ⱖ"] = "ⱖ", + ["Ⱗ"] = "ⱗ", + ["Ⱘ"] = "ⱘ", + ["Ⱙ"] = "ⱙ", + ["Ⱚ"] = "ⱚ", + ["Ⱛ"] = "ⱛ", + ["Ⱜ"] = "ⱜ", + ["Ⱝ"] = "ⱝ", + ["Ⱞ"] = "ⱞ", + ["Ⱡ"] = "ⱡ", + ["Ɫ"] = "ɫ", + ["Ᵽ"] = "ᵽ", + ["Ɽ"] = "ɽ", + ["Ⱨ"] = "ⱨ", + ["Ⱪ"] = "ⱪ", + ["Ⱬ"] = "ⱬ", + ["Ⱶ"] = "ⱶ", + ["Ⲁ"] = "ⲁ", + ["Ⲃ"] = "ⲃ", + ["Ⲅ"] = "ⲅ", + ["Ⲇ"] = "ⲇ", + ["Ⲉ"] = "ⲉ", + ["Ⲋ"] = "ⲋ", + ["Ⲍ"] = "ⲍ", + ["Ⲏ"] = "ⲏ", + ["Ⲑ"] = "ⲑ", + ["Ⲓ"] = "ⲓ", + ["Ⲕ"] = "ⲕ", + ["Ⲗ"] = "ⲗ", + ["Ⲙ"] = "ⲙ", + ["Ⲛ"] = "ⲛ", + ["Ⲝ"] = "ⲝ", + ["Ⲟ"] = "ⲟ", + ["Ⲡ"] = "ⲡ", + ["Ⲣ"] = "ⲣ", + ["Ⲥ"] = "ⲥ", + ["Ⲧ"] = "ⲧ", + ["Ⲩ"] = "ⲩ", + ["Ⲫ"] = "ⲫ", + ["Ⲭ"] = "ⲭ", + ["Ⲯ"] = "ⲯ", + ["Ⲱ"] = "ⲱ", + ["Ⲳ"] = "ⲳ", + ["Ⲵ"] = "ⲵ", + ["Ⲷ"] = "ⲷ", + ["Ⲹ"] = "ⲹ", + ["Ⲻ"] = "ⲻ", + ["Ⲽ"] = "ⲽ", + ["Ⲿ"] = "ⲿ", + ["Ⳁ"] = "ⳁ", + ["Ⳃ"] = "ⳃ", + ["Ⳅ"] = "ⳅ", + ["Ⳇ"] = "ⳇ", + ["Ⳉ"] = "ⳉ", + ["Ⳋ"] = "ⳋ", + ["Ⳍ"] = "ⳍ", + ["Ⳏ"] = "ⳏ", + ["Ⳑ"] = "ⳑ", + ["Ⳓ"] = "ⳓ", + ["Ⳕ"] = "ⳕ", + ["Ⳗ"] = "ⳗ", + ["Ⳙ"] = "ⳙ", + ["Ⳛ"] = "ⳛ", + ["Ⳝ"] = "ⳝ", + ["Ⳟ"] = "ⳟ", + ["Ⳡ"] = "ⳡ", + ["Ⳣ"] = "ⳣ", + ["A"] = "a", + ["B"] = "b", + ["C"] = "c", + ["D"] = "d", + ["E"] = "e", + ["F"] = "f", + ["G"] = "g", + ["H"] = "h", + ["I"] = "i", + ["J"] = "j", + ["K"] = "k", + ["L"] = "l", + ["M"] = "m", + ["N"] = "n", + ["O"] = "o", + ["P"] = "p", + ["Q"] = "q", + ["R"] = "r", + ["S"] = "s", + ["T"] = "t", + ["U"] = "u", + ["V"] = "v", + ["W"] = "w", + ["X"] = "x", + ["Y"] = "y", + ["Z"] = "z", + ["𐐀"] = "𐐨", + ["𐐁"] = "𐐩", + ["𐐂"] = "𐐪", + ["𐐃"] = "𐐫", + ["𐐄"] = "𐐬", + ["𐐅"] = "𐐭", + ["𐐆"] = "𐐮", + ["𐐇"] = "𐐯", + ["𐐈"] = "𐐰", + ["𐐉"] = "𐐱", + ["𐐊"] = "𐐲", + ["𐐋"] = "𐐳", + ["𐐌"] = "𐐴", + ["𐐍"] = "𐐵", + ["𐐎"] = "𐐶", + ["𐐏"] = "𐐷", + ["𐐐"] = "𐐸", + ["𐐑"] = "𐐹", + ["𐐒"] = "𐐺", + ["𐐓"] = "𐐻", + ["𐐔"] = "𐐼", + ["𐐕"] = "𐐽", + ["𐐖"] = "𐐾", + ["𐐗"] = "𐐿", + ["𐐘"] = "𐑀", + ["𐐙"] = "𐑁", + ["𐐚"] = "𐑂", + ["𐐛"] = "𐑃", + ["𐐜"] = "𐑄", + ["𐐝"] = "𐑅", + ["𐐞"] = "𐑆", + ["𐐟"] = "𐑇", + ["𐐠"] = "𐑈", + ["𐐡"] = "𐑉", + ["𐐢"] = "𐑊", + ["𐐣"] = "𐑋", + ["𐐤"] = "𐑌", + ["𐐥"] = "𐑍", + ["𐐦"] = "𐑎", + ["𐐧"] = "𐑏", +} + diff --git a/RatingBuster/embeds.xml b/RatingBuster/embeds.xml new file mode 100644 index 0000000..0c79489 --- /dev/null +++ b/RatingBuster/embeds.xml @@ -0,0 +1,19 @@ + + +