├── .docmeta ├── .gitattributes ├── .pkgmeta ├── Fonts ├── Custom font - How to.txt ├── Visitor.ttf └── custom.ttf ├── LICENSE.txt ├── README.md ├── Textures ├── blank.tga ├── minimapbutton.blp └── wglass.tga ├── TinyDPS.lua └── TinyDPS.toc /.docmeta: -------------------------------------------------------------------------------- 1 | - 2 | type: markdown 3 | input-file: README.md 4 | output-page: "Main" 5 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Default 2 | * text=auto whitespace=trailing-space,space-before-tab,tab-in-indent,tabwidth=2 3 | *.md text whitespace=-blank-at-eol 4 | *.txt text 5 | 6 | # World of Warcraft UI 7 | *.lua text 8 | *.xml text 9 | *.toc text 10 | *.blp binary 11 | *.tga binary 12 | *.ttf binary 13 | *.ogg binary 14 | *.mp3 binary 15 | 16 | # CurseForge/WowAce Packager 17 | .*meta text 18 | -------------------------------------------------------------------------------- /.pkgmeta: -------------------------------------------------------------------------------- 1 | package-as: TinyDPS 2 | enable-nolib-creation: yes 3 | 4 | externals: 5 | Libs/LibStub: https://repos.wowace.com/wow/libstub/tags/1.0 6 | Libs/LibBossIDs-1.0: https://repos.wowace.com/wow/libbossids-1-0/trunk 7 | 8 | ignore: 9 | - README.md 10 | -------------------------------------------------------------------------------- /Fonts/Custom font - How to.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | The included custom font is PT Sans Narrow 4 | This is the font from TukUI (www.tukui.org) 5 | 6 | 7 | If you want another font, follow these steps: 8 | 9 | - delete "custom.ttf" 10 | - drop your own font into this folder 11 | - rename it to "custom.ttf" 12 | - (re)start warcraft -------------------------------------------------------------------------------- /Fonts/Visitor.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Talyrius/TinyDPS/83d96e796cfd51350b37a6b317617b692a1dbc59/Fonts/Visitor.ttf -------------------------------------------------------------------------------- /Fonts/custom.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Talyrius/TinyDPS/83d96e796cfd51350b37a6b317617b692a1dbc59/Fonts/custom.ttf -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright © 2010-2021 Sideshow, Talyrius . 2 | 3 | All rights reserved. 4 | 5 | Permission is granted for anyone to use, read, or otherwise interpret this software for any purpose, without any restrictions. 6 | 7 | Permission is granted for anyone to modify this software or sample from it, and to distribute such modified versions or derivative works as long as neither the names of this software nor its author(s) are used in the name or title of the work or in any other way that may cause it to be confused with this software. 8 | 9 | Permission is granted for anyone to aggregate this software with other works not derived from this software for the purpose of creating a user interface compilation for "World of Warcraft" and to distribute such compilations as long as the software is not modified in any way, including by modifying or removing any files. 10 | 11 | This software may not be distributed standalone or in any other way, in whole or in part, modified or unmodified, without specific prior written permission from the author(s) of this software. 12 | 13 | The names of this software and/or its author(s) may not be used to promote or endorse works derived from this software without specific prior written permission from the author(s) of this software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **TinyDPS is a lightweight damage and healing meter.** 2 | 3 | Looking for an addon to measure damage and healing without adversely affecting your gameplay experience? TinyDPS should suit your needs. By excluding unnecessary features (graphs, pie charts, extensive data collection, etc.) and offering a minimalistic interface, TinyDPS attempts to maintain a balance between information and performance. 4 | 5 | ## Usage 6 | * Options are available by right-clicking on the frame or minimap button. 7 | * To move the frame or button, while holding the Shift key, click and drag to the desired location. 8 | * For resizing of the frame, click and drag the bottom-right corner. 9 | * Toggling frame visibility can be accomplished by clicking on the minimap button or typing `/tdps`. 10 | * In addition to the option in the right-click menu (under Fight), all data can be reset by middle-clicking the frame or minimap button. Similarly, the back and forward mouse buttons will allow for quickly switching between displaying overall or just the current fight's damage/healing. 11 | * Available slash commands (`/tdps `): 12 | `help` or `?`, `reset` or `r`, `damage` or `d`, `healing` or `h`, `visiblebars `, `whisper `, `reportlength ` 13 | 14 | ## Known Issues and Limitations 15 | ### Intended Behavior 16 | * Pet data is attributed to the owner. 17 | * Vehicle/mounted combat data is ignored. 18 | * Overhealing is ignored. 19 | * Absorbs are added to healing. 20 | * Damage dealt to absorbs is tracked. 21 | * Unlike damage, healing won't start a new fight. 22 | 23 | ## Feedback 24 | ### Bug Reports and Feature Requests 25 | Please submit bug reports and feature requests using the [GitHub issue tracker](https://github.com/Talyrius/TinyDPS/issues). 26 | ### Comments 27 | You may leave comments at [WoWInterface](https://www.wowinterface.com/downloads/info16780-TinyDPS.html#comments). 28 | -------------------------------------------------------------------------------- /Textures/blank.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Talyrius/TinyDPS/83d96e796cfd51350b37a6b317617b692a1dbc59/Textures/blank.tga -------------------------------------------------------------------------------- /Textures/minimapbutton.blp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Talyrius/TinyDPS/83d96e796cfd51350b37a6b317617b692a1dbc59/Textures/minimapbutton.blp -------------------------------------------------------------------------------- /Textures/wglass.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Talyrius/TinyDPS/83d96e796cfd51350b37a6b317617b692a1dbc59/Textures/wglass.tga -------------------------------------------------------------------------------- /TinyDPS.lua: -------------------------------------------------------------------------------- 1 | --[[-------------------------------------------------------------------------------------------------------------------- 2 | TinyDPS - A lightweight damage and healing meter. 3 | Copyright © 2010-2021 Sideshow, Talyrius . All rights reserved. 4 | See the accompanying LICENSE file for more information. 5 | 6 | Authorized distributions: 7 | https://github.com/Talyrius/TinyDPS 8 | https://www.curseforge.com/wow/addons/tinydps 9 | https://www.wowinterface.com/downloads/info16780-TinyDPS.html 10 | --]]-------------------------------------------------------------------------------------------------------------------- 11 | 12 | ------------------------------------------------------------------------------------------------------------------------ 13 | -- Localization -- 14 | ------------------------------------------------------------------------------------------------------------------------ 15 | 16 | local tdpsL = {} 17 | 18 | if GetLocale() == "koKR" then 19 | tdpsL.fight = "전투" 20 | tdpsL.allFight = "전체 모든 전투" 21 | tdpsL.current = "현재 " 22 | tdpsL.resetAllData = "초기화" 23 | tdpsL.showDamage = "데미지 보기" 24 | tdpsL.showHealing = "힐량 보기" 25 | 26 | tdpsL.report = "보고" 27 | tdpsL.top3 = "상위 3" 28 | tdpsL.top5 = "상위 5" 29 | tdpsL.top10 = "상위 10" 30 | tdpsL.say = "일반" 31 | tdpsL.instance = "인스턴스" 32 | tdpsL.raid = "공격대" 33 | tdpsL.party = "파티" 34 | tdpsL.guild = "길드" 35 | tdpsL.officer = "지휘관" 36 | tdpsL.whisper = "귓속말" 37 | tdpsL.whisper2 = "귓속말 " 38 | tdpsL.channel = "채널" 39 | 40 | tdpsL.options = "설정" 41 | tdpsL.text = "문자" 42 | tdpsL.size = "크기" 43 | tdpsL.increase = "증가" 44 | tdpsL.decrease = "감소" 45 | tdpsL.font = "글꼴" 46 | tdpsL.layout = "표시" 47 | tdpsL.outline = "외곽선" 48 | tdpsL.nudge = "넛지" 49 | 50 | tdpsL.dps = "DPS" 51 | tdpsL.rank = "순위" 52 | tdpsL.percent = "퍼센트" 53 | tdpsL.amount = "데미지" 54 | tdpsL.short = "요약" 55 | tdpsL.none = "없음" 56 | tdpsL.thin = "얇게" 57 | tdpsL.thick = "굵게" 58 | tdpsL.shadow = "그림자" 59 | tdpsL.mono = "단색" 60 | 61 | tdpsL.bars = "바" 62 | tdpsL.height = "높이" 63 | tdpsL.spacing = "간격" 64 | tdpsL.maximum = "줄" 65 | tdpsL.oneYourself = "1 (당신)" 66 | tdpsL.five = "5" 67 | tdpsL.ten = "10" 68 | tdpsL.fifteen = "15" 69 | tdpsL.twenty = "20" 70 | tdpsL.unlimited = "? (무제한)" 71 | 72 | tdpsL.colors = "색상" 73 | tdpsL.barBackdrop = "바 색상" 74 | tdpsL.frameBorder = "테두리 색상" 75 | tdpsL.frameBackdrop = "배경 색상" 76 | tdpsL.dimClassColors = "직업 색상 어둡게" 77 | tdpsL.resetClassColors = "직업 색상 초기화" 78 | tdpsL.swapBarTextColor = "직업 색상으로 표시" 79 | 80 | tdpsL.history = " %i 전투 기록" 81 | tdpsL.keepOnlyBossFights = "보스만 세분화 유지" 82 | 83 | tdpsL.various = "전환" 84 | tdpsL.hideInPvP = "전장/투기장에서 숨김" 85 | tdpsL.hideInBattle = "Hide In Pet Battle" 86 | tdpsL.hideWhenSolo = "솔로잉시 숨김" 87 | tdpsL.hideInCombat = "Hide In Combat (needs translatation)" 88 | tdpsL.hideOutOfCombat = "비전투시 숨김" 89 | tdpsL.growUpwards = "하단을 기준으로" 90 | tdpsL.minimapButton = "미니맵 버튼 보기" 91 | tdpsL.trackSpellDetails = "툴팁에 기술/대상 보기" 92 | tdpsL.resetOnNewGroup = "새 그룹시 자동삭제" 93 | tdpsL.refreshEverySecond = "매시간 초기화" 94 | 95 | tdpsL.spells = " %i 툴팁에 표시되는 기술 갯수" 96 | tdpsL.targets = " %i 툴팁에 표시되는 대상 갯수" 97 | 98 | tdpsL.close = "취소" 99 | tdpsL.empty = "<없음>" 100 | 101 | tdpsL.helpVersion = "버젼" 102 | tdpsL.helpMove = "이동: 쉬프트를 누른채로 마우스 드래그" 103 | tdpsL.helpResize = "사이즈조절: 우측하단 모서리를 드래그" 104 | tdpsL.helpToggle = "명령: /tdps 입력시 프레임 숨김/보기" 105 | tdpsL.helpParameters1 = "/tdps help | reset | damage | healing | whisper " 106 | tdpsL.helpParameters2 = "/tdps visiblebars | reportlength " 107 | 108 | tdpsL.allClear = "모든 데이터 초기화" 109 | tdpsL.personal = "자신" 110 | tdpsL.byPets = "소환수" 111 | tdpsL.topAbilities = "상위 기술" 112 | tdpsL.topTargets = "상위 대상" 113 | 114 | tdpsL.noTarget = "잘못된 대상 혹은 대상이 선택되지 않음" 115 | tdpsL.noData = "기록할 데이터가 없음" 116 | 117 | tdpsL.tipPrefix = { 118 | d = "데미지량 -", 119 | h = "힐량 -", 120 | } 121 | tdpsL.repPrefix = { 122 | d = "데미지량 -", 123 | h = "힐량 -", 124 | } 125 | tdpsL.overallData = "전체 전투" 126 | tdpsL.currentFight = "현재 전투" 127 | tdpsL.lastFight = "마지막 전투" 128 | tdpsL.melee = "밀리" 129 | elseif GetLocale() == "ruRU" then 130 | tdpsL.fight = "Бой" 131 | tdpsL.allFight = "Общий Все бои" 132 | tdpsL.current = "Текущий" 133 | tdpsL.resetAllData = "Сбросить статистику" 134 | tdpsL.showDamage = "Показывать урон" 135 | tdpsL.showHealing = "Показывать исцеление" 136 | 137 | tdpsL.report = "Сообщить" 138 | tdpsL.top3 = "Top 3" 139 | tdpsL.top5 = "Top 5" 140 | tdpsL.top10 = "Top 10" 141 | tdpsL.say = "Сказать" 142 | tdpsL.instance = "Подземелье" 143 | tdpsL.raid = "Рейд" 144 | tdpsL.party = "Группа" 145 | tdpsL.guild = "Гильдия" 146 | tdpsL.officer = "Офицер" 147 | tdpsL.whisper = "Шепнуть" 148 | tdpsL.whisper2 = "Шепнуть " 149 | tdpsL.channel = "Канал" 150 | 151 | tdpsL.options = "Опции" 152 | tdpsL.text = "Текст" 153 | tdpsL.size = "Размер" 154 | tdpsL.increase = "Увеличить" 155 | tdpsL.decrease = "Уменьшить" 156 | tdpsL.font = "Шрифт" 157 | tdpsL.layout = "Отображать..." 158 | tdpsL.outline = "Контур" 159 | tdpsL.nudge = "Поднять текст" 160 | 161 | tdpsL.dps = "Урон в секунду" 162 | tdpsL.rank = "Ранг" 163 | tdpsL.percent = "Проценты" 164 | tdpsL.amount = "Урон" 165 | tdpsL.short = "Сократить значения" 166 | tdpsL.none = "Нет" 167 | tdpsL.thin = "Тонкий" 168 | tdpsL.thick = "Толстый" 169 | tdpsL.shadow = "Тень" 170 | tdpsL.mono = "Одноцветный" 171 | 172 | tdpsL.bars = "Полоски" 173 | tdpsL.height = "Высота" 174 | tdpsL.spacing = "Промежуток" 175 | tdpsL.maximum = "Максимум" 176 | tdpsL.oneYourself = "1 (Ваш персонаж)" 177 | tdpsL.five = "5" 178 | tdpsL.ten = "10" 179 | tdpsL.fifteen = "15" 180 | tdpsL.twenty = "20" 181 | tdpsL.unlimited = "Неограничено" 182 | 183 | tdpsL.colors = "Цвета" 184 | tdpsL.barBackdrop = "Цвет полос" 185 | tdpsL.frameBorder = "Цвет границ окна" 186 | tdpsL.frameBackdrop = "Цвет текстуры окна" 187 | tdpsL.dimClassColors = "Уменьшить яркость классовых цветов" 188 | tdpsL.resetClassColors = "Сбросить классовые цвета" 189 | tdpsL.swapBarTextColor = "Использовать цвета классов / 1 цвет для всех полос" 190 | 191 | tdpsL.history = " Боёв запоминать: %i" 192 | tdpsL.keepOnlyBossFights = "Запоминать только бои с боссами" 193 | 194 | tdpsL.various = "Дополнительно" 195 | tdpsL.hideInPvP = "Скрывать в PvP" 196 | tdpsL.hideInBattle = "Hide In Pet Battle" 197 | tdpsL.hideWhenSolo = "Скрывать вне группы" 198 | tdpsL.hideInCombat = "Скрыть в бою" 199 | tdpsL.hideOutOfCombat = "Показывать только в бою" 200 | tdpsL.growUpwards = "Отображать новые полосы над предыдущими" 201 | tdpsL.minimapButton = "Кнопка у миникарты" 202 | tdpsL.trackSpellDetails = "Показывать детали (атакуемые цели/исп. способности)" 203 | tdpsL.resetOnNewGroup = "Сбрасывать статистику при входе в группу" 204 | tdpsL.refreshEverySecond = "Обновлять статистику каждую секунду" 205 | 206 | tdpsL.spells = " Заклинаний в подсказке: %i" 207 | tdpsL.targets = " Целей в подсказке: %i" 208 | 209 | tdpsL.close = "Закрыть" 210 | tdpsL.empty = "<Нет>" 211 | 212 | tdpsL.helpVersion = "Версия" 213 | tdpsL.helpMove = "Перемещение: зажмите Shift и двигайте окно" 214 | tdpsL.helpResize = "Смена размера: двигайте стрелку в правой нижней части окна" 215 | tdpsL.helpToggle = "Команда: '/tdps' скрыть окно/показать" 216 | tdpsL.helpParameters1 = "/tdps help | reset | damage | healing | whisper " 217 | tdpsL.helpParameters2 = "/tdps visiblebars | reportlength " 218 | 219 | tdpsL.allClear = "Статистика была сброшена" 220 | tdpsL.personal = "Личный" 221 | tdpsL.byPets = "Питомец" 222 | tdpsL.topAbilities = "Наиболее используемые способности" 223 | tdpsL.topTargets = "Наиболее атакуемые цели" 224 | 225 | tdpsL.noTarget = "Возьмите в цель игрока своей фракции" 226 | tdpsL.noData = "Нет статистики для сообщения" 227 | 228 | tdpsL.tipPrefix = { 229 | d = "Урон:", 230 | h = "Исцеление:", 231 | } 232 | tdpsL.repPrefix = { 233 | d = "Урон:", 234 | h = "Исцеление:", 235 | } 236 | tdpsL.overallData = "Все бои" 237 | tdpsL.currentFight = "Текущий бой" 238 | tdpsL.lastFight = "Последний бой" 239 | tdpsL.melee = "Ближний бой" 240 | elseif GetLocale() == "deDE" then 241 | tdpsL.fight = "Kampf" 242 | tdpsL.allFight = "Gesamt Alle Kämpfe" 243 | tdpsL.current = "Aktuell" 244 | tdpsL.resetAllData = "Alle Daten zurücksetzen" 245 | tdpsL.showDamage = "Schaden anzeigen" 246 | tdpsL.showHealing = "Heilung anzeigen" 247 | 248 | tdpsL.report = "Verkünden" 249 | tdpsL.top3 = "Top 3" 250 | tdpsL.top5 = "Top 5" 251 | tdpsL.top10 = "Top 10" 252 | tdpsL.say = "Sagen" 253 | tdpsL.instance = "Instanz" 254 | tdpsL.raid = "Schlachtzug" 255 | tdpsL.party = "Gruppe" 256 | tdpsL.guild = "Gilde" 257 | tdpsL.officer = "Offizier" 258 | tdpsL.whisper = "Flüstern" 259 | tdpsL.whisper2 = "Flüstern " 260 | tdpsL.channel = "Channel" 261 | 262 | tdpsL.options = "Optionen" 263 | tdpsL.text = "Text" 264 | tdpsL.size = "Größe" 265 | tdpsL.increase = "Vergrößern" 266 | tdpsL.decrease = "Verkleinern" 267 | tdpsL.font = "Schriftart" 268 | tdpsL.layout = "Layout" 269 | tdpsL.outline = "Kontur" 270 | tdpsL.nudge = "Anstoßen" 271 | 272 | tdpsL.dps = "DPS" 273 | tdpsL.rank = "Rang" 274 | tdpsL.percent = "Prozent" 275 | tdpsL.amount = "Menge" 276 | tdpsL.short = "Kurzes Format" 277 | tdpsL.none = "Keine" 278 | tdpsL.thin = "Dünn" 279 | tdpsL.thick = "Dick" 280 | tdpsL.shadow = "Schatten" 281 | tdpsL.mono = "Monochrome" 282 | 283 | tdpsL.bars = "Leisten" 284 | tdpsL.height = "Höhe" 285 | tdpsL.spacing = "Abstand" 286 | tdpsL.maximum = "Maximum" 287 | tdpsL.oneYourself = "1 (Du selbst)" 288 | tdpsL.five = "5" 289 | tdpsL.ten = "10" 290 | tdpsL.fifteen = "15" 291 | tdpsL.twenty = "20" 292 | tdpsL.unlimited = "? (Unbegrenzt)" 293 | 294 | tdpsL.colors = "Farben" 295 | tdpsL.barBackdrop = "Leisten - Hintergrund" 296 | tdpsL.frameBorder = "Fenster - Rand" 297 | tdpsL.frameBackdrop = "Fenster - Hintergrund" 298 | tdpsL.dimClassColors = "Klassenfarben verdunkeln" 299 | tdpsL.resetClassColors = "Klassenfarben zurücksetzen" 300 | tdpsL.swapBarTextColor = "Leisten/Text Farben austauschen" 301 | 302 | tdpsL.history = " %i Historische Kämpfe" 303 | tdpsL.keepOnlyBossFights = "Nur Bosskämpfe behalten" 304 | 305 | tdpsL.various = "Verschiedenes" 306 | tdpsL.hideInPvP = "In PvP verstecken" 307 | tdpsL.hideInBattle = "Hide In Pet Battle" 308 | tdpsL.hideWhenSolo = "Wenn solo, verstecken" 309 | tdpsL.hideInCombat = "Hide In Combat (needs translatation)" 310 | tdpsL.hideOutOfCombat = "Außerhalb des Kampfes verstecken" 311 | tdpsL.growUpwards = "Aufwärts auflisten" 312 | tdpsL.minimapButton = "Minimap Button" 313 | tdpsL.trackSpellDetails = "Zauber Details aufzeichnen" 314 | tdpsL.resetOnNewGroup = "Bei neuer Gruppe zurücksetzen" 315 | tdpsL.refreshEverySecond = "Jede Sekunde aktualisieren" 316 | 317 | tdpsL.spells = " %i Zauber in Tooltips" 318 | tdpsL.targets = " %i Ziele in Tooltips" 319 | 320 | tdpsL.close = "Abbrechen" 321 | tdpsL.empty = "" 322 | 323 | tdpsL.helpVersion = "Version" 324 | tdpsL.helpMove = "move: Halte Umschalt gedrückt und bewege das Fenster" 325 | tdpsL.helpResize = "resize: An der unteren rechten Ecke ziehen" 326 | tdpsL.helpToggle = "command: Tippe /tdps ein um das Fenster anzuzeigen/auszublenden" 327 | tdpsL.helpParameters1 = "/tdps help | reset | damage | healing | whisper " 328 | tdpsL.helpParameters2 = "/tdps visiblebars | reportlength " 329 | 330 | tdpsL.allClear = "Alle Daten wurden zurückgesetzt" 331 | tdpsL.personal = "Persönlich" 332 | tdpsL.byPets = "Durch Begleiter" 333 | tdpsL.topAbilities = "Top Fähigkeiten" 334 | tdpsL.topTargets = "Top Ziele" 335 | 336 | tdpsL.noTarget = "Ungültig oder kein Ziel ausgewählt" 337 | tdpsL.noData = "Keine Daten vorhanden zum Verkünden" 338 | 339 | tdpsL.tipPrefix = { 340 | d = "Schaden für", 341 | h = "Heilung für", 342 | } 343 | tdpsL.repPrefix = { 344 | d = "Schaden gemacht für", 345 | h = "Geheilt für", 346 | } 347 | tdpsL.overallData = "gesamte Daten" 348 | tdpsL.currentFight = "aktuellen Kampf" 349 | tdpsL.lastFight = "letzten Kampf" 350 | tdpsL.melee = "Nahkampf" 351 | elseif GetLocale() == "frFR" then 352 | tdpsL.fight = "Combat" 353 | tdpsL.allFight = "L'ensemble de tous les combats" 354 | tdpsL.current = "Actuel" 355 | tdpsL.resetAllData = "Réinitialiser toutes les données" 356 | tdpsL.showDamage = "Voir les dommages" 357 | tdpsL.showHealing = "Voir les soins" 358 | 359 | tdpsL.report = "Rapport" 360 | tdpsL.top3 = "Top 3" 361 | tdpsL.top5 = "Top 5" 362 | tdpsL.top10 = "Top 10" 363 | tdpsL.say = "Dire" 364 | tdpsL.instance = "Instance" 365 | tdpsL.raid = "Raid" 366 | tdpsL.party = "Groupe" 367 | tdpsL.guild = "Guilde" 368 | tdpsL.officer = "Officer" 369 | tdpsL.whisper = "Chuchoter à la cible" 370 | tdpsL.whisper2 = "Chuchoter " 371 | tdpsL.channel = "Canal" 372 | 373 | tdpsL.options = "Options" 374 | tdpsL.text = "Texte" 375 | tdpsL.size = "Taille" 376 | tdpsL.increase = "Agrandir" 377 | tdpsL.decrease = "Réduire" 378 | tdpsL.font = "Fonte" 379 | tdpsL.layout = "Disposition" 380 | tdpsL.outline = "Contour" 381 | tdpsL.nudge = "Démarrer" 382 | 383 | tdpsL.dps = "DPS" 384 | tdpsL.rank = "Classement" 385 | tdpsL.percent = "Pourcentage" 386 | tdpsL.amount = "Quantité" 387 | tdpsL.short = "Format court" 388 | tdpsL.none = "Aucun" 389 | tdpsL.thin = "Mince" 390 | tdpsL.thick = "Épais" 391 | tdpsL.shadow = "Ombre" 392 | tdpsL.mono = "Monochrome" 393 | 394 | tdpsL.bars = "Bars" 395 | tdpsL.height = "Hauteur" 396 | tdpsL.spacing = "Espacement" 397 | tdpsL.maximum = "Barres visibles" 398 | tdpsL.oneYourself = "1 (Vous-même)" 399 | tdpsL.five = "5" 400 | tdpsL.ten = "10" 401 | tdpsL.fifteen = "15" 402 | tdpsL.twenty = "20" 403 | tdpsL.unlimited = "? (Illimité)" 404 | 405 | tdpsL.colors = "Couleurs" 406 | tdpsL.barBackdrop = "Bar fond" 407 | tdpsL.frameBorder = "Bordure de la fenêtre" 408 | tdpsL.frameBackdrop = "Fond de la fenêtre" 409 | tdpsL.dimClassColors = "Couleurs sombres de classe" 410 | tdpsL.resetClassColors = "Réinitialiser les couleurs de classe" 411 | tdpsL.swapBarTextColor = "Changer la bar/Couleur du texte" 412 | 413 | tdpsL.history = " %i Combats historiques" 414 | tdpsL.keepOnlyBossFights = "Garde seulement les combats des boss" 415 | 416 | tdpsL.various = "Divers" 417 | tdpsL.hideAlways = "Toujours cacher" 418 | tdpsL.hideInPvP = "Cacher en PvP" 419 | tdpsL.hideInBattle = "Hide In Pet Battle" 420 | tdpsL.hideWhenSolo = "Cacher en mode solo" 421 | tdpsL.hideInCombat = "Cacher en Combat" 422 | tdpsL.hideOutOfCombat = "Cacher hors combat" 423 | tdpsL.growUpwards = "Direction vers le haut" 424 | tdpsL.minimapButton = "Bouton sur la Minicarte" 425 | tdpsL.trackSpellDetails = "Suivre les détails des sorts" 426 | tdpsL.resetOnNewGroup = "Réinitialiser le nouveau groupe" 427 | tdpsL.refreshEverySecond = "Rafraîchir Chaque Seconde" 428 | 429 | tdpsL.spells = " %i Sorts dans les infobulles" 430 | tdpsL.targets = " %i Objectifs dans les infobulles" 431 | 432 | tdpsL.close = "Annuler" 433 | tdpsL.empty = "" 434 | 435 | tdpsL.helpVersion = "Version" 436 | tdpsL.helpMove = "Pour déplacer: Maintenez la touche Maj et faites glisser le cadre" 437 | tdpsL.helpResize = "Redimensionner: Faites glisser le coin inférieur droit" 438 | tdpsL.helpToggle = "Commande: Taper '/tdps' pour masquer ou afficher" 439 | tdpsL.helpParameters1 = "/tdps help | reset | damage | healing | whisper " 440 | tdpsL.helpParameters2 = "/tdps visiblebars | reportlength " 441 | 442 | tdpsL.allClear = "Toutes les données ont été réinitialisées" 443 | tdpsL.personal = "Personnel" 444 | tdpsL.byPets = "Par Pet(s)" 445 | tdpsL.topAbilities = "Capacités utilisées le plus en combat" 446 | tdpsL.topTargets = "Tes cibles principales" 447 | 448 | tdpsL.noTarget = "Cible non valide ou non sélectionné" 449 | tdpsL.noData = "Aucune donnée à afficher pour le moment" 450 | 451 | tdpsL.tipPrefix = { 452 | d = "Donnée des dommages pour", 453 | h = "Données des soins pour", 454 | } 455 | tdpsL.repPrefix = { 456 | d = "Dommages causés par", 457 | h = "Soins causés par", 458 | } 459 | tdpsL.overallData = "Les données globales" 460 | tdpsL.currentFight = "Le combat actuel" 461 | tdpsL.lastFight = "Le dernier combat" 462 | tdpsL.melee = "Mêlée" 463 | elseif GetLocale() == "itIT" then 464 | tdpsL.fight = "Scontro" 465 | tdpsL.allFight = "Totale di tutti gli scontri (Overall Data)" 466 | tdpsL.current = "Corrente" 467 | tdpsL.resetAllData = "Riazzera tutti i dati" 468 | tdpsL.showDamage = "Mostra i danni" 469 | tdpsL.showHealing = "Mostra le cure" 470 | 471 | tdpsL.report = "Riporta" 472 | tdpsL.top3 = "Migliori 3" 473 | tdpsL.top5 = "Migliori 5" 474 | tdpsL.top10 = "Migliori 10" 475 | tdpsL.say = "Dici" 476 | tdpsL.instance = "Istance" 477 | tdpsL.raid = "Incursione" 478 | tdpsL.party = "Gruppo" 479 | tdpsL.guild = "Gilda" 480 | tdpsL.officer = "Ufficiali" 481 | tdpsL.whisper = "Sussurro al bersaglio" 482 | tdpsL.whisper2 = "Sussurro a " 483 | tdpsL.channel = "Canale" 484 | 485 | tdpsL.options = "Opzioni" 486 | tdpsL.text = "Testo" 487 | tdpsL.size = "Dimensioni" 488 | tdpsL.increase = "Ingrandisci" 489 | tdpsL.decrease = "Rimpicciolisci" 490 | tdpsL.font = "Carattere" 491 | tdpsL.layout = "Disposizione" 492 | tdpsL.outline = "Contorno" 493 | tdpsL.nudge = "Avvio" 494 | 495 | tdpsL.dps = "DPS" 496 | tdpsL.rank = "Rango" 497 | tdpsL.percent = "Percentuale" 498 | tdpsL.amount = "Ammontare" 499 | tdpsL.short = "Formato abbreviato" 500 | tdpsL.none = "Nessuno" 501 | tdpsL.thin = "Leggero" 502 | tdpsL.thick = "Pesante" 503 | tdpsL.shadow = "Ombreggiato" 504 | tdpsL.mono = "Monocromatico" 505 | 506 | tdpsL.bars = "Barre" 507 | tdpsL.height = "Altezza" 508 | tdpsL.spacing = "Spaziatura" 509 | tdpsL.maximum = "Barre visibili" 510 | tdpsL.oneYourself = "1 (Te stesso)" 511 | tdpsL.five = "5" 512 | tdpsL.ten = "10" 513 | tdpsL.fifteen = "15" 514 | tdpsL.twenty = "20" 515 | tdpsL.unlimited = "? (Illimitate)" 516 | 517 | tdpsL.colors = "Colori" 518 | tdpsL.barBackdrop = "Sfondo delle barre" 519 | tdpsL.frameBorder = "Bordo del riquadro" 520 | tdpsL.frameBackdrop = "Sfondo del riquadro" 521 | tdpsL.dimClassColors = "Scurisci i colori delle classi" 522 | tdpsL.resetClassColors = "Ripristina i colori delle classi" 523 | tdpsL.swapBarTextColor = "Scambia il colore tra barra e testo" 524 | 525 | tdpsL.history = " %i Storico degli scontri" 526 | tdpsL.keepOnlyBossFights = "Conserva solo gli scontri contro un boss" 527 | 528 | tdpsL.various = "Varie" 529 | tdpsL.hideAlways = "Nascondi sempre" 530 | tdpsL.hideInPvP = "Nascondi in PvP" 531 | tdpsL.hideInBattle = "Hide In Pet Battle" 532 | tdpsL.hideWhenSolo = "Nascondi in solitaria" 533 | tdpsL.hideInCombat = "Nascondi in combattimento" 534 | tdpsL.hideOutOfCombat = "Nascondi fuori dal combattimento" 535 | tdpsL.growUpwards = "Sviluppa verso l'alto" 536 | tdpsL.minimapButton = "Pulsante della minimappa" 537 | tdpsL.trackSpellDetails = "Traccia i dettagli degli incantesimi" 538 | tdpsL.resetOnNewGroup = "Riazzera con un nuovo gruppo" 539 | tdpsL.refreshEverySecond = "Aggiorna ogni secondo" 540 | 541 | tdpsL.spells = " %i Incantesimi nei suggerimenti" 542 | tdpsL.targets = " %i Bersagli nei suggerimenti" 543 | 544 | tdpsL.close = "Cancella" 545 | tdpsL.empty = "" 546 | 547 | tdpsL.helpVersion = "Versione" 548 | tdpsL.helpMove = "muovi: tieni premuto shift e trascina il riquadro" 549 | tdpsL.helpResize = "ridimensiona: trascina l'angolo destro in basso" 550 | tdpsL.helpToggle = "visibilità: digita /tdps per nascondere o visualizzare" 551 | tdpsL.helpParameters1 = "/tdps help | reset | damage | healing | whisper " 552 | tdpsL.helpParameters2 = "/tdps visiblebars | reportlength " 553 | 554 | tdpsL.allClear = "Tutti i dati sono stati azzerati" 555 | tdpsL.personal = "Personale" 556 | tdpsL.byPets = "Famigli" 557 | tdpsL.topAbilities = "Abilità migliori" 558 | tdpsL.topTargets = "Bersagli migliori" 559 | 560 | tdpsL.noTarget = "Bersaglio invalido o non selezionato" 561 | tdpsL.noData = "Nessun dato da riportare" 562 | 563 | tdpsL.tipPrefix = { 564 | d = "Danno per", 565 | h = "Cura per", 566 | } 567 | tdpsL.repPrefix = { 568 | d = "Danno fatto per", 569 | h = "Cura fatta per", 570 | } 571 | tdpsL.overallData = "dati complessivi" 572 | tdpsL.currentFight = "scontro corrente" 573 | tdpsL.lastFight = "ultimo scontro" 574 | tdpsL.melee = "mischia" 575 | elseif GetLocale() == "zhCN" then 576 | tdpsL.fight = "战斗" 577 | tdpsL.allFight = "总体 所有战斗" 578 | tdpsL.current = "当前" 579 | tdpsL.resetAllData = "重置所有数据" 580 | tdpsL.showDamage = "显示伤害" 581 | tdpsL.showHealing = "显示治疗" 582 | 583 | tdpsL.report = "报告" 584 | tdpsL.top3 = "前 3" 585 | tdpsL.top5 = "前 5" 586 | tdpsL.top10 = "前 10" 587 | tdpsL.say = "说话" 588 | tdpsL.instance = "副本" 589 | tdpsL.raid = "团队" 590 | tdpsL.party = "队伍" 591 | tdpsL.guild = "公会" 592 | tdpsL.officer = "官员" 593 | tdpsL.whisper = "密语目标" 594 | tdpsL.whisper2 = "密语 <名字>" 595 | tdpsL.channel = "频道" 596 | 597 | tdpsL.options = "选项" 598 | tdpsL.text = "文字" 599 | tdpsL.size = "大小" 600 | tdpsL.increase = "增加" 601 | tdpsL.decrease = "减少" 602 | tdpsL.font = "字体" 603 | tdpsL.layout = "布局" 604 | tdpsL.outline = "描边" 605 | tdpsL.nudge = "微调" 606 | 607 | tdpsL.dps = "DPS" 608 | tdpsL.rank = "排名" 609 | tdpsL.percent = "百分比" 610 | tdpsL.amount = "总量" 611 | tdpsL.short = "缩略模式" 612 | tdpsL.none = "无" 613 | tdpsL.thin = "细" 614 | tdpsL.thick = "粗" 615 | tdpsL.shadow = "阴影" 616 | tdpsL.mono = "单色" 617 | 618 | tdpsL.bars = "计量条" 619 | tdpsL.height = "高" 620 | tdpsL.spacing = "间距" 621 | tdpsL.maximum = "最多显示" 622 | tdpsL.oneYourself = "1 (自己)" 623 | tdpsL.five = "5" 624 | tdpsL.ten = "10" 625 | tdpsL.fifteen = "15" 626 | tdpsL.twenty = "20" 627 | tdpsL.unlimited = "? (所有)" 628 | 629 | tdpsL.colors = "颜色" 630 | tdpsL.barBackdrop = "计量条背景" 631 | tdpsL.frameBorder = "框架边框" 632 | tdpsL.frameBackdrop = "框架背景" 633 | tdpsL.dimClassColors = "暗淡职业颜色" 634 | tdpsL.resetClassColors = "重置职业颜色" 635 | tdpsL.swapBarTextColor = "互换计量条/文字颜色" 636 | 637 | tdpsL.history = " %i 历史战斗记录" 638 | tdpsL.keepOnlyBossFights = "只保留boss战斗记录" 639 | 640 | tdpsL.various = "个性化" 641 | tdpsL.hideAlways = "始终隐藏" 642 | tdpsL.hideInPvP = "PVP时隐藏" 643 | tdpsL.hideInBattle = "Hide In Pet Battle" 644 | tdpsL.hideWhenSolo = "Solo时隐藏" 645 | tdpsL.hideInCombat = "战斗中隐藏" 646 | tdpsL.hideOutOfCombat = "脱离战斗后隐藏" 647 | tdpsL.growUpwards = "计量条向上增长" 648 | tdpsL.minimapButton = "小地图按钮" 649 | tdpsL.trackSpellDetails = "显示法术详情" 650 | tdpsL.resetOnNewGroup = "新队伍时重置" 651 | tdpsL.refreshEverySecond = "每秒刷新" 652 | 653 | tdpsL.spells = " 前 %i 技能" 654 | tdpsL.targets = " 前 %i 目标" 655 | 656 | tdpsL.close = "关闭" 657 | tdpsL.empty = "<空>" 658 | 659 | tdpsL.helpVersion = "版本" 660 | tdpsL.helpMove = "移动: 按住 shift 鼠标左键拖动" 661 | tdpsL.helpResize = "宽: 右下角调整宽度" 662 | tdpsL.helpToggle = "输入: type /tdps 隐藏或显示" 663 | tdpsL.helpParameters1 = "/tdps help | reset | damage | healing | whisper " 664 | tdpsL.helpParameters2 = "/tdps visiblebars | reportlength " 665 | 666 | tdpsL.allClear = "所有数据已被重置" 667 | tdpsL.personal = "玩家" 668 | tdpsL.byPets = "宠物(s)" 669 | tdpsL.topAbilities = "技能" 670 | tdpsL.topTargets = "目标" 671 | 672 | tdpsL.noTarget = "无效或没有目标选择" 673 | tdpsL.noData = "没有数据报告" 674 | 675 | tdpsL.tipPrefix = { 676 | d = "伤害为", 677 | h = "治疗为", 678 | } 679 | tdpsL.repPrefix = { 680 | d = "伤害输出为", 681 | h = "治疗量为", 682 | } 683 | tdpsL.overallData = "所有战斗" 684 | tdpsL.currentFight = "当前战斗" 685 | tdpsL.lastFight = "上次战斗" 686 | tdpsL.melee = "肉搏" 687 | elseif GetLocale() == "esES" or GetLocale() == "esMX" then 688 | tdpsL.fight = "Combate" 689 | tdpsL.allFight = "Todo Todos los Combates" 690 | tdpsL.current = "Actual" 691 | tdpsL.resetAllData = "Reiniciar Todos los Datos" 692 | tdpsL.showDamage = "Mostrar DPS" 693 | tdpsL.showHealing = "Mostrar Sanacion" 694 | 695 | tdpsL.report = "Reportar" 696 | tdpsL.top3 = "Top 3" 697 | tdpsL.top5 = "Top 5" 698 | tdpsL.top10 = "Top 10" 699 | tdpsL.say = "Decir" 700 | tdpsL.instance = "Estancia" 701 | tdpsL.raid = "Banda" 702 | tdpsL.party = "Grupo" 703 | tdpsL.guild = "Hermandad" 704 | tdpsL.officer = "Oficiales" 705 | tdpsL.whisper = "Susurrar al objetivo" 706 | tdpsL.whisper2 = "Susurrar a " 707 | tdpsL.channel = "Canal" 708 | 709 | tdpsL.options = "Opciones" 710 | tdpsL.text = "Texto" 711 | tdpsL.size = "Talla" 712 | tdpsL.increase = "Aumentar" 713 | tdpsL.decrease = "Disminuir" 714 | tdpsL.font = "Fuente" 715 | tdpsL.layout = "Formato" 716 | tdpsL.outline = "Outline" 717 | tdpsL.nudge = "Nudge" 718 | 719 | tdpsL.dps = "DPS" 720 | tdpsL.rank = "Rango" 721 | tdpsL.percent = "Porcentaje" 722 | tdpsL.amount = "Cantidad" 723 | tdpsL.short = "Formato Corto" 724 | tdpsL.none = "None" 725 | tdpsL.thin = "Thin" 726 | tdpsL.thick = "Thick" 727 | tdpsL.shadow = "Shadow" 728 | tdpsL.mono = "Monochrome" 729 | 730 | tdpsL.bars = "Barras" 731 | tdpsL.height = "Altura" 732 | tdpsL.spacing = "Espaciado" 733 | tdpsL.maximum = "Barras Visibles" 734 | tdpsL.oneYourself = "1 (Tú)" 735 | tdpsL.five = "5" 736 | tdpsL.ten = "10" 737 | tdpsL.fifteen = "15" 738 | tdpsL.twenty = "20" 739 | tdpsL.unlimited = "? (Ilimitado)" 740 | 741 | tdpsL.colors = "Colores" 742 | tdpsL.barBackdrop = "Fondo de la Barra" 743 | tdpsL.frameBorder = "Borde de la Ventana" 744 | tdpsL.frameBackdrop = "Fondo de la Ventana" 745 | tdpsL.dimClassColors = "Colores de Clase Dim" 746 | tdpsL.resetClassColors = "Reestablecer Colores de Clase" 747 | tdpsL.swapBarTextColor = "Intercambiar Colores de la Barra/texto" 748 | 749 | tdpsL.history = " %i Historico de Combates" 750 | tdpsL.keepOnlyBossFights = "Registrar Solo los Combates con Jefes" 751 | 752 | tdpsL.various = "Varios" 753 | tdpsL.hideAlways = "Siempre Oculto" 754 | tdpsL.hideInPvP = "Ocultar durante JcJ" 755 | tdpsL.hideInBattle = "Hide In Pet Battle" 756 | tdpsL.hideWhenSolo = "Ocultar cuando estes solo" 757 | tdpsL.hideInCombat = "Ocultar en Combate" 758 | tdpsL.hideOutOfCombat = "Ocultar fuera de combate" 759 | tdpsL.growUpwards = "Crece hacia arriba" 760 | tdpsL.minimapButton = "Boton de Minimapa" 761 | tdpsL.trackSpellDetails = "Rastrear Detalles de Hechizos" 762 | tdpsL.resetOnNewGroup = "Reiniciar Datos en Nuevos Grupos" 763 | tdpsL.refreshEverySecond = "Actualizar cada segundo" 764 | 765 | tdpsL.spells = " %i Hechizos en Tooltip" 766 | tdpsL.targets = " %i Objetivos en Tooltip" 767 | 768 | tdpsL.close = "Cancelar" 769 | tdpsL.empty = "" 770 | 771 | tdpsL.helpVersion = "Version" 772 | tdpsL.helpMove = "mover: Presione shift y arrastre la ventana" 773 | tdpsL.helpResize = "redimensionar: arrastre la esquina inferior derecha" 774 | tdpsL.helpToggle = "Mostrar/Ocultar: escriba /tdps para mostrar/ocultar" 775 | tdpsL.helpParameters1 = "/tdps help | reset | damage | healing | whisper " 776 | tdpsL.helpParameters2 = "/tdps visiblebars | reportlength " 777 | 778 | tdpsL.allClear = "Todos los datos han sido reiniciados" 779 | tdpsL.personal = "Personal" 780 | tdpsL.byPets = "Por Mascota(s)" 781 | tdpsL.topAbilities = "Habilidades Top" 782 | tdpsL.topTargets = "Objetivos Top" 783 | 784 | tdpsL.noTarget = "Inválido o no se ha seleccionado objetivo" 785 | tdpsL.noData = "No hay datos." 786 | 787 | tdpsL.tipPrefix = { 788 | d = "DPS", 789 | h = "Sanacion", 790 | } 791 | tdpsL.repPrefix = { 792 | d = "DPS Hecho", 793 | h = "Sanacion Hecha", 794 | } 795 | tdpsL.overallData = "Todos los datos" 796 | tdpsL.currentFight = "Combate Actual" 797 | tdpsL.lastFight = "Último Combate" 798 | tdpsL.melee = "Cuerpo a Cuerpo" 799 | else 800 | tdpsL.fight = "Fight" 801 | tdpsL.allFight = "Overall All Fights" 802 | tdpsL.current = "Current" 803 | tdpsL.resetAllData = "Reset All Data" 804 | tdpsL.showDamage = "Show Damage" 805 | tdpsL.showHealing = "Show Healing" 806 | 807 | tdpsL.report = "Report" 808 | tdpsL.top3 = "Top 3" 809 | tdpsL.top5 = "Top 5" 810 | tdpsL.top10 = "Top 10" 811 | tdpsL.say = "Say" 812 | tdpsL.instance = "Instance" 813 | tdpsL.raid = "Raid" 814 | tdpsL.party = "Party" 815 | tdpsL.guild = "Guild" 816 | tdpsL.officer = "Officer" 817 | tdpsL.whisper = "Whisper Target" 818 | tdpsL.whisper2 = "Whisper " 819 | tdpsL.channel = "Channel" 820 | 821 | tdpsL.options = "Options" 822 | tdpsL.text = "Text" 823 | tdpsL.size = "Size" 824 | tdpsL.increase = "Increase" 825 | tdpsL.decrease = "Decrease" 826 | tdpsL.font = "Font" 827 | tdpsL.layout = "Layout" 828 | tdpsL.outline = "Outline" 829 | tdpsL.nudge = "Nudge" 830 | 831 | tdpsL.dps = "DPS" 832 | tdpsL.rank = "Rank" 833 | tdpsL.percent = "Percent" 834 | tdpsL.amount = "Amount" 835 | tdpsL.short = "Short Format" 836 | tdpsL.none = "None" 837 | tdpsL.thin = "Thin" 838 | tdpsL.thick = "Thick" 839 | tdpsL.shadow = "Shadow" 840 | tdpsL.mono = "Monochrome" 841 | 842 | tdpsL.bars = "Bars" 843 | tdpsL.height = "Height" 844 | tdpsL.spacing = "Spacing" 845 | tdpsL.maximum = "Visible bars" 846 | tdpsL.oneYourself = "1 (Yourself)" 847 | tdpsL.five = "5" 848 | tdpsL.ten = "10" 849 | tdpsL.fifteen = "15" 850 | tdpsL.twenty = "20" 851 | tdpsL.unlimited = "? (Unlimited)" 852 | 853 | tdpsL.colors = "Colors" 854 | tdpsL.barBackdrop = "Bar Backdrop" 855 | tdpsL.frameBorder = "Frame Border" 856 | tdpsL.frameBackdrop = "Frame Backdrop" 857 | tdpsL.dimClassColors = "Dim Class Colors" 858 | tdpsL.resetClassColors = "Reset Class Colors" 859 | tdpsL.swapBarTextColor = "Swap Bar/Text Color" 860 | 861 | tdpsL.history = " %i Historic Fights" 862 | tdpsL.keepOnlyBossFights = "Keep Only Boss Fights" 863 | 864 | tdpsL.various = "Various" 865 | tdpsL.hideAlways = "Hide Always" 866 | tdpsL.hideInPvP = "Hide In PvP" 867 | tdpsL.hideInBattle = "Hide In Pet Battle" 868 | tdpsL.hideWhenSolo = "Hide When Solo" 869 | tdpsL.hideInCombat = "Hide In Combat" 870 | tdpsL.hideOutOfCombat = "Hide Out Of Combat" 871 | tdpsL.growUpwards = "Grow Upwards" 872 | tdpsL.minimapButton = "Minimap Button" 873 | tdpsL.trackSpellDetails = "Track Spell Details" 874 | tdpsL.resetOnNewGroup = "Reset On New Group" 875 | tdpsL.refreshEverySecond = "Refresh Every Second" 876 | 877 | tdpsL.spells = " %i Spells in Tooltips" 878 | tdpsL.targets = " %i Targets in Tooltips" 879 | 880 | tdpsL.close = "Cancel" 881 | tdpsL.empty = "" 882 | 883 | tdpsL.helpVersion = "Version" 884 | tdpsL.helpMove = "move: hold shift and drag the frame" 885 | tdpsL.helpResize = "resize: drag the bottom right corner" 886 | tdpsL.helpToggle = "toggle: type /tdps to hide or show" 887 | tdpsL.helpParameters1 = "/tdps help | reset | damage | healing | whisper " 888 | tdpsL.helpParameters2 = "/tdps visiblebars | reportlength " 889 | 890 | tdpsL.allClear = "All data has been reset" 891 | tdpsL.personal = "Personal" 892 | tdpsL.byPets = "By Pet(s)" 893 | tdpsL.topAbilities = "Top Abilities" 894 | tdpsL.topTargets = "Top Targets" 895 | 896 | tdpsL.noTarget = "Invalid or no target selected" 897 | tdpsL.noData = "No data to report" 898 | 899 | tdpsL.tipPrefix = { 900 | d = "Damage for", 901 | h = "Healing for", 902 | } 903 | tdpsL.repPrefix = { 904 | d = "Damage Done for", 905 | h = "Healing Done for", 906 | } 907 | tdpsL.overallData = "Overall Data" 908 | tdpsL.currentFight = "Current Fight" 909 | tdpsL.lastFight = "Last Fight" 910 | tdpsL.melee = "Melee" 911 | end 912 | 913 | ------------------------------------------------------------------------------------------------------------------------ 914 | -- Variables -- 915 | ------------------------------------------------------------------------------------------------------------------------ 916 | 917 | local bu, bar = {}, {} 918 | local px, com 919 | local maxValue, barsWithValue 920 | local scrollPos, isMovingOrSizing = 1, false 921 | local ttSpellMerge, ttMobMerge, ttSort = {}, {}, {} 922 | local cColor 923 | 924 | local isBoss = LibStub("LibBossIDs-1.0").BossIDs 925 | local isHeal = { 926 | SPELL_ABSORBED = true, 927 | SPELL_HEAL = true, 928 | SPELL_PERIODIC_HEAL = true, 929 | } 930 | local isMiss = { 931 | SWING_MISSED = true, 932 | RANGE_MISSED = true, 933 | SPELL_MISSED = true, 934 | SPELL_PERIODIC_MISSED = true, 935 | DAMAGE_SHIELD_MISSED = true, 936 | } 937 | local isDamage = { 938 | SWING_DAMAGE = true, 939 | RANGE_DAMAGE = true, 940 | SPELL_DAMAGE = true, 941 | SPELL_PERIODIC_DAMAGE = true, 942 | DAMAGE_SHIELD = true, 943 | DAMAGE_SPLIT = true, 944 | } 945 | local isValidEvent = { 946 | SWING_DAMAGE = true, 947 | SWING_MISSED = true, 948 | RANGE_DAMAGE = true, 949 | RANGE_MISSED = true, 950 | SPELL_ABSORBED = true, 951 | SPELL_DAMAGE = true, 952 | SPELL_HEAL = true, 953 | SPELL_MISSED = true, 954 | SPELL_SUMMON = true, 955 | SPELL_PERIODIC_DAMAGE = true, 956 | SPELL_PERIODIC_HEAL = true, 957 | SPELL_PERIODIC_MISSED = true, 958 | SPELL_EXTRA_ATTACKS = true, 959 | DAMAGE_SHIELD = true, 960 | DAMAGE_SHIELD_MISSED = true, 961 | DAMAGE_SPLIT = true, 962 | } 963 | local isExcludedAbsorb = { 964 | [ 20711] = true, -- Spirit of Redemption 965 | [114556] = true, -- Purgatory 966 | [115069] = true, -- Stagger 967 | [184553] = true, -- Spirit Shift 968 | } 969 | local isExcludedNPC = { 970 | [ "76933"] = true, -- Prismatic Crystal 971 | ["103679"] = true, -- Soul Effigy 972 | } 973 | local isExcludedPet = { 974 | -- Totems 975 | [ "2630"] = true, -- Earthbind Totem 976 | [ "5913"] = true, -- Tremor Totem 977 | ["10467"] = true, -- Mana Tide Totem 978 | ["53006"] = true, -- Spirit Link Totem 979 | ["59717"] = true, -- Windwalk Totem 980 | ["60561"] = true, -- Earthgrab Totem 981 | ["61245"] = true, -- Capacitor Totem 982 | ["62002"] = true, -- Stormlash Totem 983 | -- Miscellaneous 984 | ["29742"] = true, -- Snake Wrap 985 | ["36619"] = true, -- Bone Spike 986 | ["38163"] = true, -- Swarming Shadows 987 | ["38711"] = true, -- Bone Spike 988 | ["38712"] = true, -- Bone Spike 989 | } 990 | 991 | local function initialiseSavedVariables() 992 | tdps = { 993 | speed = 2, 994 | width = 190, 995 | version = -1, 996 | autoReset = true, 997 | swapColor = true, 998 | tooltipSpells = 3, 999 | tooltipTargets = 3, 1000 | anchor = "TOPLEFT", 1001 | layout = 10, 1002 | showRank = true, 1003 | onlyBossSegments = false, 1004 | showMinimapButton = false, 1005 | spacing = 2, 1006 | barHeight = 15, 1007 | bar = {0.9, 0.9, 0.9, 1}, 1008 | barbackdrop = {1, 1, 1, 0.05}, 1009 | border = {0, 0, 0, 0.8}, 1010 | backdrop = {0, 0, 0, 0.8}, 1011 | } 1012 | 1013 | tdpsTextOffset = 0 1014 | tdpsVisibleBars = 10 1015 | tdpsReportLength = 5 1016 | 1017 | if GameFontNormal then 1018 | tdpsFont = { 1019 | name = GameFontNormal:GetFont(), 1020 | size = 12, 1021 | outline = "", 1022 | shadow = 1, 1023 | } 1024 | else 1025 | tdpsFont = { 1026 | name = [[Interface\AddOns\TinyDPS\Fonts\Visitor.ttf]], 1027 | size = 13, 1028 | outline = "OUTLINE, MONOCHROME", 1029 | shadow = 0, 1030 | } 1031 | end 1032 | 1033 | tdpsColorAlpha = .8 1034 | end 1035 | 1036 | tdpsPosition = { 1037 | x = 0, 1038 | y = 0, 1039 | } 1040 | 1041 | local function initialiseSavedVariablesPerCharacter() 1042 | tdpsVersion = -1 1043 | tdpsPet, tdpsPlayer, tdpsLink = {}, {}, {} 1044 | tdpsFight = {{ 1045 | name = tdpsL.overallData, 1046 | d = 0, h = 0 1047 | }, { 1048 | name = nil, 1049 | boss = nil, 1050 | d = 0, 1051 | h = 0 1052 | }, 1053 | } 1054 | tdpsF = 1 1055 | tdpsV = "d" 1056 | tdpsNumberOfFights = 2 1057 | end 1058 | 1059 | initialiseSavedVariables() 1060 | initialiseSavedVariablesPerCharacter() 1061 | 1062 | ------------------------------------------------------------------------------------------------------------------------ 1063 | -- Frames -- 1064 | ------------------------------------------------------------------------------------------------------------------------ 1065 | 1066 | -- anchor frame 1067 | CreateFrame("Frame", "tdpsAnchor", UIParent, "BackdropTemplate") 1068 | tdpsAnchor:SetWidth(3) 1069 | tdpsAnchor:SetHeight(3) 1070 | tdpsAnchor:SetMovable(true) 1071 | tdpsAnchor:SetPoint("CENTER", UIParent, "CENTER", 0, 0) 1072 | tdpsAnchor:SetFrameStrata("BACKGROUND") 1073 | tdpsAnchor:SetBackdrop({ 1074 | bgFile = [[Interface\AddOns\TinyDPS\Textures\blank.tga]], 1075 | edgeFile = [[Interface\AddOns\TinyDPS\Textures\blank.tga]], 1076 | tile = false, 1077 | tileSize = 1, 1078 | edgeSize = 1, 1079 | insets = { 1080 | left = 1, 1081 | right = 1, 1082 | top = 1, 1083 | bottom = 1, 1084 | }, 1085 | }) 1086 | tdpsAnchor:SetBackdropColor(0, 0, 0, 0) 1087 | tdpsAnchor:SetBackdropBorderColor(0, 0, 0, 0) 1088 | 1089 | -- main window 1090 | CreateFrame("Frame", "tdpsFrame", UIParent, "BackdropTemplate") 1091 | tdpsFrame:SetWidth(190) 1092 | tdpsFrame:SetHeight(tdps.barHeight + 4) 1093 | tdpsFrame:SetClampedToScreen(true) 1094 | tdpsFrame:EnableMouse(true) 1095 | tdpsFrame:EnableMouseWheel(true) 1096 | tdpsFrame:SetResizable(true) 1097 | tdpsFrame:SetPoint("TOPLEFT", tdpsAnchor, "TOPLEFT", 0, 0) 1098 | tdpsFrame:SetFrameStrata("MEDIUM") 1099 | tdpsFrame:SetFrameLevel(1) 1100 | tdpsFrame:SetBackdrop({ 1101 | bgFile = [[Interface\AddOns\TinyDPS\Textures\blank.tga]], 1102 | edgeFile = [[Interface\AddOns\TinyDPS\Textures\blank.tga]], 1103 | tile = false, 1104 | tileSize = 1, 1105 | edgeSize = 1, 1106 | insets = { 1107 | left = 1, 1108 | right = 1, 1109 | top = 1, 1110 | bottom = 1, 1111 | }, 1112 | }) 1113 | 1114 | -- main window animation 1115 | local tdpsAnimationGroup = tdpsFrame:CreateAnimationGroup() 1116 | local tdpsAnimation = tdpsAnimationGroup:CreateAnimation("Alpha") 1117 | tdpsAnimation:SetFromAlpha(1) 1118 | tdpsAnimation:SetToAlpha(0) 1119 | tdpsAnimation:SetDuration(.2) 1120 | tdpsAnimation:SetScript("OnFinished", function(self, requested) 1121 | tdpsRefresh() 1122 | end) 1123 | 1124 | -- title font string 1125 | tdpsFrame:CreateFontString("noData", "OVERLAY") 1126 | noData:SetPoint("CENTER", tdpsFrame, "CENTER") 1127 | noData:SetJustifyH("CENTER") 1128 | noData:SetFont(tdpsFont.name, tdpsFont.size) 1129 | noData:SetShadowColor(.1, .1, .1, 1) 1130 | noData:SetShadowOffset(tdpsFont.shadow, tdpsFont.shadow * -1) 1131 | noData:SetTextColor(1, 1, 1, .07) 1132 | noData:SetText("TinyDPS") 1133 | 1134 | -- resize frame 1135 | CreateFrame("Frame", "tdpsResizeFrame", tdpsFrame) 1136 | tdpsResizeFrame:SetFrameStrata("MEDIUM") 1137 | tdpsResizeFrame:SetFrameLevel(3) 1138 | tdpsResizeFrame:SetWidth(6) 1139 | tdpsResizeFrame:SetHeight(6) 1140 | tdpsResizeFrame:SetPoint("BOTTOMRIGHT", tdpsFrame, "BOTTOMRIGHT", 0, 0) 1141 | tdpsResizeFrame:EnableMouse(true) 1142 | tdpsResizeFrame:CreateTexture("tdpsResizeTexture") 1143 | tdpsResizeTexture:SetTexture([[Interface\Buttons\UI-AutoCastableOverlay]]) 1144 | tdpsResizeTexture:SetTexCoord(.619, .760, .612, .762) 1145 | tdpsResizeTexture:SetDesaturated(true) 1146 | tdpsResizeTexture:SetAlpha(0) 1147 | tdpsResizeTexture:ClearAllPoints() 1148 | tdpsResizeTexture:SetPoint("TOPLEFT", tdpsResizeFrame) 1149 | tdpsResizeTexture:SetPoint("BOTTOMRIGHT", tdpsResizeFrame, "BOTTOMRIGHT", 0, 0) 1150 | tdpsResizeFrame:SetScale(1.3) 1151 | 1152 | -- minimap button frame 1153 | CreateFrame("Button", "tdpsButtonFrame", Minimap) 1154 | tdpsButtonFrame:SetHeight(30) 1155 | tdpsButtonFrame:SetWidth(30) 1156 | tdpsButtonFrame:SetMovable(true) 1157 | tdpsButtonFrame:SetClampedToScreen(true) 1158 | tdpsButtonFrame:SetUserPlaced(true) 1159 | tdpsButtonFrame:EnableMouse(true) 1160 | tdpsButtonFrame:RegisterForDrag("LeftButton") 1161 | tdpsButtonFrame:SetFrameStrata("MEDIUM") 1162 | tdpsButtonFrame:SetPoint("CENTER", Minimap:GetWidth() / 2 * -1, Minimap:GetHeight() / 2 * -1) 1163 | tdpsButtonFrame:CreateTexture("tdpsButtonTexture", "BACKGROUND") 1164 | tdpsButtonTexture:SetWidth(24) 1165 | tdpsButtonTexture:SetHeight(24) 1166 | tdpsButtonTexture:SetTexture([[Interface\AddOns\TinyDPS\Textures\minimapbutton.blp]]) 1167 | tdpsButtonTexture:SetPoint("CENTER") 1168 | tdpsButtonFrame:SetNormalTexture(tdpsButtonTexture) 1169 | tdpsButtonFrame:CreateTexture("tdpsButtonTexturePushed", "BACKGROUND") 1170 | tdpsButtonTexturePushed:SetWidth(24) 1171 | tdpsButtonTexturePushed:SetHeight(24) 1172 | tdpsButtonTexturePushed:SetTexture([[Interface\AddOns\TinyDPS\Textures\minimapbutton.blp]]) 1173 | tdpsButtonTexturePushed:SetPoint("CENTER", 1, -1) 1174 | tdpsButtonFrame:SetPushedTexture(tdpsButtonTexturePushed) 1175 | tdpsButtonFrame:SetHighlightTexture([[Interface\Minimap\UI-Minimap-ZoomButton-Highlight]]) 1176 | tdpsButtonFrame:CreateTexture("tdpsButtonOverlay", "OVERLAY") 1177 | tdpsButtonOverlay:SetWidth(53) 1178 | tdpsButtonOverlay:SetHeight(53) 1179 | tdpsButtonOverlay:SetTexture([[Interface\Minimap\MiniMap-TrackingBorder]]) 1180 | tdpsButtonOverlay:SetPoint("TOPLEFT") 1181 | 1182 | -- dropdown frame 1183 | CreateFrame("Frame", "tdpsDropDown") 1184 | tdpsDropDown.displayMode = "MENU" 1185 | 1186 | ------------------------------------------------------------------------------------------------------------------------ 1187 | -- Functions -- 1188 | ------------------------------------------------------------------------------------------------------------------------ 1189 | 1190 | -- make local references to globals (faster) 1191 | local tonumber, band = tonumber, bit.band 1192 | local floor, abs = floor, abs 1193 | local sort, tremove, tinsert, wipe = sort, tremove, tinsert, wipe 1194 | local pairs, ipairs, type = pairs, ipairs, type 1195 | local strsplit, format = strsplit, format 1196 | local CombatLogGetCurrentEventInfo = CombatLogGetCurrentEventInfo 1197 | local UnitName, UnitGUID, UnitClass, UnitIsPlayer, UnitAffectingCombat = UnitName, UnitGUID, UnitClass, UnitIsPlayer, 1198 | UnitAffectingCombat 1199 | local IsInInstance, IsInRaid, IsInGroup, InCombatLockdown, IsInBattle = IsInInstance, IsInRaid, IsInGroup, 1200 | InCombatLockdown, C_PetBattles.IsInBattle 1201 | local GetNumGroupMembers, GetWorldPVPAreaInfo, GetBestMapForUnit = GetNumGroupMembers, GetWorldPVPAreaInfo, 1202 | C_Map.GetBestMapForUnit 1203 | 1204 | -- some random functions 1205 | local function round(num, idp) 1206 | return floor(num * (10 ^ (idp or 0)) + .5) / (10 ^ (idp or 0)) 1207 | end 1208 | 1209 | local function echo(str) 1210 | print("|cfffef00fTinyDPS |cff82e2eb"..(str or "")) 1211 | end 1212 | 1213 | local function getClass(name) 1214 | local _, class = UnitClass(name) 1215 | return class or "UNKNOWN" 1216 | end 1217 | 1218 | local function isPvPZone() 1219 | local uiMapID = GetBestMapForUnit("player") 1220 | local _, instanceType = IsInInstance() 1221 | local _, _, isActiveWintergrasp = GetWorldPVPAreaInfo(1) 1222 | local _, _, isActiveTolBarad = GetWorldPVPAreaInfo(2) 1223 | local _, _, isActiveAshran = GetWorldPVPAreaInfo(3) 1224 | if instanceType == "pvp" 1225 | or instanceType == "arena" 1226 | or (uiMapID == 123 and isActiveWintergrasp) 1227 | or (uiMapID == 244 and isActiveTolBarad) 1228 | or (uiMapID == 588 and isActiveAshran) then 1229 | return true 1230 | end 1231 | end 1232 | 1233 | local function nudgeText() 1234 | if tdpsTextOffset == 2 then 1235 | tdpsTextOffset = -2 1236 | else 1237 | tdpsTextOffset = tdpsTextOffset + 1 1238 | end 1239 | for i = 1, #bar do 1240 | bar[i].fontStringLeft:ClearAllPoints() 1241 | bar[i].fontStringRight:ClearAllPoints() 1242 | bar[i].fontStringRight:SetPoint("RIGHT", -1, tdpsTextOffset) 1243 | bar[i].fontStringLeft:SetPoint("LEFT", 1, tdpsTextOffset) 1244 | bar[i].fontStringLeft:SetPoint("RIGHT", bar[i].fontStringRight, "LEFT", -2, 1) 1245 | end 1246 | end 1247 | 1248 | local function report(button, channel, playerName) 1249 | if type(channel) == "number" then 1250 | destination = channel 1251 | channel = "CHANNEL" 1252 | end 1253 | 1254 | if channel == "WHISPER" then 1255 | if not playerName then 1256 | if UnitIsPlayer("target") and UnitCanCooperate("player", "target") then 1257 | destination = GetUnitName("target", true) 1258 | else 1259 | echo(tdpsL.noTarget) 1260 | return 1261 | end 1262 | else 1263 | destination = playerName 1264 | end 1265 | end 1266 | 1267 | -- make table for sorting 1268 | local report = {} 1269 | for k, v in pairs(tdpsPlayer) do 1270 | local reportPlayer = { 1271 | name = strsplit("-", tdpsPlayer[k].name), 1272 | n = tdpsPlayer[k].fight[tdpsF][tdpsV], 1273 | t = tdpsPlayer[k].fight[tdpsF].t, 1274 | } 1275 | local pet = tdpsPlayer[k].pet 1276 | for i = 1, #pet do 1277 | -- add pet number 1278 | reportPlayer.n = reportPlayer.n + tdpsPet[pet[i]].fight[tdpsF][tdpsV] 1279 | -- check time 1280 | if tdpsPet[pet[i]].fight[tdpsF].t > reportPlayer.t then 1281 | reportPlayer.t = tdpsPet[pet[i]].fight[tdpsF].t 1282 | end 1283 | end 1284 | tinsert(report, reportPlayer) 1285 | end 1286 | sort(report, function(x, y) 1287 | return x.n > y.n 1288 | end) 1289 | 1290 | -- check if there is any data 1291 | if not report[1] or report[1].n == 0 then 1292 | echo(tdpsL.noData) 1293 | return 1294 | end 1295 | 1296 | -- output report title 1297 | if tdpsF == 2 then 1298 | SendChatMessage(format("%s %s", tdpsL.repPrefix[tdpsV], tdpsL.lastFight), channel, nil, destination) 1299 | else 1300 | SendChatMessage(format("%s %s", tdpsL.repPrefix[tdpsV], tdpsFight[tdpsF].name or "?"), channel, nil, destination) 1301 | end 1302 | 1303 | -- output the text lines 1304 | for i = 1, math.min(#report, tdpsReportLength) do 1305 | if report[i].n > 0 then 1306 | SendChatMessage(format("%i. %s %i %i%% (%i)", i, report[i].name, report[i].n, report[i].n / 1307 | tdpsFight[tdpsF][tdpsV] * 100, report[i].n / report[i].t), channel, nil, destination) 1308 | end 1309 | end 1310 | end 1311 | 1312 | local function visibilityEvent() 1313 | if (tdps.hidePvP and isPvPZone()) 1314 | or (tdps.hideBattle and IsInBattle()) 1315 | or (tdps.hideSolo and not IsInGroup()) 1316 | or (tdps.hideOOC and not UnitAffectingCombat("player")) 1317 | or (tdps.hideIC and UnitAffectingCombat("player")) then 1318 | tdpsFrame:Hide() 1319 | else 1320 | tdpsFrame:Show() 1321 | tdpsRefresh() 1322 | end 1323 | end 1324 | 1325 | local function deleteSpellData() 1326 | for _, v in pairs(tdpsPlayer) do 1327 | for i = 1, #v.fight do 1328 | v.fight[i].ds, v.fight[i].hs = {}, {} 1329 | end 1330 | end 1331 | for _, v in pairs(tdpsPet) do 1332 | for i = 1, #v.fight do 1333 | v.fight[i].ds, v.fight[i].hs = {}, {} 1334 | end 1335 | end 1336 | -- cleanup memory 1337 | if not InCombatLockdown() then 1338 | collectgarbage() 1339 | end 1340 | end 1341 | 1342 | local function short(n) 1343 | if n > 999999 then 1344 | return format("%.1fM", n / 1000000) 1345 | elseif n > 9999 then 1346 | return format("%.0fK", n / 1000) 1347 | elseif n > 999 then 1348 | return format("%.1fK", n / 1000) 1349 | else 1350 | return format("%i", n) 1351 | end 1352 | end 1353 | 1354 | local textLayout = { 1355 | -- bits: 8 = dps, 4 = percentage, 2 = amount, 1 = short format. Example: 13 = 1101 = percentage and dps (short) 1356 | [0] = function(i, n, t) 1357 | bar[i].fontStringRight:SetText("") 1358 | end, 1359 | [1] = function(i, n, t) 1360 | bar[i].fontStringRight:SetText("") 1361 | end, 1362 | [2] = function(i, n, t) 1363 | bar[i].fontStringRight:SetFormattedText("%i", n) 1364 | end, 1365 | [3] = function(i, n, t) 1366 | bar[i].fontStringRight:SetText(short(n)) 1367 | end, 1368 | [4] = function(i, n, t) 1369 | bar[i].fontStringRight:SetFormattedText("%i%%", n / tdpsFight[tdpsF][tdpsV] * 100) 1370 | end, 1371 | [5] = function(i, n, t) 1372 | bar[i].fontStringRight:SetFormattedText("%i%%", n / tdpsFight[tdpsF][tdpsV] * 100) 1373 | end, 1374 | [6] = function(i, n, t) 1375 | bar[i].fontStringRight:SetFormattedText("%i%% %i", n / tdpsFight[tdpsF][tdpsV] * 100, n / t) 1376 | end, 1377 | [7] = function(i, n, t) 1378 | bar[i].fontStringRight:SetFormattedText("%s %i%%", short(n), n / tdpsFight[tdpsF][tdpsV] * 100) 1379 | end, 1380 | [8] = function(i, n, t) 1381 | bar[i].fontStringRight:SetFormattedText("%i", n / t) 1382 | end, 1383 | [9] = function(i, n, t) 1384 | bar[i].fontStringRight:SetText(short(n / t)) 1385 | end, 1386 | [10] = function(i, n, t) 1387 | bar[i].fontStringRight:SetFormattedText("%i %i", n, n / t) 1388 | end, 1389 | [11] = function(i, n, t) 1390 | bar[i].fontStringRight:SetFormattedText("%s %s", short(n), short(n / t)) 1391 | end, 1392 | [12] = function(i, n, t) 1393 | bar[i].fontStringRight:SetFormattedText("%i%% %i", n / tdpsFight[tdpsF][tdpsV] * 100, n / t) 1394 | end, 1395 | [13] = function(i, n, t) 1396 | bar[i].fontStringRight:SetFormattedText("%i%% %s", n / tdpsFight[tdpsF][tdpsV] * 100, short(n / t)) 1397 | end, 1398 | [14] = function(i, n, t) 1399 | bar[i].fontStringRight:SetFormattedText("%i %i%% %i", n, n / tdpsFight[tdpsF][tdpsV] * 100, n / t) 1400 | end, 1401 | [15] = function(i, n, t) 1402 | bar[i].fontStringRight:SetFormattedText("%s %i%% %s", short(n), n / tdpsFight[tdpsF][tdpsV] * 100, short(n / t)) 1403 | end 1404 | } 1405 | 1406 | function tdpsRefresh() 1407 | maxValue, barsWithValue = 0, 0 1408 | -- amount, time, height, pet, text, guid 1409 | local n, t, h, p, g 1410 | 1411 | -- update all bar values 1412 | for i = 1, #bar do 1413 | bar[i]:Hide() 1414 | g = bar[i].guid 1415 | n, t, p = tdpsPlayer[g].fight[tdpsF][tdpsV], tdpsPlayer[g].fight[tdpsF].t, tdpsPlayer[g].pet 1416 | for i = 1, #p do 1417 | n = n + tdpsPet[p[i]].fight[tdpsF][tdpsV] 1418 | if tdpsPet[p[i]].fight[tdpsF].t > t then 1419 | t = tdpsPet[p[i]].fight[tdpsF].t 1420 | end 1421 | end 1422 | -- update bar values 1423 | if n > 0 then 1424 | barsWithValue = barsWithValue + 1 1425 | if n > maxValue then 1426 | maxValue = n 1427 | end 1428 | textLayout[tdps.layout](i, n, t) 1429 | end 1430 | bar[i].n = n 1431 | end 1432 | 1433 | -- sort all bars 1434 | sort(bar, function(x, y) 1435 | return x.n > y.n 1436 | end) 1437 | 1438 | -- layout the bars 1439 | px = -2 1440 | if tdpsVisibleBars == 1 then 1441 | for i = 1, #bar do 1442 | if bar[i].name == UnitName("player") and bar[i].n > 0 then 1443 | bar[i]:SetMinMaxValues(0, maxValue) 1444 | bar[i]:SetValue(bar[i].n) 1445 | bar[i]:SetPoint("TOPLEFT", tdpsFrame, "TOPLEFT", 2, px) 1446 | if tdps.showRank then 1447 | bar[i].fontStringLeft:SetFormattedText("%i%s%s", i, ". ", bar[i].name) 1448 | else 1449 | bar[i].fontStringLeft:SetText(bar[i].name) 1450 | end 1451 | px = px - tdps.barHeight - tdps.spacing 1452 | bar[i]:Show() 1453 | end 1454 | end 1455 | else 1456 | local to 1457 | if barsWithValue < tdpsVisibleBars + scrollPos - 1 then 1458 | to = barsWithValue 1459 | else 1460 | to = tdpsVisibleBars + scrollPos - 1 1461 | end 1462 | for i = scrollPos, to do 1463 | bar[i]:SetWidth(tdpsFrame:GetWidth() - 4) 1464 | bar[i]:SetMinMaxValues(0, maxValue) 1465 | bar[i]:SetValue(bar[i].n) 1466 | bar[i]:SetPoint("TOPLEFT", tdpsFrame, "TOPLEFT", 2, px) 1467 | if tdps.showRank then 1468 | bar[i].fontStringLeft:SetFormattedText("%i%s%s", i, ". ", bar[i].name) 1469 | else 1470 | bar[i].fontStringLeft:SetText(bar[i].name) 1471 | end 1472 | px = px - tdps.barHeight - tdps.spacing 1473 | bar[i]:Show() 1474 | end 1475 | end 1476 | 1477 | -- set the frame height 1478 | h = abs(px) + 2 - tdps.spacing 1479 | if h < tdps.barHeight then 1480 | tdpsFrame:SetHeight(tdps.barHeight + 4) noData:Show() 1481 | else 1482 | tdpsFrame:SetHeight(h) noData:Hide() 1483 | end 1484 | end 1485 | 1486 | --[[ 1487 | local function tdpsShowStatus() 1488 | ACTION_STATUS_FADETIME = 3 1489 | if tdpsF == 2 then 1490 | ActionStatus_DisplayMessage(format("%s for Current Fight", viewTitle[tdpsV]), true) 1491 | else 1492 | ActionStatus_DisplayMessage(format("%s for %s", viewTitle[tdpsV], tdpsFight[tdpsF].name), true) 1493 | end 1494 | end 1495 | --]] 1496 | 1497 | local function changeView(button, v) 1498 | if tdpsV == v then 1499 | return 1500 | end 1501 | tdpsV = v scrollPos = 1 CloseDropDownMenus() tdpsAnimationGroup:Play() 1502 | end 1503 | 1504 | local function checkView(v) 1505 | if tdpsV == v then 1506 | return true 1507 | end 1508 | end 1509 | 1510 | local function changeFight(button, f) 1511 | if tdpsF == f then 1512 | return 1513 | else 1514 | tdpsF = f scrollPos = 1 CloseDropDownMenus() tdpsAnimationGroup:Play() 1515 | end 1516 | end 1517 | 1518 | local function checkFight(f) 1519 | if tdpsF == f then 1520 | return true 1521 | end 1522 | end 1523 | 1524 | local function changeTextLayout(button, bit) 1525 | if band(tdps.layout, bit) > 0 then 1526 | tdps.layout = tdps.layout - bit 1527 | else 1528 | tdps.layout = tdps.layout + bit 1529 | end 1530 | tdpsRefresh() 1531 | end 1532 | 1533 | local function changeNumberOfFights(button) 1534 | if tdpsNumberOfFights == 11 then 1535 | tdpsNumberOfFights = 2 1536 | else 1537 | tdpsNumberOfFights = tdpsNumberOfFights + 1 1538 | end 1539 | if button then 1540 | button:SetFormattedText(tdpsL.history, tdpsNumberOfFights - 2) 1541 | end 1542 | 1543 | -- make or delete entries for global fight data 1544 | while #tdpsFight > tdpsNumberOfFights do 1545 | tremove(tdpsFight) 1546 | end 1547 | while #tdpsFight < tdpsNumberOfFights do 1548 | tinsert(tdpsFight, { 1549 | name = nil, 1550 | boss = nil, 1551 | d = 0, 1552 | h = 0, 1553 | }) 1554 | end 1555 | 1556 | -- make or delete entries for combatants data 1557 | for _, v in pairs(tdpsPlayer) do 1558 | while #v.fight > tdpsNumberOfFights do 1559 | tremove(v.fight) 1560 | end 1561 | while #v.fight < tdpsNumberOfFights do 1562 | tinsert(v.fight, { 1563 | d = 0, 1564 | ds = {}, 1565 | h = 0, 1566 | hs = {}, 1567 | t = 0, 1568 | }) 1569 | end 1570 | end 1571 | for _, v in pairs(tdpsPet) do 1572 | while #v.fight > tdpsNumberOfFights do 1573 | tremove(v.fight) 1574 | end 1575 | while #v.fight < tdpsNumberOfFights do 1576 | tinsert(v.fight, { 1577 | d = 0, 1578 | ds = {}, 1579 | h = 0, 1580 | hs = {}, 1581 | t = 0, 1582 | }) 1583 | end 1584 | end 1585 | 1586 | --[[ adjust the current selected fight 1587 | example: selected fight is 5; user disables fight history; we now have only 2 fights (overall and current); the new 1588 | selected fight has to be 2 --]] 1589 | while not tdpsFight[tdpsF] do 1590 | tdpsF = tdpsF - 1 1591 | end 1592 | 1593 | -- cleanup memory 1594 | if not InCombatLockdown() then 1595 | collectgarbage() 1596 | end 1597 | end 1598 | 1599 | local function changeBarSpacing(button) 1600 | if tdps.spacing + 1 > 8 then 1601 | tdps.spacing = 0 1602 | else 1603 | tdps.spacing = tdps.spacing + 1 1604 | end 1605 | button:SetText(tdpsL.spacing..": "..tdps.spacing) 1606 | tdpsRefresh() 1607 | end 1608 | 1609 | local function changeBarHeight(button, d) 1610 | if tdps.barHeight + d < 2 then 1611 | tdps.barHeight = 2 1612 | elseif tdps.barHeight + d > 40 then 1613 | tdps.barHeight = 40 1614 | else 1615 | tdps.barHeight = tdps.barHeight + d 1616 | end 1617 | for i = 1, #bar do 1618 | bar[i]:SetHeight(tdps.barHeight) 1619 | end 1620 | tdpsRefresh() 1621 | end 1622 | 1623 | local function changeFont(button, change, arg) 1624 | -- check arg 1625 | if change == "font" then 1626 | tdpsFont.name = arg 1627 | end 1628 | if change == "size" then 1629 | if tdpsFont.size + arg < 4 then 1630 | tdpsFont.size = 4 1631 | elseif tdpsFont.size + arg > 30 then 1632 | tdpsFont.size = 30 1633 | else 1634 | tdpsFont.size = tdpsFont.size + arg 1635 | end 1636 | end 1637 | if change == "outline" then 1638 | tdpsFont.outline, tdpsFont.shadow = arg, 0 1639 | end 1640 | if change == "shadow" then 1641 | tdpsFont.outline, tdpsFont.shadow = "", arg 1642 | end 1643 | -- set the font 1644 | noData:SetFont(tdpsFont.name, tdpsFont.size, tdpsFont.outline) 1645 | noData:SetShadowOffset(tdpsFont.shadow, tdpsFont.shadow * -1) 1646 | for i = 1, #bar do 1647 | bar[i].fontStringLeft:SetFont(tdpsFont.name, tdpsFont.size, tdpsFont.outline) 1648 | bar[i].fontStringRight:SetFont(tdpsFont.name, tdpsFont.size, tdpsFont.outline) 1649 | bar[i].fontStringLeft:SetShadowOffset(tdpsFont.shadow, tdpsFont.shadow * -1) 1650 | bar[i].fontStringRight:SetShadowOffset(tdpsFont.shadow, tdpsFont.shadow * -1) 1651 | end 1652 | end 1653 | 1654 | local function changeBarColor() 1655 | if tdps.swapColor then 1656 | for i = 1, #bar do 1657 | bar[i]:SetStatusBarColor(cColor[tdpsPlayer[bar[i].guid].class].r, cColor[tdpsPlayer[bar[i].guid].class].g, 1658 | cColor[tdpsPlayer[bar[i].guid].class].b, tdpsColorAlpha) 1659 | bar[i].fontStringLeft:SetTextColor(tdps.bar[1], tdps.bar[2], tdps.bar[3], tdps.bar[4]) 1660 | bar[i].fontStringRight:SetTextColor(tdps.bar[1], tdps.bar[2], tdps.bar[3], tdps.bar[4]) 1661 | end 1662 | else 1663 | for i = 1, #bar do 1664 | bar[i]:SetStatusBarColor(tdps.bar[1], tdps.bar[2], tdps.bar[3], tdps.bar[4]) 1665 | bar[i].fontStringLeft:SetTextColor(cColor[tdpsPlayer[bar[i].guid].class].r, 1666 | cColor[tdpsPlayer[bar[i].guid].class].g, cColor[tdpsPlayer[bar[i].guid].class].b, tdpsColorAlpha) 1667 | bar[i].fontStringRight:SetTextColor(cColor[tdpsPlayer[bar[i].guid].class].r, 1668 | cColor[tdpsPlayer[bar[i].guid].class].g, cColor[tdpsPlayer[bar[i].guid].class].b, tdpsColorAlpha) 1669 | end 1670 | end 1671 | end 1672 | 1673 | local function changeBarBackdropColor() 1674 | for i = 1, #bar do 1675 | bar[i]:SetBackdropColor(tdps.barbackdrop[1], tdps.barbackdrop[2], tdps.barbackdrop[3], tdps.barbackdrop[4]) 1676 | end 1677 | end 1678 | 1679 | local function startNewFight(target, GUID) 1680 | local _, _, _, _, _, id = strsplit("-", GUID) 1681 | tdpsStartNewFight = false 1682 | tdpsInCombat = true 1683 | if tdpsF ~= 1 then 1684 | scrollPos = 1 1685 | end 1686 | 1687 | -- insert a new fight at position 2 1688 | if tdpsFight[2].d + tdpsFight[2].h > 0 and ((tdps.onlyBossSegments and tdpsFight[2].boss) or not 1689 | tdps.onlyBossSegments) then 1690 | tinsert(tdpsFight, 2, { 1691 | name = target or "?", 1692 | boss = isBoss[tonumber(id)], 1693 | d = 0, 1694 | h = 0, 1695 | }) 1696 | tremove(tdpsFight) 1697 | for _, v in pairs(tdpsPlayer) do 1698 | tinsert(v.fight, 2, { 1699 | d = 0, 1700 | ds = {}, 1701 | h = 0, 1702 | hs = {}, 1703 | t = 0, 1704 | }) 1705 | tremove(v.fight) 1706 | end 1707 | for _, v in pairs(tdpsPet) do 1708 | tinsert(v.fight, 2, { 1709 | d = 0, 1710 | ds = {}, 1711 | h = 0, 1712 | hs = {}, 1713 | t = 0, 1714 | }) 1715 | tremove(v.fight) 1716 | end 1717 | -- reset current fight 1718 | else 1719 | tdpsFight[2] = { 1720 | name = target or "?", 1721 | boss = isBoss[tonumber(id)], 1722 | d = 0, 1723 | h = 0, 1724 | } 1725 | for _, v in pairs(tdpsPlayer) do 1726 | v.fight[2] = { 1727 | d = 0, 1728 | ds = {}, 1729 | h = 0, 1730 | hs = {}, 1731 | t = 0, 1732 | } 1733 | end 1734 | for _, v in pairs(tdpsPet) do 1735 | v.fight[2] = { 1736 | d = 0, 1737 | ds = {}, 1738 | h = 0, 1739 | hs = {}, 1740 | t = 0, 1741 | } 1742 | end 1743 | end 1744 | end 1745 | 1746 | local function checkCombat() 1747 | if tdpsStartNewFight then 1748 | return 1749 | end 1750 | if UnitAffectingCombat("player") or UnitAffectingCombat("pet") then 1751 | tdpsInCombat = true 1752 | return 1753 | end 1754 | for i = 1, GetNumGroupMembers() do 1755 | if IsInRaid() then 1756 | if UnitAffectingCombat(format("raid%i", i)) or UnitAffectingCombat(format("raidpet%i", i)) then 1757 | tdpsInCombat = true 1758 | return 1759 | end 1760 | else 1761 | if UnitAffectingCombat(format("party%i", i)) or UnitAffectingCombat(format("partypet%i", i)) then 1762 | tdpsInCombat = true 1763 | return 1764 | end 1765 | end 1766 | end 1767 | tdpsInCombat = false 1768 | end 1769 | 1770 | local function getPetOwnerName(petGUID) 1771 | local n, s 1772 | if petGUID == UnitGUID("pet") then 1773 | n, s = UnitName("player") 1774 | if s then 1775 | return n.."-"..s 1776 | else 1777 | return n 1778 | end 1779 | else 1780 | for i = 1, GetNumGroupMembers() do 1781 | if IsInRaid() then 1782 | if petGUID == UnitGUID(format("raidpet%i", i)) then 1783 | n, s = UnitName(format("raid%i", i)) 1784 | if s then 1785 | return n.."-"..s 1786 | else 1787 | return n 1788 | end 1789 | end 1790 | else 1791 | if petGUID == UnitGUID(format("partypet%i", i)) then 1792 | n, s = UnitName(format("party%i", i)) 1793 | if s then 1794 | return n.."-"..s 1795 | else 1796 | return n 1797 | end 1798 | end 1799 | end 1800 | end 1801 | end 1802 | end 1803 | 1804 | local function getPetOwnerGUID(petGUID) 1805 | if petGUID == UnitGUID("pet") then 1806 | return UnitGUID("player") 1807 | else 1808 | for i = 1, GetNumGroupMembers() do 1809 | if IsInRaid() then 1810 | if petGUID == UnitGUID(format("raidpet%i", i)) then 1811 | return UnitGUID(format("raid%i", i)) 1812 | end 1813 | else 1814 | if petGUID == UnitGUID(format("partypet%i", i)) then 1815 | return UnitGUID(format("party%i", i)) 1816 | end 1817 | end 1818 | end 1819 | end 1820 | end 1821 | 1822 | local function isPartyPet(petGUID) 1823 | if petGUID == UnitGUID("pet") then 1824 | return true 1825 | else 1826 | for i = 1, GetNumGroupMembers() do 1827 | if IsInRaid() then 1828 | if petGUID == UnitGUID(format("raidpet%i", i)) then 1829 | return true 1830 | end 1831 | else 1832 | if petGUID == UnitGUID(format("partypet%i", i)) then 1833 | return true 1834 | end 1835 | end 1836 | end 1837 | end 1838 | end 1839 | 1840 | local function toggleMinimapButton() 1841 | tdps.showMinimapButton = not tdps.showMinimapButton 1842 | if tdps.showMinimapButton then 1843 | tdpsRefresh() 1844 | tdpsButtonFrame:Show() 1845 | else 1846 | tdpsButtonFrame:Hide() 1847 | end 1848 | end 1849 | 1850 | local function ver() 1851 | echo(tdpsL.helpVersion.." "..GetAddOnMetadata("TinyDPS", "Version").." by Sideshow (formerly) and Talyrius") 1852 | end 1853 | 1854 | local function slashhelp() 1855 | echo(tdpsL.helpParameters1) 1856 | echo(tdpsL.helpParameters2) 1857 | end 1858 | 1859 | local function help() 1860 | ver() 1861 | echo("- "..tdpsL.helpMove) 1862 | echo("- "..tdpsL.helpResize) 1863 | echo("- "..tdpsL.helpToggle) 1864 | slashhelp() 1865 | end 1866 | 1867 | local function reset() 1868 | -- hide all bars in the GUI 1869 | for i = 1, #bar do 1870 | bar[i]:ClearAllPoints() 1871 | bar[i]:Hide() 1872 | end 1873 | -- delete data 1874 | tdpsPlayer, tdpsPet, tdpsLink, tdpsFight, bar = {}, {}, {}, {}, {} 1875 | -- make new fight data 1876 | tinsert(tdpsFight, { 1877 | name = tdpsL.overallData, 1878 | d = 0, 1879 | h = 0, 1880 | }) 1881 | while #tdpsFight < tdpsNumberOfFights do 1882 | tinsert(tdpsFight, 2, { 1883 | name = nil, 1884 | boss = false, 1885 | d = 0, 1886 | h = 0, 1887 | }) 1888 | end 1889 | -- reset scroll position 1890 | scrollPos = 1 1891 | -- return to current fight if needed 1892 | if tdpsF > 2 then 1893 | tdpsF = 2 1894 | end 1895 | -- reset the window 1896 | tdpsFrame:SetHeight(tdps.barHeight + 4) 1897 | noData:Show() 1898 | -- output message 1899 | echo(tdpsL.allClear) 1900 | CloseDropDownMenus() 1901 | -- cleanup memory 1902 | if not InCombatLockdown() then 1903 | collectgarbage() 1904 | end 1905 | end 1906 | 1907 | local function toggle() 1908 | if tdpsFrame:IsVisible() then 1909 | CloseDropDownMenus() 1910 | tdps.hidePvP, tdps.hideBattle, tdps.hideSolo, tdps.hideIC, tdps.hideOOC = true, true, true, true, true 1911 | tdpsFrame:Hide() 1912 | else 1913 | CloseDropDownMenus() 1914 | tdps.hidePvP, tdps.hideBattle, tdps.hideSolo, tdps.hideIC, tdps.hideOOC = nil, nil, nil, nil, nil 1915 | tdpsRefresh() 1916 | tdpsFrame:Show() 1917 | end 1918 | PlaySound(SOUNDKIT.GS_TITLE_OPTION_EXIT) 1919 | end 1920 | 1921 | SLASH_TINYDPS1, SLASH_TINYDPS2 = "/tinydps", "/tdps" 1922 | function SlashCmdList.TINYDPS(msg, editbox) 1923 | local cmd, arg = strsplit(" ", strlower(msg)) 1924 | if cmd == "reset" or cmd == "r" then 1925 | reset() 1926 | elseif cmd == "damage" or cmd == "d" then 1927 | changeView(nil, "d") 1928 | elseif cmd == "healing" or cmd == "h" then 1929 | changeView(nil, "h") 1930 | elseif cmd == "reportlength" and tonumber(arg) then 1931 | tdpsReportLength = min(40, max(1, tonumber(arg))) 1932 | elseif cmd == "visiblebars" and tonumber(arg) then 1933 | tdpsVisibleBars = min(40, max(1, tonumber(arg))) scrollPos = 1 tdpsRefresh() 1934 | elseif cmd == "whisper" and arg then 1935 | report(nil, "WHISPER", arg) 1936 | elseif cmd == "help" or cmd == "?" then 1937 | help() 1938 | elseif cmd == "" then 1939 | toggle() 1940 | else 1941 | slashhelp() 1942 | end 1943 | end 1944 | 1945 | local function scroll(d) 1946 | if bar[1] and bar[1].n > 0 and scrollPos - d > 0 and scrollPos - d + tdpsVisibleBars <= barsWithValue + 1 and 1947 | tdpsVisibleBars > 1 then 1948 | scrollPos = scrollPos - d 1949 | tdpsRefresh() 1950 | end 1951 | end 1952 | 1953 | -- function for adding buttons in the context menu 1954 | local function newBu(...) 1955 | --[[ level, text, title, notCheckable, hasArrow, value, keepShownOnClick, func, arg1, arg2, checked, disabled, 1956 | isNotRadio, hasColorSwatch, swatchFunc, hasOpacity, opacityFunc, r, g, b, opacity, notClickable --]] 1957 | level, bu.text, bu.isTitle, bu.notCheckable, bu.hasArrow, bu.value, bu.keepShownOnClick, bu.func, bu.arg1, bu.arg2, 1958 | bu.checked, bu.disabled, bu.isNotRadio, bu.hasColorSwatch, bu.swatchFunc, bu.hasOpacity, bu.opacityFunc, bu.r, bu.g, 1959 | bu.b, bu.opacity, bu.notClickable = ... 1960 | UIDropDownMenu_AddButton(bu, level) 1961 | wipe(bu) 1962 | end 1963 | 1964 | tdpsDropDown.initialize = function(self, level) 1965 | if level == 1 then 1966 | PlaySound(SOUNDKIT.GS_TITLE_OPTION_EXIT) 1967 | newBu(level, "TinyDPS ", 1, 1) 1968 | newBu(level, tdpsL.fight, nil, 1, 1, "fight", 1) 1969 | newBu(level, tdpsL.report, nil, 1, 1, "report", 1) 1970 | newBu(level, tdpsL.options, nil, 1, 1, "options", 1) 1971 | newBu(level, tdpsL.close, nil, 1) 1972 | elseif level == 2 and UIDROPDOWNMENU_MENU_VALUE == "fight" then 1973 | newBu(level, tdpsL.allFight, nil, nil, nil, nil, nil, changeFight, 1, nil, checkFight(1)) 1974 | newBu(level, tdpsL.current.." "..(tdpsFight[2].name or tdpsL.empty), nil, nil, nil, nil, nil, changeFight, 2, 1975 | nil, checkFight(2)) 1976 | if tdpsNumberOfFights > 2 then 1977 | newBu(level, "", nil, 1, nil, nil, nil, nil, nil, nil, nil, 1) 1978 | end 1979 | for i = 3, tdpsNumberOfFights do 1980 | newBu(level, format("%s %i %s", tdpsL.fight, i - 2, (tdpsFight[i].name or tdpsL.empty)), nil, nil, nil, nil, 1981 | nil, changeFight, i, nil, checkFight(i)) 1982 | end 1983 | newBu(level, "", nil, 1, nil, nil, nil, nil, nil, nil, nil, 1) 1984 | newBu(level, tdpsL.showDamage, nil, nil, nil, nil, nil, changeView, "d", nil, checkView("d")) 1985 | newBu(level, tdpsL.showHealing, nil, nil, nil, nil, nil, changeView, "h", nil, checkView("h")) 1986 | newBu(level, "", nil, 1, nil, nil, nil, nil, nil, nil, nil, 1) 1987 | newBu(level, " "..tdpsL.resetAllData, nil, 1, nil, nil, nil, reset) 1988 | elseif level == 2 and UIDROPDOWNMENU_MENU_VALUE == "report" then 1989 | newBu(level, tdpsL.say, nil, 1, nil, nil, nil, report, "SAY") 1990 | newBu(level, tdpsL.instance, nil, 1, nil, nil, nil, report, "INSTANCE_CHAT") 1991 | newBu(level, tdpsL.raid, nil, 1, nil, nil, nil, report, "RAID") 1992 | newBu(level, tdpsL.party, nil, 1, nil, nil, nil, report, "PARTY") 1993 | newBu(level, tdpsL.guild, nil, 1, nil, nil, nil, report, "GUILD") 1994 | newBu(level, tdpsL.officer, nil, 1, nil, nil, nil, report, "OFFICER") 1995 | newBu(level, tdpsL.whisper, nil, 1, nil, nil, nil, report, "WHISPER") 1996 | newBu(level, tdpsL.whisper2, nil, 1, nil, nil, nil, function() 1997 | ChatEdit_ActivateChat(DEFAULT_CHAT_FRAME.editBox) 1998 | DEFAULT_CHAT_FRAME.editBox:SetText("/tdps whisper ") 1999 | end) 2000 | for i = 1, 20 do 2001 | local _, name = GetChannelName(i) 2002 | if name then 2003 | newBu(level, name.." ", nil, 1, nil, nil, nil, report, i) 2004 | end 2005 | end 2006 | newBu(level, "", nil, 1, nil, nil, nil, nil, nil, nil, nil, 1) 2007 | newBu(level, "Report Length: "..tdpsReportLength, nil, 1, nil, nil, nil, function() 2008 | ChatEdit_ActivateChat(DEFAULT_CHAT_FRAME.editBox) 2009 | DEFAULT_CHAT_FRAME.editBox:SetText("/tdps reportlength "..tdpsReportLength) 2010 | end) 2011 | elseif level == 2 and UIDROPDOWNMENU_MENU_VALUE == "options" then 2012 | newBu(level, tdpsL.text, nil, 1, 1, "text", 1) 2013 | newBu(level, tdpsL.bars, nil, 1, 1, "bars", 1) 2014 | newBu(level, tdpsL.colors, nil, 1, 1, "colors", 1) 2015 | newBu(level, tdpsL.various, nil, 1, 1, "various", 1) 2016 | elseif level == 3 and UIDROPDOWNMENU_MENU_VALUE == "text" then 2017 | newBu(level, tdpsL.size, nil, 1, 1, "size", 1) 2018 | newBu(level, tdpsL.font, nil, 1, 1, "font", 1) 2019 | newBu(level, tdpsL.layout, nil, 1, 1, "layout", 1) 2020 | newBu(level, tdpsL.outline, nil, 1, 1, "outline", 1) 2021 | newBu(level, format(tdpsL.nudge, tdpsTextOffset), nil, 1, nil, nil, 1, nudgeText) 2022 | elseif level == 3 and UIDROPDOWNMENU_MENU_VALUE == "bars" then 2023 | newBu(level, tdpsL.height, nil, 1, 1, "height", 1) 2024 | newBu(level, tdpsL.spacing..": "..tdps.spacing, nil, 1, nil, nil, 1, changeBarSpacing) 2025 | newBu(level, tdpsL.maximum..": "..tdpsVisibleBars, nil, 1, nil, nil, nil, function() 2026 | ChatEdit_ActivateChat(DEFAULT_CHAT_FRAME.editBox) 2027 | DEFAULT_CHAT_FRAME.editBox:SetText("/tdps visiblebars "..tdpsVisibleBars) 2028 | end) 2029 | elseif level == 3 and UIDROPDOWNMENU_MENU_VALUE == "colors" then 2030 | local st 2031 | if tdps.swapColor then 2032 | st = tdpsL.text 2033 | else 2034 | st = tdpsL.bars 2035 | end 2036 | newBu(level, st, nil, 1, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1, function() 2037 | ColorPickerOkayButton:Hide() 2038 | ColorPickerCancelButton:SetText("Close") 2039 | local red, green, blue = ColorPickerFrame:GetColorRGB() 2040 | local alpha = 1 - OpacitySliderFrame:GetValue() 2041 | tdps.bar[1], tdps.bar[2], tdps.bar[3], tdps.bar[4] = red, green, blue, alpha 2042 | changeBarColor() 2043 | end, 1, function() 2044 | local red, green, blue = ColorPickerFrame:GetColorRGB() 2045 | local alpha = 1 - OpacitySliderFrame:GetValue() 2046 | tdps.bar[1], tdps.bar[2], tdps.bar[3], tdps.bar[4] = red, green, blue, alpha 2047 | changeBarColor() 2048 | end, tdps.bar[1], tdps.bar[2], tdps.bar[3], 1 - tdps.bar[4], 1) 2049 | newBu(level, tdpsL.barBackdrop, nil, 1, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1, function() 2050 | ColorPickerOkayButton:Hide() 2051 | ColorPickerCancelButton:SetText("Close") 2052 | local red, green, blue = ColorPickerFrame:GetColorRGB() 2053 | local alpha = 1 - OpacitySliderFrame:GetValue() 2054 | tdps.barbackdrop[1], tdps.barbackdrop[2], tdps.barbackdrop[3], tdps.barbackdrop[4] = red, green, blue, alpha 2055 | changeBarBackdropColor() 2056 | end, 1, function() 2057 | local red, green, blue = ColorPickerFrame:GetColorRGB() 2058 | local alpha = 1 - OpacitySliderFrame:GetValue() 2059 | tdps.barbackdrop[1], tdps.barbackdrop[2], tdps.barbackdrop[3], tdps.barbackdrop[4] = red, green, blue, alpha 2060 | changeBarBackdropColor() 2061 | end, tdps.barbackdrop[1], tdps.barbackdrop[2], tdps.barbackdrop[3], 1 - tdps.barbackdrop[4], 1) 2062 | newBu(level, tdpsL.frameBorder, nil, 1, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1, function() 2063 | ColorPickerOkayButton:Hide() 2064 | ColorPickerCancelButton:SetText("Close") 2065 | local red, green, blue = ColorPickerFrame:GetColorRGB() 2066 | local alpha = 1 - OpacitySliderFrame:GetValue() 2067 | tdpsFrame:SetBackdropBorderColor(red, green, blue, alpha) 2068 | tdps.border[1], tdps.border[2], tdps.border[3], tdps.border[4] = red, green, blue, alpha 2069 | end, 1, function() 2070 | local red, green, blue = ColorPickerFrame:GetColorRGB() 2071 | local alpha = 1 - OpacitySliderFrame:GetValue() 2072 | tdpsFrame:SetBackdropBorderColor(red, green, blue, alpha) 2073 | tdps.border[1], tdps.border[2], tdps.border[3], tdps.border[4] = red, green, blue, alpha 2074 | end, tdps.border[1], tdps.border[2], tdps.border[3], 1 - tdps.border[4], 1) 2075 | newBu(level, tdpsL.frameBackdrop, nil, 1, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1, function() 2076 | ColorPickerOkayButton:Hide() 2077 | ColorPickerCancelButton:SetText("Close") 2078 | local red, green, blue = ColorPickerFrame:GetColorRGB() 2079 | local alpha = 1 - OpacitySliderFrame:GetValue() 2080 | tdpsFrame:SetBackdropColor(red, green, blue, alpha) 2081 | tdps.backdrop[1], tdps.backdrop[2], tdps.backdrop[3], tdps.backdrop[4] = red, green, blue, alpha 2082 | end, 1, function() 2083 | local red, green, blue = ColorPickerFrame:GetColorRGB() 2084 | local alpha = 1 - OpacitySliderFrame:GetValue() 2085 | tdpsFrame:SetBackdropColor(red, green, blue, alpha) 2086 | tdps.backdrop[1], tdps.backdrop[2], tdps.backdrop[3], tdps.backdrop[4] = red, green, blue, alpha 2087 | end, tdps.backdrop[1], tdps.backdrop[2], tdps.backdrop[3], 1 - tdps.backdrop[4], 1) 2088 | newBu(level, tdpsL.dimClassColors, nil, 1, nil, nil, 1, function() 2089 | if tdpsColorAlpha - .1 < 0 then 2090 | tdpsColorAlpha = 0 2091 | else 2092 | tdpsColorAlpha = tdpsColorAlpha - .1 2093 | end 2094 | changeBarColor() 2095 | end) 2096 | newBu(level, tdpsL.resetClassColors, nil, 1, nil, nil, 1, function() 2097 | tdpsColorAlpha = 1 2098 | changeBarColor() 2099 | end) 2100 | newBu(level, tdpsL.swapBarTextColor.." ", nil, 1, nil, nil, 1, function() 2101 | tdps.swapColor = not tdps.swapColor 2102 | if tdps.swapColor then 2103 | DropDownList3Button1:SetText(tdpsL.text) 2104 | else 2105 | DropDownList3Button1:SetText(tdpsL.bars) 2106 | end 2107 | changeBarColor() 2108 | end) 2109 | elseif level == 3 and UIDROPDOWNMENU_MENU_VALUE == "various" then 2110 | newBu(level, tdpsL.hideInPvP, nil, nil, nil, nil, 1, function() 2111 | tdps.hidePvP = not tdps.hidePvP 2112 | visibilityEvent() 2113 | end, nil, nil, tdps.hidePvP, nil, 1) 2114 | newBu(level, tdpsL.hideInBattle, nil, nil, nil, nil, 1, function() 2115 | tdps.hideBattle = not tdps.hideBattle 2116 | visibilityEvent() 2117 | end, nil, nil, tdps.hideBattle, nil, 1) 2118 | newBu(level, tdpsL.hideWhenSolo, nil, nil, nil, nil, 1, function() 2119 | tdps.hideSolo = not tdps.hideSolo 2120 | visibilityEvent() 2121 | end, nil, nil, tdps.hideSolo, nil, 1) 2122 | newBu(level, tdpsL.hideInCombat, nil, nil, nil, nil, 1, function(self) 2123 | tdps.hideIC = not tdps.hideIC 2124 | if tdps.hideIC and tdps.hideOOC then 2125 | _G[gsub(self:GetName(), "%d$", strmatch(self:GetName(), "%d$") + 1)]:Click() 2126 | end 2127 | visibilityEvent() 2128 | end, nil, nil, tdps.hideIC, nil, 1) 2129 | newBu(level, tdpsL.hideOutOfCombat, nil, nil, nil, nil, 1, function(self) 2130 | tdps.hideOOC = not tdps.hideOOC 2131 | if tdps.hideOOC and tdps.hideIC then 2132 | _G[gsub(self:GetName(), "%d$", strmatch(self:GetName(), "%d$") - 1)]:Click() 2133 | end 2134 | visibilityEvent() 2135 | end, nil, nil, tdps.hideOOC, nil, 1) 2136 | newBu(level, "", nil, 1, nil, nil, nil, nil, nil, nil, nil, 1) 2137 | newBu(level, tdpsL.growUpwards, nil, nil, nil, nil, 1, function() 2138 | if tdps.anchor == "TOPLEFT" then 2139 | tdps.anchor = "BOTTOMLEFT" 2140 | else 2141 | tdps.anchor = "TOPLEFT" 2142 | end 2143 | tdpsFrame:ClearAllPoints() 2144 | tdpsFrame:SetPoint(tdps.anchor, tdpsAnchor, tdps.anchor) 2145 | end, nil, nil, function() 2146 | if tdps.anchor == "BOTTOMLEFT" then 2147 | return true 2148 | end 2149 | end, nil, 1) 2150 | newBu(level, tdpsL.minimapButton, nil, nil, nil, nil, 1, toggleMinimapButton, nil, nil, tdps.showMinimapButton, nil, 2151 | 1) 2152 | newBu(level, tdpsL.resetOnNewGroup, nil, nil, nil, nil, 1, function() 2153 | tdps.autoReset = not tdps.autoReset 2154 | end, nil, nil, tdps.autoReset, nil, 1) 2155 | newBu(level, tdpsL.refreshEverySecond, nil, nil, nil, nil, 1, function() 2156 | if tdps.speed == 2 then 2157 | tdps.speed = 1 2158 | else 2159 | tdps.speed = 2 2160 | end 2161 | end, nil, nil, function() 2162 | if tdps.speed == 1 then 2163 | return true 2164 | end 2165 | end, nil, 1) 2166 | newBu(level, "", nil, 1, nil, nil, nil, nil, nil, nil, nil, 1) 2167 | newBu(level, tdpsL.trackSpellDetails, nil, nil, nil, nil, 1, function() 2168 | tdps.trackSpells = not tdps.trackSpells 2169 | if not tdps.trackSpells then 2170 | deleteSpellData() 2171 | end 2172 | end, nil, nil, tdps.trackSpells, nil, 1) 2173 | newBu(level, format(tdpsL.spells, tdps.tooltipSpells), nil, 1, nil, nil, 1, function() 2174 | if tdps.tooltipSpells == 10 then 2175 | tdps.tooltipSpells = 0 2176 | else 2177 | tdps.tooltipSpells = tdps.tooltipSpells + 1 2178 | end 2179 | DropDownList3Button12:SetFormattedText(tdpsL.spells, tdps.tooltipSpells) 2180 | end) 2181 | newBu(level, format(tdpsL.targets, tdps.tooltipTargets), nil, 1, nil, nil, 1, function() 2182 | if tdps.tooltipTargets == 10 then 2183 | tdps.tooltipTargets = 0 2184 | else 2185 | tdps.tooltipTargets = tdps.tooltipTargets + 1 2186 | end 2187 | DropDownList3Button13:SetFormattedText(tdpsL.targets, tdps.tooltipTargets) 2188 | end) 2189 | newBu(level, "", nil, 1, nil, nil, nil, nil, nil, nil, nil, 1) 2190 | newBu(level, tdpsL.keepOnlyBossFights, nil, nil, nil, nil, 1, function() 2191 | tdps.onlyBossSegments = not tdps.onlyBossSegments 2192 | end, nil, nil, tdps.onlyBossSegments, nil, 1) 2193 | newBu(level, format(tdpsL.history, tdpsNumberOfFights - 2), nil, 1, nil, nil, 1, changeNumberOfFights) 2194 | elseif level == 4 and UIDROPDOWNMENU_MENU_VALUE == "size" then 2195 | newBu(level, tdpsL.increase, nil, 1, nil, nil, 1, changeFont, "size", 1) 2196 | newBu(level, tdpsL.decrease, nil, 1, nil, nil, 1, changeFont, "size", -1) 2197 | elseif level == 4 and UIDROPDOWNMENU_MENU_VALUE == "font" then 2198 | if GetLocale() == "koKR" then 2199 | newBu(level, "굵은 글꼴", nil, nil, nil, nil, nil, changeFont, "font", [[Fonts\2002B.TTF]], function() 2200 | if tdpsFont.name == [[Fonts\2002B.TTF]] then 2201 | return true 2202 | end 2203 | end, nil, nil) 2204 | newBu(level, "기본 글꼴", nil, nil, nil, nil, nil, changeFont, "font", [[Fonts\2002.TTF]], function() 2205 | if tdpsFont.name == [[Fonts\2002.TTF]] then 2206 | return true 2207 | end 2208 | end, nil, nil) 2209 | newBu(level, "데미지 글꼴", nil, nil, nil, nil, nil, changeFont, "font", [[Fonts\K_Damage.TTF]], function() 2210 | if tdpsFont.name == [[Fonts\K_Damage.TTF]] then 2211 | return true 2212 | end 2213 | end, nil, nil) 2214 | newBu(level, "퀘스트 글꼴", nil, nil, nil, nil, nil, changeFont, "font", [[Fonts\K_Pagetext.TTF]], function() 2215 | if tdpsFont.name == [[Fonts\K_Pagetext.TTF]] then 2216 | return true 2217 | end 2218 | end, nil, nil) 2219 | elseif GetLocale() == "zhCN" then 2220 | newBu(level, "默认", nil, nil, nil, nil, nil, changeFont, "font", [[Fonts\ZYKai_T.TTF]], function() 2221 | if tdpsFont.name == [[Fonts\ZYKai_T.TTF]] then 2222 | return true 2223 | end 2224 | end, nil, nil) 2225 | newBu(level, "聊天", nil, nil, nil, nil, nil, changeFont, "font", [[Fonts\ZYHei.TTF]], function() 2226 | if tdpsFont.name == [[Fonts\ZYHei.TTF]] then 2227 | return true 2228 | end 2229 | end, nil, nil) 2230 | newBu(level, "伤害数字", nil, nil, nil, nil, nil, changeFont, "font", [[Fonts\ZYKai_C.TTF]], function() 2231 | if tdpsFont.name == [[Fonts\ZYKai_C.TTF]] then 2232 | return true 2233 | end 2234 | end, nil, nil) 2235 | elseif GetLocale() == "zhTW" then 2236 | newBu(level, "預設", nil, nil, nil, nil, nil, changeFont, "font", [[Fonts\bLEI00D.TTF]], function() 2237 | if tdpsFont.name == [[Fonts\bLEI00D.TTF]] then 2238 | return true 2239 | end 2240 | end, nil, nil) 2241 | newBu(level, "聊天", nil, nil, nil, nil, nil, changeFont, "font", [[Fonts\bHEI01B.TTF]], function() 2242 | if tdpsFont.name == [[Fonts\bHEI01B.TTF]] then 2243 | return true 2244 | end 2245 | end, nil, nil) 2246 | newBu(level, "傷害數字", nil, nil, nil, nil, nil, changeFont, "font", [[Fonts\bKAI00M.TTF]], function() 2247 | if tdpsFont.name == [[Fonts\bKAI00M.TTF]] then 2248 | return true 2249 | end 2250 | end, nil, nil) 2251 | newBu(level, "提示訊息", nil, nil, nil, nil, nil, changeFont, "font", [[Fonts\bHEI00M.TTF]], function() 2252 | if tdpsFont.name == [[Fonts\bHEI00M.TTF]] then 2253 | return true 2254 | end 2255 | end, nil, nil) 2256 | else 2257 | newBu(level, "Skurri", nil, nil, nil, nil, nil, changeFont, "font", [[Fonts\SKURRI.TTF]], function() 2258 | if tdpsFont.name == [[Fonts\SKURRI.TTF]] then 2259 | return true 2260 | end 2261 | end, nil, nil) 2262 | newBu(level, "Visitor", nil, nil, nil, nil, nil, changeFont, "font", 2263 | [[Interface\AddOns\TinyDPS\Fonts\visitor.ttf]], function() 2264 | if tdpsFont.name == [[Interface\AddOns\TinyDPS\Fonts\visitor.ttf]] then 2265 | return true 2266 | end 2267 | end, nil, nil) 2268 | newBu(level, "Morpheus", nil, nil, nil, nil, nil, changeFont, "font", [[Fonts\MORPHEUS.TTF]], function() 2269 | if tdpsFont.name == [[Fonts\MORPHEUS.TTF]] then 2270 | return true 2271 | end 2272 | end, nil, nil) 2273 | newBu(level, "Arial Narrow", nil, nil, nil, nil, nil, changeFont, "font", [[Fonts\ARIALN.TTF]], function() 2274 | if tdpsFont.name == [[Fonts\ARIALN.TTF]] then 2275 | return true 2276 | end 2277 | end, nil, nil) 2278 | newBu(level, "Friz Quadrata TT", nil, nil, nil, nil, nil, changeFont, "font", [[Fonts\FRIZQT__.TTF]], function() 2279 | if tdpsFont.name == [[Fonts\FRIZQT__.TTF]] then 2280 | return true 2281 | end 2282 | end, nil, nil) 2283 | end 2284 | 2285 | if GetLocale() == "ruRU" then 2286 | newBu(level, "Nimrod MT", nil, nil, nil, nil, nil, changeFont, "font", [[Fonts\NIM_____.TTF]], function() 2287 | if tdpsFont.name == [[Fonts\NIM_____.TTF]] then 2288 | return true 2289 | end 2290 | end, nil, nil) 2291 | end 2292 | 2293 | newBu(level, "Custom", nil, nil, nil, nil, nil, changeFont, "font", [[Interface\AddOns\TinyDPS\Fonts\custom.ttf]], 2294 | function() 2295 | if tdpsFont.name == [[Interface\AddOns\TinyDPS\Fonts\custom.ttf]] then 2296 | return true 2297 | end 2298 | end, nil, nil) 2299 | elseif level == 4 and UIDROPDOWNMENU_MENU_VALUE == "layout" then 2300 | newBu(level, tdpsL.dps, nil, nil, nil, nil, 1, changeTextLayout, 8, nil, function() 2301 | if band(tdps.layout, 8) > 0 then 2302 | return true 2303 | end 2304 | end, nil, 1) 2305 | newBu(level, tdpsL.rank, nil, nil, nil, nil, 1, function() 2306 | tdps.showRank = not 2307 | tdps.showRank 2308 | tdpsRefresh() 2309 | end, nil, nil, tdps.showRank, nil, 1) 2310 | newBu(level, tdpsL.percent, nil, nil, nil, nil, 1, changeTextLayout, 4, nil, function() 2311 | if band(tdps.layout, 4) > 0 then 2312 | return true 2313 | end 2314 | end, nil, 1) 2315 | newBu(level, tdpsL.amount, nil, nil, nil, nil, 1, changeTextLayout, 2, nil, function() 2316 | if band(tdps.layout, 2) > 0 then 2317 | return true 2318 | end 2319 | end, nil, 1) 2320 | newBu(level, tdpsL.short, nil, nil, nil, nil, 1, changeTextLayout, 1, nil, function() 2321 | if band(tdps.layout, 1) > 0 then 2322 | return true 2323 | end 2324 | end, nil, 1) 2325 | elseif level == 4 and UIDROPDOWNMENU_MENU_VALUE == "outline" then 2326 | newBu(level, tdpsL.none, nil, nil, nil, nil, nil, changeFont, "outline", "", function() 2327 | if tdpsFont.outline == "" and tdpsFont.shadow == 0 then 2328 | return true 2329 | end 2330 | end) 2331 | newBu(level, tdpsL.thin, nil, nil, nil, nil, nil, changeFont, "outline", "OUTLINE", function() 2332 | if tdpsFont.outline == "OUTLINE" and tdpsFont.shadow == 0 then 2333 | return true 2334 | end 2335 | end) 2336 | newBu(level, tdpsL.thick, nil, nil, nil, nil, nil, changeFont, "outline", "THICKOUTLINE", function() 2337 | if tdpsFont.outline == "THICKOUTLINE" and tdpsFont.shadow == 0 then 2338 | return true 2339 | end 2340 | end) 2341 | newBu(level, tdpsL.shadow, nil, nil, nil, nil, nil, changeFont, "shadow", 1, function() 2342 | if tdpsFont.outline == "" and tdpsFont.shadow > 0 then 2343 | return true 2344 | end 2345 | end) 2346 | newBu(level, tdpsL.mono, nil, nil, nil, nil, nil, changeFont, "outline", "OUTLINE, MONOCHROME", function() 2347 | if tdpsFont.outline == "OUTLINE, MONOCHROME" and tdpsFont.shadow == 0 then 2348 | return true 2349 | end 2350 | end) 2351 | elseif level == 4 and UIDROPDOWNMENU_MENU_VALUE == "height" then 2352 | newBu(level, tdpsL.increase, nil, 1, nil, nil, 1, changeBarHeight, 1) 2353 | newBu(level, tdpsL.decrease, nil, 1, nil, nil, 1, changeBarHeight, -1) 2354 | elseif level == 4 and UIDROPDOWNMENU_MENU_VALUE == "spacing" then 2355 | newBu(level, tdpsL.increase, nil, 1, nil, nil, 1, changeBarSpacing, 1) 2356 | newBu(level, tdpsL.decrease, nil, 1, nil, nil, 1, changeBarSpacing, -1) 2357 | end 2358 | end 2359 | 2360 | local function tdpsSpellSort(x, y) 2361 | if ttSpellMerge[x] > ttSpellMerge[y] then 2362 | return true 2363 | end 2364 | end 2365 | 2366 | local function tdpsMobSort(x, y) 2367 | if ttMobMerge[x] > ttMobMerge[y] then 2368 | return true 2369 | end 2370 | end 2371 | 2372 | local function newBar(g) 2373 | local dummybar = CreateFrame("Statusbar", "tdpsStatusBar", tdpsFrame, "BackdropTemplate") 2374 | dummybar:SetFrameStrata("MEDIUM") 2375 | dummybar:SetFrameLevel(2) 2376 | dummybar:SetOrientation("HORIZONTAL") 2377 | dummybar:EnableMouse(true) 2378 | dummybar:EnableMouseWheel(true) 2379 | dummybar:SetWidth(tdpsFrame:GetWidth() - 4) 2380 | dummybar:SetHeight(tdps.barHeight) 2381 | dummybar:Hide() 2382 | --dummybar:SetPoint("RIGHT", tdpsFrame, "RIGHT", -2, 0) 2383 | dummybar:SetBackdrop({ 2384 | bgFile = [[Interface\AddOns\TinyDPS\Textures\wglass.tga]], 2385 | edgeFile = [[Interface\AddOns\TinyDPS\Textures\blank.tga]], 2386 | tile = false, 2387 | tileSize = 1, 2388 | edgeSize = 1, 2389 | insets = { 2390 | left = 0, 2391 | right = 0, 2392 | top = 0, 2393 | bottom = 0, 2394 | } 2395 | }) 2396 | dummybar:SetStatusBarTexture([[Interface\AddOns\TinyDPS\Textures\wglass.tga]]) 2397 | 2398 | -- bar info 2399 | dummybar.name, dummybar.guid, dummybar.n = strsplit("-", tdpsPlayer[g]["name"]), g, 0 2400 | 2401 | -- scripts 2402 | dummybar:SetScript("OnEnter", function(self) 2403 | GameTooltip:SetOwner(self) 2404 | GameTooltip:SetText(tdpsPlayer[g].name) 2405 | 2406 | -- tooltip title 2407 | if tdpsF == 2 then 2408 | GameTooltip:AddLine(format("%s %s", tdpsL.tipPrefix[tdpsV], tdpsL.currentFight), 1, .85, 0) 2409 | else 2410 | GameTooltip:AddLine(format("%s %s", tdpsL.tipPrefix[tdpsV], tdpsFight[tdpsF].name or "?"), 1, .85, 0) 2411 | end 2412 | 2413 | -- own amount 2414 | GameTooltip:AddDoubleLine(tdpsL.personal, tdpsPlayer[self.guid].fight[tdpsF][tdpsV].." (" .. 2415 | round(tdpsPlayer[self.guid].fight[tdpsF][tdpsV] / (self.n) * 100, 0).."%)", 1, 1, 1, 1, 1, 1) 2416 | 2417 | -- pet amount 2418 | local pet, petAmount = tdpsPlayer[g].pet, 0 2419 | for i = 1, #pet do 2420 | petAmount = petAmount + tdpsPet[pet[i]].fight[tdpsF][tdpsV] 2421 | end 2422 | if petAmount > 0 then 2423 | GameTooltip:AddDoubleLine(tdpsL.byPets, petAmount.." ("..round(petAmount / (self.n) * 100, 0).."%)", 1, 1, 1, 1, 2424 | 1, 1) 2425 | end 2426 | 2427 | -- spell details 2428 | if tdps.trackSpells then 2429 | -- merge the data of this player 2430 | for k, v in pairs(tdpsPlayer[g].fight[tdpsF][tdpsV.."s"]) do 2431 | for kk, vv in pairs(v) do 2432 | ttSpellMerge[k] = (ttSpellMerge[k] or 0) + vv ttMobMerge[kk] = (ttMobMerge[kk] or 0) + vv 2433 | end 2434 | end 2435 | for i = 1, #pet do 2436 | for k, v in pairs(tdpsPet[pet[i]].fight[tdpsF][tdpsV.."s"]) do 2437 | for kk, vv in pairs(v) do 2438 | ttSpellMerge[k] = (ttSpellMerge[k] or 0) + vv ttMobMerge[kk] = (ttMobMerge[kk] or 0) + vv 2439 | end 2440 | end 2441 | end 2442 | 2443 | -- display spells 2444 | if tdps.tooltipSpells > 0 then 2445 | GameTooltip:AddLine(tdpsL.topAbilities, 1, .85, 0) 2446 | end 2447 | for k, v in pairs(ttSpellMerge) do 2448 | tinsert(ttSort, k) 2449 | end 2450 | sort(ttSort, tdpsSpellSort) 2451 | for i = 1, tdps.tooltipSpells do 2452 | if ttSort[i] then 2453 | GameTooltip:AddDoubleLine(i..". "..ttSort[i], ttSpellMerge[ttSort[i]].." (" .. 2454 | round(ttSpellMerge[ttSort[i]] / (self.n) * 100, 0).."%)", 1, 1, 1, 1, 1, 1) 2455 | end 2456 | end 2457 | wipe(ttSort) 2458 | 2459 | -- display targets 2460 | if tdps.tooltipTargets > 0 then 2461 | GameTooltip:AddLine(tdpsL.topTargets, 1, .85, 0) 2462 | end 2463 | for k, v in pairs(ttMobMerge) do 2464 | tinsert(ttSort, k) 2465 | end 2466 | sort(ttSort, tdpsMobSort) 2467 | for i = 1, tdps.tooltipTargets do 2468 | if ttSort[i] then 2469 | GameTooltip:AddDoubleLine(i..". "..ttSort[i], ttMobMerge[ttSort[i]].." ("..round(ttMobMerge[ttSort[i]] / 2470 | (self.n) * 100, 0).."%)", 1, 1, 1, 1, 1, 1) 2471 | end 2472 | end 2473 | wipe(ttSort) 2474 | wipe(ttSpellMerge) 2475 | wipe(ttMobMerge) 2476 | end 2477 | 2478 | -- display the tooltip 2479 | GameTooltip:Show() 2480 | end) 2481 | 2482 | dummybar:SetScript("OnLeave", function(self) 2483 | GameTooltip:Hide() 2484 | end) 2485 | 2486 | dummybar:SetScript("OnMouseDown", function(self, button) 2487 | if button == "LeftButton" and IsShiftKeyDown() then 2488 | CloseDropDownMenus() 2489 | GameTooltip:Hide() 2490 | isMovingOrSizing = true 2491 | tdpsAnchor:StartMoving() 2492 | elseif button == "RightButton" then 2493 | ToggleDropDownMenu(1, nil, tdpsDropDown, "cursor", 0, 0) 2494 | elseif button == "MiddleButton" then 2495 | reset() 2496 | elseif button == "Button4" then 2497 | changeFight(nil, 1) 2498 | elseif button == "Button5" then 2499 | changeFight(nil, 2) 2500 | end 2501 | end) 2502 | 2503 | dummybar:SetScript("OnMouseUp", function(self, button) 2504 | if button == "LeftButton" then 2505 | tdpsAnchor:StopMovingOrSizing() 2506 | isMovingOrSizing = nil 2507 | -- set position of frame 2508 | tdpsFrame:ClearAllPoints() 2509 | tdpsFrame:SetPoint(tdps.anchor, tdpsAnchor, tdps.anchor, 0, 0) 2510 | -- save position of anchor 2511 | local xOfs, yOfs = tdpsAnchor:GetCenter() 2512 | local scale = tdpsAnchor:GetEffectiveScale() 2513 | local uis = UIParent:GetScale() 2514 | xOfs = xOfs * scale - GetScreenWidth() * uis / 2 2515 | yOfs = yOfs * scale - GetScreenHeight() * uis / 2 2516 | tdpsPosition.x = xOfs / uis 2517 | tdpsPosition.y = yOfs / uis 2518 | end 2519 | end) 2520 | 2521 | dummybar:SetScript("OnMouseWheel", function(self, direction) 2522 | scroll(direction) 2523 | end) 2524 | 2525 | -- number fontstring 2526 | dummybar.fontStringRight = dummybar:CreateFontString(nil, "OVERLAY") 2527 | dummybar.fontStringRight:SetPoint("RIGHT", -1, tdpsTextOffset) 2528 | dummybar.fontStringRight:SetJustifyH("RIGHT") 2529 | dummybar.fontStringRight:SetWordWrap(false) 2530 | dummybar.fontStringRight:SetFont(tdpsFont.name, tdpsFont.size, tdpsFont.outline) 2531 | dummybar.fontStringRight:SetShadowColor(.05, .05, .05, 1) 2532 | dummybar.fontStringRight:SetShadowOffset(tdpsFont.shadow, tdpsFont.shadow * -1) 2533 | 2534 | -- name fontstring 2535 | dummybar.fontStringLeft = dummybar:CreateFontString(nil, "OVERLAY") 2536 | dummybar.fontStringLeft:SetPoint("LEFT", 1, tdpsTextOffset) 2537 | dummybar.fontStringLeft:SetPoint("RIGHT", dummybar.fontStringRight, "LEFT", -2, 1) 2538 | dummybar.fontStringLeft:SetJustifyH("LEFT") 2539 | dummybar.fontStringLeft:SetWordWrap(false) 2540 | dummybar.fontStringLeft:SetFont(tdpsFont.name, tdpsFont.size, tdpsFont.outline) 2541 | dummybar.fontStringLeft:SetShadowColor(.05, .05, .05, 1) 2542 | dummybar.fontStringLeft:SetShadowOffset(tdpsFont.shadow, tdpsFont.shadow * -1) 2543 | 2544 | -- colors 2545 | local classR, classG, classB, classA = cColor[tdpsPlayer[g].class].r, cColor[tdpsPlayer[g].class].g, 2546 | cColor[tdpsPlayer[g].class].b, tdpsColorAlpha 2547 | if tdps.swapColor then 2548 | dummybar:SetStatusBarColor(classR, classG, classB, classA) 2549 | dummybar.fontStringRight:SetTextColor(tdps.bar[1], tdps.bar[2], tdps.bar[3], tdps.bar[4]) 2550 | dummybar.fontStringLeft:SetTextColor(tdps.bar[1], tdps.bar[2], tdps.bar[3], tdps.bar[4]) 2551 | else 2552 | dummybar:SetStatusBarColor(tdps.bar[1], tdps.bar[2], tdps.bar[3], tdps.bar[4]) 2553 | dummybar.fontStringRight:SetTextColor(classR, classG, classB, classA) 2554 | dummybar.fontStringLeft:SetTextColor(classR, classG, classB, classA) 2555 | end 2556 | dummybar:SetBackdropColor(tdps.barbackdrop[1], tdps.barbackdrop[2], tdps.barbackdrop[3], tdps.barbackdrop[4]) 2557 | dummybar:SetBackdropBorderColor(0, 0, 0, 0) 2558 | 2559 | -- save bar 2560 | tinsert(bar, dummybar) 2561 | end 2562 | 2563 | local function makeCombatant(k, n, pgl, c) 2564 | if c == "PET" then 2565 | tdpsPet[k] = { 2566 | name = n, 2567 | guid = pgl, 2568 | class = c, 2569 | stamp = 0, 2570 | fight = {}, 2571 | } 2572 | while #tdpsPet[k].fight < tdpsNumberOfFights do 2573 | tinsert(tdpsPet[k].fight, { 2574 | d = 0, 2575 | ds = {}, 2576 | h = 0, 2577 | hs = {}, 2578 | t = 0, 2579 | }) 2580 | end 2581 | else 2582 | tdpsPlayer[k] = { 2583 | name = n, 2584 | pet = pgl, 2585 | class = c, 2586 | stamp = 0, 2587 | fight = {}, 2588 | } 2589 | while #tdpsPlayer[k].fight < tdpsNumberOfFights do 2590 | tinsert(tdpsPlayer[k].fight, { 2591 | d = 0, 2592 | ds = {}, 2593 | h = 0, 2594 | hs = {}, 2595 | t = 0, 2596 | }) 2597 | end 2598 | newBar(k) 2599 | end 2600 | end 2601 | 2602 | local function trackSpell(amount, target, spell, dh) 2603 | if tdps.trackSpells then 2604 | dh = dh.."s" 2605 | if not com.fight[1][dh][spell] then 2606 | -- make the spell 2607 | com.fight[1][dh][spell] = {} 2608 | end 2609 | if not com.fight[2][dh][spell] then 2610 | com.fight[2][dh][spell] = {} 2611 | end 2612 | -- record the amount 2613 | com.fight[1][dh][spell][target] = (com.fight[1][dh][spell][target] or 0) + amount 2614 | com.fight[2][dh][spell][target] = (com.fight[2][dh][spell][target] or 0) + amount 2615 | end 2616 | end 2617 | 2618 | ------------------------------------------------------------------------------------------------------------------------ 2619 | -- Combat Event Handler -- 2620 | ------------------------------------------------------------------------------------------------------------------------ 2621 | 2622 | local function tdpsCombatEvent(self, event, ...) 2623 | local timestamp, event, hideCaster, sourceGUID, sourceName, sourceFlags, sourceRaidFlags, destGUID, destName, 2624 | destFlags, destRaidFlags, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20, arg21, arg22 = ... 2625 | local _, _, _, _, _, destID = strsplit("-", destGUID) 2626 | 2627 | -- ignore events directed towards these 2628 | if isExcludedNPC[destID] then 2629 | return 2630 | end 2631 | 2632 | -- reorganize these return args for consistency 2633 | local amount, spellName 2634 | if event == "SPELL_ABSORBED" then 2635 | if type(arg12) == "number" then 2636 | -- triggered by a spell 2637 | if isExcludedAbsorb[arg19] then 2638 | return 2639 | end 2640 | sourceGUID = arg15 2641 | sourceName = arg16 2642 | sourceFlags = arg17 2643 | sourceRaidFlags = arg18 2644 | spellName = arg20 2645 | amount = arg22 2646 | else 2647 | -- triggered by a swing 2648 | if isExcludedAbsorb[arg16] then 2649 | return 2650 | end 2651 | sourceGUID = arg12 2652 | sourceName = arg13 2653 | sourceFlags = arg14 2654 | sourceRaidFlags = arg15 2655 | spellName = arg17 2656 | amount = arg19 2657 | end 2658 | end 2659 | 2660 | -- return when source is an outsider 2661 | if sourceFlags % 8 == 0 then 2662 | return 2663 | end 2664 | 2665 | -- give units a name if they don't have one to prevent errors 2666 | if not destName then 2667 | destName = NONE 2668 | end 2669 | 2670 | -- return on invalid event, vehicle, friendly fire, hostile healing, evaded 2671 | if not isValidEvent[event] or strsplit("-", sourceGUID) == "Vehicle" or (band(destFlags, 16) > 0 and isDamage[event]) 2672 | or (band(destFlags, 16) == 0 and isHeal[event]) or arg15 == "EVADE" then 2673 | return 2674 | end 2675 | 2676 | -- create summoned pets 2677 | if event == "SPELL_SUMMON" then 2678 | -- add pet when player summons 2679 | if UnitIsPlayer(sourceName) and not isExcludedPet[destID] then 2680 | -- make owner if necessary 2681 | if not tdpsPlayer[sourceGUID] then 2682 | makeCombatant(sourceGUID, sourceName, {sourceName..": "..destName}, getClass(sourceName)) 2683 | end 2684 | -- make pointer 2685 | tdpsLink[destGUID] = sourceName..": "..destName 2686 | -- make pet if it does not exist yet 2687 | if not tdpsPet[sourceName..": "..destName] then 2688 | makeCombatant(sourceName..": "..destName, destName, destGUID, "PET") 2689 | end 2690 | -- add pet to owner if it's not there yet 2691 | local found = false 2692 | for i = 1, #tdpsPlayer[sourceGUID].pet do 2693 | if tdpsPlayer[sourceGUID].pet[i] == sourceName..": "..destName then 2694 | found = true 2695 | break 2696 | end 2697 | end 2698 | if not found then 2699 | tinsert(tdpsPlayer[sourceGUID].pet, sourceName..": "..destName) 2700 | end 2701 | -- the summoner is also a pet (example: totems can summon elementals) 2702 | elseif tdpsLink[sourceGUID] then 2703 | -- owner's owner name 2704 | local ownersOwnerName = strsplit(":", tdpsLink[sourceGUID]) 2705 | -- make pointer 2706 | tdpsLink[destGUID] = ownersOwnerName..": "..destName 2707 | -- make pet 2708 | makeCombatant(ownersOwnerName..": "..destName, destName, destGUID, "PET") 2709 | -- add pet to owner if it's not there yet 2710 | local found = false 2711 | for i = 1, #tdpsPlayer[UnitGUID(ownersOwnerName)].pet do 2712 | if tdpsPlayer[UnitGUID(ownersOwnerName)].pet[i] == ownersOwnerName..": "..destName then 2713 | found = true 2714 | break 2715 | end 2716 | end 2717 | if not found then 2718 | tinsert(tdpsPlayer[UnitGUID(ownersOwnerName)].pet, ownersOwnerName..": "..destName) 2719 | end 2720 | end 2721 | return 2722 | end 2723 | 2724 | -- select or create combatant 2725 | if tdpsPlayer[sourceGUID] then 2726 | com = tdpsPlayer[sourceGUID] 2727 | elseif tdpsPet[tdpsLink[sourceGUID]] then 2728 | com = tdpsPet[tdpsLink[sourceGUID]] 2729 | elseif UnitIsPlayer(sourceName) then 2730 | makeCombatant(sourceGUID, sourceName, {}, getClass(sourceName)) 2731 | tdpsCombatEvent(self, event, ...) 2732 | return 2733 | elseif isPartyPet(sourceGUID) then 2734 | -- get owner 2735 | local ownerGUID, ownerName = getPetOwnerGUID(sourceGUID), getPetOwnerName(sourceGUID) 2736 | -- make owner if it does not exist yet 2737 | if not tdpsPlayer[ownerGUID] then 2738 | makeCombatant(ownerGUID, ownerName, {ownerName..": "..sourceName}, getClass(ownerName)) 2739 | end 2740 | -- make pointer 2741 | tdpsLink[sourceGUID] = ownerName..": "..sourceName 2742 | -- make pet if it does not exist yet 2743 | if not tdpsPet[ownerName..": "..sourceName] then 2744 | makeCombatant(ownerName..": "..sourceName, sourceName, sourceGUID, "PET") 2745 | end 2746 | -- add pet to owner if it's not there yet 2747 | local found = false 2748 | for i = 1, #tdpsPlayer[ownerGUID].pet do 2749 | if tdpsPlayer[ownerGUID].pet[i] == ownerName..": "..sourceName then 2750 | found = true 2751 | break 2752 | end 2753 | end 2754 | if not found then 2755 | tinsert(tdpsPlayer[ownerGUID].pet, ownerName..": "..sourceName) 2756 | end 2757 | -- event 2758 | tdpsCombatEvent(self, event, ...) 2759 | return 2760 | else 2761 | return 2762 | end 2763 | 2764 | -- track numbers 2765 | if isMiss[event] then 2766 | if tdpsStartNewFight then 2767 | startNewFight(destName, destGUID) 2768 | end 2769 | if event == "SWING_MISSED" and arg12 == "ABSORB" then 2770 | amount = floor(arg14 + .5) 2771 | trackSpell(amount, destName, tdpsL.melee, "d") 2772 | elseif arg15 == "ABSORB" then 2773 | amount = floor(arg17 + .5) 2774 | trackSpell(amount, destName, arg13, "d") 2775 | else 2776 | return 2777 | end 2778 | tdpsFight[1].d, tdpsFight[2].d = tdpsFight[1].d + amount, tdpsFight[2].d + amount 2779 | com.fight[1].d, com.fight[2].d = com.fight[1].d + amount, com.fight[2].d + amount 2780 | elseif isDamage[event] then 2781 | if tdpsStartNewFight then 2782 | startNewFight(destName, destGUID) 2783 | end 2784 | if event == "SWING_DAMAGE" then 2785 | amount = floor(arg12 + (arg17 or 0) + .5) 2786 | trackSpell(amount, destName, tdpsL.melee, "d") 2787 | else 2788 | amount = floor(arg15 + (arg20 or 0) + .5) 2789 | trackSpell(amount, destName, arg13, "d") 2790 | end 2791 | tdpsFight[1].d, tdpsFight[2].d = tdpsFight[1].d + amount, tdpsFight[2].d + amount 2792 | com.fight[1].d, com.fight[2].d = com.fight[1].d + amount, com.fight[2].d + amount 2793 | elseif isHeal[event] then 2794 | if event ~= "SPELL_ABSORBED" then 2795 | -- effective healing 2796 | amount = arg15 - arg16 2797 | end 2798 | amount = floor(amount + .5) 2799 | if amount < 1 or not tdpsInCombat then 2800 | -- stop on complete overheal or out of combat; heals will never start a new fight 2801 | return 2802 | end 2803 | trackSpell(amount, destName, spellName or arg13, "h") 2804 | tdpsFight[1].h, tdpsFight[2].h = tdpsFight[1].h + amount, tdpsFight[2].h + amount 2805 | com.fight[1].h, com.fight[2].h = com.fight[1].h + amount, com.fight[2].h + amount 2806 | end 2807 | 2808 | -- add combat time 2809 | amount = timestamp - com.stamp 2810 | if amount < 3.5 then 2811 | com.fight[1].t = com.fight[1].t + amount 2812 | else 2813 | com.fight[1].t = com.fight[1].t + 3.5 2814 | end 2815 | if amount < 3.5 then 2816 | com.fight[2].t = com.fight[2].t + amount 2817 | else 2818 | com.fight[2].t = com.fight[2].t + 3.5 2819 | end 2820 | 2821 | -- save timestamp 2822 | com.stamp = timestamp 2823 | 2824 | -- set onupdate 2825 | tdpsAnchor:SetScript("OnUpdate", tdpsOnUpdate) 2826 | end 2827 | 2828 | ------------------------------------------------------------------------------------------------------------------------ 2829 | -- Addon Scripts -- 2830 | ------------------------------------------------------------------------------------------------------------------------ 2831 | 2832 | tdpsFrame:RegisterEvent("ADDON_LOADED") 2833 | tdpsFrame:SetScript("OnEvent", function(self, event) 2834 | local addonVer = GetAddOnMetadata("TinyDPS", "Version") 2835 | local v1, v2, v3, v4 = strmatch(addonVer, "(%d+)%.(%d+)%.(%d+)%.(%d+)") 2836 | 2837 | if addonVer ~= "DEV" and v4 then 2838 | local curVer = v1..v2..v3.."."..(strlen(v4) == 1 and "0"..v4 or v4) 2839 | -- global version mismatch 2840 | if curVer ~= tdps.version and tonumber(tdps.version) < 0.935 then 2841 | initialiseSavedVariables() 2842 | echo("Global variables have been reset to version "..addonVer) 2843 | end 2844 | -- character version mismatch 2845 | if curVer ~= tdpsVersion and tonumber(tdpsVersion) < 0.935 then 2846 | initialiseSavedVariablesPerCharacter() 2847 | echo("Character variables have been reset to version "..addonVer) 2848 | tdpsFrame:SetHeight(tdps.barHeight + 4) 2849 | end 2850 | -- save current version 2851 | tdps.version = curVer 2852 | tdpsVersion = curVer 2853 | end 2854 | 2855 | -- set position of anchor 2856 | tdpsAnchor:ClearAllPoints() 2857 | local scale = tdpsAnchor:GetEffectiveScale() 2858 | local uis = UIParent:GetScale() 2859 | tdpsAnchor:SetPoint("CENTER", UIParent, "CENTER", tdpsPosition.x * uis / scale, tdpsPosition.y * uis / scale) 2860 | 2861 | -- set position of frame 2862 | tdpsFrame:ClearAllPoints() 2863 | tdpsFrame:SetPoint(tdps.anchor, tdpsAnchor, tdps.anchor) 2864 | 2865 | -- set width 2866 | tdpsFrame:SetWidth(tdps.width) 2867 | 2868 | -- check for custom class colors 2869 | cColor = { 2870 | UNKNOWN = { 2871 | r = .5, 2872 | g = .5, 2873 | b = .5, 2874 | colorStr = "ff7f7f7f0", 2875 | }, 2876 | } 2877 | cColor = setmetatable(cColor, {__index = CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS}) 2878 | 2879 | -- make bars if any 2880 | for k in pairs(tdpsPlayer) do 2881 | newBar(k) 2882 | end 2883 | 2884 | -- set font and colors 2885 | noData:SetFont(tdpsFont.name, tdpsFont.size, tdpsFont.outline) 2886 | noData:SetShadowOffset(tdpsFont.shadow, tdpsFont.shadow * -1) 2887 | tdpsFrame:SetBackdropBorderColor(tdps.border[1], tdps.border[2], tdps.border[3], tdps.border[4]) 2888 | tdpsFrame:SetBackdropColor(tdps.backdrop[1], tdps.backdrop[2], tdps.backdrop[3], tdps.backdrop[4]) 2889 | 2890 | -- hide when necessary 2891 | visibilityEvent() 2892 | 2893 | -- minimap button 2894 | if tdps.showMinimapButton then 2895 | tdpsButtonFrame:Show() 2896 | else 2897 | tdpsButtonFrame:Hide() 2898 | end 2899 | 2900 | -- reset events 2901 | tdpsFrame:UnregisterEvent("ADDON_LOADED") 2902 | tdpsFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") 2903 | tdpsFrame:SetScript("OnEvent", function(self, event, ...) 2904 | tdpsCombatEvent(self, event, CombatLogGetCurrentEventInfo()) 2905 | end) 2906 | end) 2907 | 2908 | -- all events that can show or hide the main window 2909 | tdpsAnchor:RegisterEvent("PLAYER_REGEN_ENABLED") 2910 | tdpsAnchor:RegisterEvent("PLAYER_REGEN_DISABLED") 2911 | tdpsAnchor:RegisterEvent("GROUP_ROSTER_UPDATE") 2912 | tdpsAnchor:RegisterEvent("PLAYER_ENTERING_WORLD") 2913 | tdpsAnchor:RegisterEvent("ZONE_CHANGED_NEW_AREA") 2914 | tdpsAnchor:RegisterEvent("UPDATE_UI_WIDGET") 2915 | tdpsAnchor:RegisterEvent("PET_BATTLE_OPENING_START") 2916 | tdpsAnchor:RegisterEvent("PET_BATTLE_CLOSE") 2917 | 2918 | local wasInGroup 2919 | tdpsAnchor:SetScript("OnEvent", function(self, event, ...) 2920 | visibilityEvent() 2921 | if event == "GROUP_ROSTER_UPDATE" then 2922 | if tdps.autoReset and IsInGroup() and wasInGroup == false then 2923 | reset() 2924 | end 2925 | wasInGroup = not not IsInGroup() 2926 | end 2927 | end) 2928 | 2929 | -- onupdate 2930 | local sec = 2 2931 | function tdpsOnUpdate(self, elapsed) 2932 | sec = sec + elapsed 2933 | if sec > tdps.speed then 2934 | checkCombat() 2935 | if not tdpsInCombat then 2936 | tdpsStartNewFight = true 2937 | -- halted out of combat and restarted with combat (see function tdpsCombatEvent) 2938 | tdpsAnchor:SetScript("OnUpdate", nil) 2939 | end 2940 | -- conditional refresh of the main window 2941 | if tdpsFrame:IsVisible() and not isMovingOrSizing and not tdpsAnimationGroup:IsPlaying() then 2942 | tdpsRefresh() 2943 | end 2944 | sec = 0 2945 | end 2946 | end 2947 | 2948 | tdpsAnchor:SetScript("OnUpdate", tdpsOnUpdate) 2949 | 2950 | tdpsFrame:SetScript("OnMouseDown", function(self, button) 2951 | if button == "LeftButton" and IsShiftKeyDown() then 2952 | CloseDropDownMenus() 2953 | GameTooltip:Hide() 2954 | isMovingOrSizing = true 2955 | tdpsAnchor:StartMoving() 2956 | elseif button == "RightButton" then 2957 | ToggleDropDownMenu(1, nil, tdpsDropDown, "cursor", 0, 0) 2958 | elseif button == "MiddleButton" then 2959 | reset() 2960 | elseif button == "Button4" then 2961 | changeFight(nil, 1) 2962 | elseif button == "Button5" then 2963 | changeFight(nil, 2) 2964 | end 2965 | end) 2966 | 2967 | tdpsFrame:SetScript("OnMouseUp", function(self, button) 2968 | if button == "LeftButton" then 2969 | tdpsAnchor:StopMovingOrSizing() 2970 | isMovingOrSizing = nil 2971 | -- set position of frame 2972 | tdpsFrame:ClearAllPoints() 2973 | tdpsFrame:SetPoint(tdps.anchor, tdpsAnchor, tdps.anchor, 0, 0) 2974 | -- save position of anchor 2975 | local xOfs, yOfs = tdpsAnchor:GetCenter() 2976 | local scale = tdpsAnchor:GetEffectiveScale() 2977 | local uis = UIParent:GetScale() 2978 | xOfs = xOfs * scale - GetScreenWidth() * uis / 2 2979 | yOfs = yOfs * scale - GetScreenHeight() * uis / 2 2980 | tdpsPosition.x = xOfs / uis 2981 | tdpsPosition.y = yOfs / uis 2982 | end 2983 | end) 2984 | 2985 | tdpsFrame:SetScript("OnMouseWheel", function(self, direction) 2986 | scroll(direction) 2987 | end) 2988 | 2989 | ------------------------------------------------------------------------------------------------------------------------ 2990 | -- Minimap Button Scripts -- 2991 | ------------------------------------------------------------------------------------------------------------------------ 2992 | 2993 | tdpsButtonFrame:SetScript("OnMouseDown", function(self, button) 2994 | if button == "RightButton" then 2995 | ToggleDropDownMenu(1, nil, tdpsDropDown, "cursor", 0, 0) 2996 | end 2997 | if button == "MiddleButton" then 2998 | reset() 2999 | end 3000 | end) 3001 | 3002 | tdpsButtonFrame:SetScript("OnMouseUp", function(self, button) 3003 | if button == "LeftButton" then 3004 | toggle() 3005 | end 3006 | end) 3007 | 3008 | tdpsButtonFrame:SetScript("OnDragStart", function(self, button) 3009 | tdpsButtonFrame:SetScript("OnUpdate", function(self, elapsed) 3010 | local x, y = Minimap:GetCenter() 3011 | local cx, cy = GetCursorPosition() 3012 | x, y = cx / self:GetEffectiveScale() - x, cy / self:GetEffectiveScale() - y 3013 | if x > Minimap:GetWidth() / 2 + tdpsButtonFrame:GetWidth() / 2 then 3014 | x = Minimap:GetWidth() / 2 + tdpsButtonFrame:GetWidth() / 2 3015 | end 3016 | if x < Minimap:GetWidth() / 2 * -1 - tdpsButtonFrame:GetWidth() / 2 then 3017 | x = Minimap:GetWidth() / 2 * -1 - tdpsButtonFrame:GetWidth() / 2 3018 | end 3019 | if y > Minimap:GetHeight() / 2 + tdpsButtonFrame:GetHeight() / 2 then 3020 | y = Minimap:GetHeight() / 2 + tdpsButtonFrame:GetHeight() / 2 3021 | end 3022 | if y < Minimap:GetHeight() / 2 * -1 - tdpsButtonFrame:GetHeight() / 2 then 3023 | y = Minimap:GetHeight() / 2 * -1 - tdpsButtonFrame:GetHeight() / 2 3024 | end 3025 | tdpsButtonFrame:ClearAllPoints() 3026 | tdpsButtonFrame:SetPoint("CENTER", x, y) 3027 | end) 3028 | end) 3029 | 3030 | tdpsButtonFrame:SetScript("OnDragStop", function(self, button) 3031 | tdpsButtonFrame:SetScript("OnUpdate", nil) 3032 | end) 3033 | 3034 | tdpsButtonFrame:SetScript("OnEnter", function(self) 3035 | GameTooltip:SetOwner(tdpsButtonFrame) 3036 | GameTooltip:SetText("TinyDPS") 3037 | 3038 | if tdpsF == 2 then 3039 | GameTooltip:AddLine(format("%s %s", tdpsL.tipPrefix[tdpsV], tdpsL.currentFight), 1, .85, 0) 3040 | else 3041 | GameTooltip:AddLine(format("%s %s", tdpsL.tipPrefix[tdpsV], tdpsFight[tdpsF].name), 1, .85, 0) 3042 | end 3043 | 3044 | -- personal amount 3045 | local ownAmount, ownTime, pet = 0, 0 3046 | if tdpsPlayer[UnitGUID("player")] then 3047 | pet, ownAmount, ownTime = tdpsPlayer[UnitGUID("player")].pet, tdpsPlayer[UnitGUID("player")].fight[tdpsF][tdpsV], 3048 | tdpsPlayer[UnitGUID("player")].fight[tdpsF].t 3049 | for i = 1, #pet do 3050 | ownAmount = ownAmount + tdpsPet[pet[i]].fight[tdpsF][tdpsV] 3051 | if tdpsPet[pet[i]].fight[tdpsF].t > ownTime then 3052 | ownTime = tdpsPet[pet[i]].fight[tdpsF].t 3053 | end 3054 | end 3055 | if ownAmount > 0 then 3056 | if (band(tdps.layout, 1) == 1) then -- short format bit active 3057 | GameTooltip:AddDoubleLine(UnitName("player"), format("%s (%s)", short(ownAmount), short(ownAmount / ownTime)), 3058 | 1, 1, 1, 1, 1, 1) 3059 | else 3060 | GameTooltip:AddDoubleLine(UnitName("player"), format("%i (%i)", ownAmount, ownAmount / ownTime), 1, 1, 1, 1, 1, 3061 | 1) 3062 | end 3063 | end 3064 | end 3065 | 3066 | -- raid amount 3067 | local partyAmount, partyTime = 0, 0 3068 | for k, v in pairs(tdpsPlayer) do 3069 | partyAmount = partyAmount + v.fight[tdpsF][tdpsV] 3070 | if v.fight[tdpsF].t > partyTime then 3071 | partyTime = v.fight[tdpsF].t 3072 | end 3073 | end 3074 | for k, v in pairs(tdpsPet) do 3075 | partyAmount = partyAmount + v.fight[tdpsF][tdpsV] 3076 | if v.fight[tdpsF].t > partyTime then 3077 | partyTime = v.fight[tdpsF].t 3078 | end 3079 | end 3080 | 3081 | if partyAmount > ownAmount then 3082 | if (band(tdps.layout, 1) == 1) then -- short format bit active 3083 | GameTooltip:AddDoubleLine(tdpsL.raid, format("%s (%s)", short(partyAmount), short(partyAmount / partyTime)), 1, 1, 3084 | 1, 1, 1, 1) 3085 | else 3086 | GameTooltip:AddDoubleLine(tdpsL.raid, format("%i (%i)", partyAmount, partyAmount / partyTime), 1, 1, 1, 1, 1, 1) 3087 | end 3088 | end 3089 | 3090 | GameTooltip:Show() 3091 | end) 3092 | 3093 | tdpsButtonFrame:SetScript("OnLeave", function(self) 3094 | GameTooltip:Hide() 3095 | end) 3096 | 3097 | ------------------------------------------------------------------------------------------------------------------------ 3098 | -- Resizing Scripts -- 3099 | ------------------------------------------------------------------------------------------------------------------------ 3100 | 3101 | tdpsResizeFrame:SetScript("OnEnter", function() 3102 | tdpsResizeTexture:SetDesaturated(false) 3103 | tdpsResizeTexture:SetAlpha(1) 3104 | end) 3105 | 3106 | tdpsResizeFrame:SetScript("OnLeave", function() 3107 | tdpsResizeTexture:SetDesaturated(true) 3108 | tdpsResizeTexture:SetAlpha(0) 3109 | end) 3110 | 3111 | tdpsResizeFrame:SetScript("OnMouseDown", function() 3112 | isMovingOrSizing = true 3113 | tdpsFrame:SetMinResize(60, tdpsFrame:GetHeight()) 3114 | tdpsFrame:SetMaxResize(400, tdpsFrame:GetHeight()) 3115 | tdpsFrame:StartSizing() 3116 | end) 3117 | 3118 | tdpsResizeFrame:SetScript("OnMouseUp", function() 3119 | tdpsFrame:StopMovingOrSizing() 3120 | tdpsFrame:ClearAllPoints() 3121 | tdpsFrame:SetPoint(tdps.anchor, tdpsAnchor, tdps.anchor) 3122 | isMovingOrSizing = nil 3123 | tdps.width = tdpsFrame:GetWidth() 3124 | for i = 1, #bar do 3125 | bar[i]:SetWidth(tdpsFrame:GetWidth() - 4) 3126 | bar[i]:SetValue(0) 3127 | end 3128 | tdpsRefresh() 3129 | end) 3130 | -------------------------------------------------------------------------------- /TinyDPS.toc: -------------------------------------------------------------------------------- 1 | ## Interface: 90105 2 | 3 | ## Title: TinyDPS 4 | ## Notes: A lightweight damage and healing meter. 5 | 6 | ## Author: Talyrius, Sideshow (former) 7 | ## Version: @project-version@ 8 | ## X-Revision: @project-abbreviated-hash@ 9 | ## X-Date: @project-date-iso@ 10 | ## X-Copyright: Copyright © 2010-2021 Sideshow, Talyrius. 11 | ## X-License: All rights reserved. 12 | ## X-Email: contact@talyrius.net 13 | ## X-Website: https://github.com/Talyrius/TinyDPS 14 | ## X-Feedback: https://www.wowinterface.com/downloads/info16780-TinyDPS.html#comments 15 | ## X-Localizations: enUS, deDE, esES, esMX, frFR, itIT, ruRU, koKR, zhCN 16 | ## X-Category: Combat, Caster, Damage Dealer, Healer, Tank 17 | ## X-Icon: Interface\AddOns\TinyDPS\Textures\minimapbutton 18 | ## X-Curse-Project-ID: 23664 19 | ## X-WoWI-ID: 16780 20 | 21 | ## SavedVariables: tdps, tdpsPosition, tdpsFont, tdpsNumberOfFights, tdpsF, tdpsV, tdpsTextOffset, tdpsColorAlpha, tdpsVisibleBars, tdpsReportLength 22 | ## SavedVariablesPerCharacter: tdpsVersion, tdpsPlayer, tdpsLink, tdpsPet, tdpsFight, tdpsPartySize, tdpsCombat, tdpsNewFight 23 | ## OptionalDependencies: LibStub, LibBossIDs-1.0 24 | ## LoadManagers: AddonLoader 25 | ## X-LoadOn-Always: delayed 26 | ## X-LoadOn-Combat: true 27 | 28 | #@no-lib-strip@ 29 | Libs\LibStub\LibStub.lua 30 | Libs\LibBossIDs-1.0\lib.xml 31 | #@end-no-lib-strip@ 32 | 33 | TinyDPS.lua 34 | 35 | #@debug@ 36 | ## Version: DEV 37 | #@end-debug@ 38 | --------------------------------------------------------------------------------